java的反射机制
Java反射主要内容:
1. 理解Class类并且实例化Class对象
2. 运行时创建对象并获取类的完整结构
3. 通过反射调用类的制定方法、指定属性
4. 动态代理
Java反射机制提供功能:
1. 运行时判断任意一个对象所属的类
2. 运行时构造任意一个类的对象
3. 运行时判断任意一个类所具有的变量和方法
4. 运行时调用任意一个对象的成员变量和方法
5. 生成动态代理
反射主要类:
1. java.lang.Class:(反射的源头)
2. java.lang.reflect.Method
3. java.lang.reflect.Field
4. java.lang.reflect.Constructor
-
详细介绍
-
一、Class类
正常方式:引入需要的包类名称>通过new实例化>取得实例化对象
反射方式:实例化对象>getClass()方法>得到完整的包类名
Java程序流程图:
类的加载器:
类的加载包括:
[类加载:][6]将类的class文件读入内存,并为之创建一个java.lang.Class对象。
[类连接:][6]将类的二进制数据合并到JRE中。
[类的初始化:][6]JVM负责对类进行初始化。
加载器:ClassLoader
1. [引导类加载器][6]
用C++编写,是JVM自带的类加载器,负责Java平台核心库的加载,该加载器无法直接获取。
2. [扩展类加载器][6]
负责jre/lib/ext目录下的jar包或-D java.ext.dirs指定目录下的jar包装入工作库。
3. [系统类加载器][6]
负责java-classpath或者-D java.class.path所制定的目录下的类和jar包装入工作,是最常用的加载器
(1).获取Class对象方法
1. 运行时类本身的.class属性
2. 通过运行时类的对象的getClass()方法获取Class对象
3. 通过Class的静态方法Class.forName()方法获取
4. 通过类的加载器
ClassLoader c = this.getClass().getClassLoader();
Class cs = c.loadClass();
//有了Class实例以后可以进行一下操作
1. 创建对应的运行时类的对象;
2. 获取对应的运行时类的完整结构(属性、方法、构造器、内部类…);
3. 调用对应的运行时类的制定结构(属性、方法、构造器);
4. 反射应用,动态代理;
二、创建类对象并获取类的完整结构
1.创建类对象
1)类必须有一个无参构造方法newInstance()实际上是调用了该类
的默认构造器;
2)类的构造器的访问权限足够;
2.获取属性(Field)
1)getField()方法只能获取public的属性以及父类中public的属性;
2)如果想要获取所有的可以使用getDeclaredFileds()不包括父类
的Field;
3)属性的修饰符、权限控制符、类型和名字可以单独获取
权限修饰符有Modifier类(查看API);
3.获取方法(Method)
1)getMethods():获取运行时类及其父类中所有申明为public方法;
2)getDeclaredMethods():获取运行时类本身申明的所有方法;
3)注解、权限修饰符、返回值类型、方法名、参数列表和异常可以独获取;
4.获取构造方法(Constructor)
1)先生成class类对象
getDeclareConstructors()方法获取(查看API文档)
调用指定构造器代码:
{
Class pclass = Person.class;
Object obj = cons.newInstance(构造方参数,实参);
}
方法代码:
@Test
public void test1() throws Exception{
Class aclass = Animal.class;
//获取指定构造方法
Constructor cons=
aclass.getConstructor(int.class,String.class);
/**执行指定构造方法创建对象
*如果没有参数getConstructor()不填写
*Constructor cons = pclass.getConstructor(构造方法参数类型);
*Constructor cons = pclass.getDeclaredConstructor(构造方*法参数类型);
*如果权限不能访问,需要设置允许
*cons.setAccessible(true);
*/
Animal am = (Animal)cons.newInstance(12,"bird");
System.out.println(am);
}
5.其它功能
获取所在包getPackage();
获取泛型;
获取实现的接口;
获取注解;
三、通过反射调用类中指定的方法、属性
1.调用指定属性
1)获取Class
Class pclass = Person.class;
2)获取指定属性;
Field name = pclass.getField(name);
//如果是私有private需要用getDeclaredFiled(name)获取属性
3)创建运行时类对象:
Person p = pclass.newInstance()方法;
4)将运行时类的指定属性赋值:
name.set(p,”value”);
//如果Field权限是private不能直接操作,需要设置
//setAccessible(true);
5)获取指定对象中的该值
name.get(p);
2.调用运行时类中指定方法
1)获取运行类对象
Class pclass = Person.class;
Person p = pclass.newInstance();
2)获取方法
Mehtod m = Pclass.getMethod(mehtodName,Class … params)
3)调用指定方法
m.invoke(p);
静态方法调用:
如果是静态方法则:m.invoke(Person.class);
多参数方法调用:
Method m = pclass.getDeclaredMehtod(p,String.class,Integer.class);
Object value = m.invoke(p,”xiao”,21);
//调用方法的返回值调用指定构造器:
Class pclass = Person.class;
//在获取构造方法的时候传入对应的构造器参数类型
Constructor cons = pclass.getDeclaredConstructor(String.class,int.class);
//在创建实例的时候传入实参
Person p = (Person)cons.newInstance(“xiao”,23);