反射是为了在不知道源码的情况下剖析类的组成。
-
Class: 是一个类; 一个描述类的类.
封装了描述方法的 Method,
描述字段的 Filed,
描述构造器的 Constructor 等属性. -
如何得到 Class 对象:
2.1 Person.class
2.2 person.getClass()
2.3 Class.forName(“com.atguigu.javase.Person”) -
关于 Method:
3.1 如何获取 Method:
1). getDeclaredMethods: 得到 Method 的数组.
2). getDeclaredMethod(String methondName, Class … parameterTypes)
3.2 如何调用 Method
1). 如果方法时 private 修饰的, 需要先调用 Method 的 setAccessible(true), 使其变为可访问
2). method.invoke(obj, Object … args);
-
关于 Field:
4.1 如何获取 Field: getField(String fieldName)
4.2 如何获取 Field 的值:
1). setAccessible(true)
2). field.get(Object obj)
4.3 如何设置 Field 的值:
field.set(Obejct obj, Object val) -
了解 Constructor 和 Annotation
-
反射和泛型.
6.1 getGenericSuperClass: 获取带泛型参数的父类, 返回值为: BaseDao<Employee, String>
6.2 Type 的子接口: ParameterizedType
6.3 可以调用 ParameterizedType 的 Type[] getActualTypeArguments() 获取泛型参数的数组.
自己随便创建了一个类,通过outline看一下。
假定现在只知道包名和类名
1 获取类的字节码文件
//获取字节码文件对象 三种方式
Class c = Person.class;
c = new Person().getClass();
c = Class.forName("com.ali.test1.Person");
2 获取资源时区分public或已声明的。(属性/方法/构造方法)
以构造方法为例,自行类比获取属性和普通方法
//获取所有public的构造方法
Constructor[] cons = c.getConstructors();
System.out.println(cons.length);
//获取所有声明的构造方法
cons = c.getDeclaredConstructors();
System.out.println(cons.length);
for(Constructor con: cons){
System.out.println(con);
}
//获取单个构造方法(public的),并构造对象
Constructor con = c.getConstructor();
Person p1 = (Person)con.newInstance();
System.out.println("p1= "+p1);
//获取构造方法,并构造对象
con = c.getDeclaredConstructor(String.class,int.class);
Person p2 = (Person)con.newInstance("jack",18);
System.out.println("p2 = "+ p2);
//public属性
Field name_field = c.getField("name");
name_field.set(p1, "xiaozhang");
name_field.set(p2, "xiaohong");
System.out.println("p1= "+p1);
System.out.println("p2 = "+ p2);
//所有属性中的一个
Field age_field = c.getDeclaredField("age");
age_field.set(p1, 18);
age_field.set(p2, 16);
System.out.println("p1= "+p1);
System.out.println("p2 = "+ p2);
//私有属性
Field address_field = c.getDeclaredField("address");
//默认不允许访问,反射时设置允许访问到
address_field.setAccessible(true);
address_field.set(p1, "成都");
address_field.set(p2, "北京");
System.out.println("p1= "+p1);
System.out.println("p2 = "+ p2);
//public 方法
Method method1 = c.getMethod("method1");
//方法让对象执行
method1.invoke(p1);
//有参数
Method method2 = c.getMethod("method2",String.class);
//方法让对象执行
method2.invoke(p1,"hello");
System.out.println("p1= "+p1);
//有返回值
Method method3 = c.getMethod("method3");
//方法让对象执行
String res = (String)method3.invoke(p1);
System.out.println(res);
//私有方法
Method method4 = c.getDeclaredMethod("method4");
method4.setAccessible(true);
int num = (int)method4.invoke(p1);
System.out.println(num);