反射
反射机制被视为java为准动态语言的主要的一个关键性质,反射机制允许程序在执行期借助reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。那么什么是动态语言,什么是静态语言?
动态语言
在运行时才进行数据类型检查,可以改变结构
静态语言
在编译阶段就做数据类型检查,就已经确定了结构,运行时不可变
反射机制的工作原理
本人理解的反射机制是:首先在运行前jvm将字节码文件加载到方法区中(每一个类都有一个字节码文件),并且在堆中开辟一个空间存放一个访问方法区中该字节码文件的入口,即创建一个Class实例。字节码文件存放的就是类中的信息,反射中的方法就是访问该字节码,获得和修改该字节码文件,字节码文件中的信息只有声明信息,如果想要访问成员变量的值,就需要创建一个实例化该类,jvm就会在堆中开辟空间存放该实例化的类信息,通过该对象访问成员变量的值。
注:本人只是根据所了解的知识得出的结论,正确性有待验证,有错误希望更正,同时希望能够给出你们对于反射工作原理的理解。
在获取类的内部信息之前需要得到该类的class,即访问入口
获取Class类的实例
-
若已知具体的类,可通过类名.class属性获取,该方法最为安全可靠,但这种方式不会初始化该类,即不会执行该类中的静态代码块
Class clazz = SuperClass.class;//输出:class jvm.loading.SuperClass -
已知某个类的实例,调用该实例的getClass()方法获取Class对象
SuperClass sc = new SuperClass(); Class clazz = sc.getClass();//输出:class jvm.loading.SuperClass -
已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出找不到类异常
try { Class cClass = Class.forName("jvm.loading.SuperClass"); System.out.println(cClass); } catch (ClassNotFoundException e) { e.printStackTrace(); }//输出:class jvm.loading.SuperClass -
内置基本数据类型可以直接用类名.Type
Class dClass = Integer.TYPE;//输出:int
类中的信息可分为
| 类名 | 用途 |
|---|---|
| Class类 | 类的实体,在运行的Java应用程序中表示类和接口 |
| Field类 | 类的成员变量 |
| Method类 | 类中的成员方法 |
| Constructor类 | 类中的构造方法 |
Class类的常用方法
| 方法 | 用途 |
|---|---|
| ClassLoader getClassLoader() | 获得该类的类加载器 |
| String getName() | 获得该类的类名 |
| Object newInstance() | 创建该类的对象 |
| Class getSuperClass() | 获得该类的父类 |
| Class [] getInterfaces() | 获得该类实现的接口 |
| Package getPackage() | 获得该类的存放路径 |
| Field[] getFields() | 获得权限为public的所有成员变量 |
| Field getField(String name) | 获得权限为public且名为name的成员变量 |
| Field[] getDeclaredFields() | 获得所有成员变量 |
| Field[] getDeclaredFields(String name) | 获得名为name成员变量 |
| Constructor[] getConstructors() | 获得权限为public的所有构造方法 |
| Constructor getConstructor(Class<?>…parameterTypes) | 获得权限为public的指定构造方法 |
| Constructor[] getDeclaredConstructors() | 获得所有构造方法 |
| Constructor getDeclaredConstructor(Class<?>…parameterTypes) | 获得指定构造方法 |
| Method[] getMethods() | 获得权限为public所有成员方法 |
| Method getMethod(Class<?>…parameterTypes) | 获得权限为public的指定成员方法 |
| Method[] getDeclaredMethods() | 获得所有成员方法 |
| Method getDeclaredMethod(Class<?>…parameterTypes) | 获得指定成员方法 |
Field类成员变量类
| 方法 | 用途 |
|---|---|
| String getName() | 获得该成员变量的名称 |
| Class getType() | 获得该成员变量的类型的Class对象 |
| Object get(Object obj) | 获得指定对象obj中成员变量的值 |
| void set(Object obj ,Object value) | 设置obj类中指定的成员变量的值为value |
| void setAccessible(boolean flag) | 如果flag为true,则忽略权限限制,直接访问成员变量 |
| int getModifiers() | 获得该成员变量的修饰符 |
Constructor类构造方法类
| 方法 | 用途 |
|---|---|
| boolean isVarArgs() | 查看该构造方法是否有可变参数,有则返回true(注意:可变参数可以理解为数组) |
| Class[] getParameterTypes() | 获得该构造方法中的参数类型,以数组方式存储 |
| Class[] getExceptionTypes() | 如果该构造方法中使用throws方式抛出异常,则会获得抛出的所有异常,如果使用try catch的方式则获得不到 |
| Class newInstance(Object… obj) | 传递参数给该构造方法,实例化该类 |
| void setAccessible(boolean flag) | 如果flag为true,则忽略权限限制,直接可以创建实例 |
| int getModifiers() | 获得该构造方法的修饰符 |
构造方法的修饰符
| 修饰符 | 值 |
|---|---|
| public | 1 |
| private | 2 |
| protected | 4 |
| static | 8 |
| final | 16 |
| synchronized | 32 |
| volatile | 64 |
| transient | 128 |
| native | 256 |
| interface | 512 |
| abstract | 1024 |
| strict | 2048 |
Method成员方法类
成员方法类的方法和构造方法类中的方法用途差不多
| 方法 | 用途 |
|---|---|
| getName() | 获得该方法的名称 |
| Class[] getParameterTypes() | 获得该构造方法中的参数类型,以数组方式存储 |
| Class getReturnType() | 获得该方法的返回值类型 |
| Class[] getExceptionTypes() | 如果该方法中使用throws方式抛出异常,则会获得抛出的所有异常,如果使用try catch的方式则获得不到 |
| Object invoke(Object obj,Object… args) | 调用obj对象中的方法,并且传递参数args执行该方法 |
| boolean isVarArgs() | 查看该方法是否有可变参数,有则返回true(注意:可变参数可以理解为数组) |
| int getModifiers() | 获得该构造方法的修饰符 |
1万+

被折叠的 条评论
为什么被折叠?



