反射
# 反射
利用反射我们可以使用任意一个类中的,所有方法和属性,无视修饰符
用反射创建对象,反射调用成员变量 / 方法
利用反射可以无视修饰符获取类里面所有的属性和方法
先获取配置文件中的信息,动态获取信息并创建对象和调用方法
# 获取 class 类的对象
# Class.forName()
Class<?> aClass = Class.forName("笔记.反射.Studen");
System.out.println(aClass);
2
通过 forName 传递全类名 (包名 + 类名) 获取
# 类名.class
Class<Studen> studenClass = Studen.class;
System.out.println(studenClass);
2
# 对象.getclass ()
Studen s =new Studen();
Class<? extends Studen> aClass1 = s.getClass();
System.out.println(aClass1);
2
3
# 获取 Constructor 对象
Constructor 为构造方法对象,在反射中所有方法属性都为对象
# getConstructors()
该方法获取该 class 所有的公共构造方法
Class<?> aClass = Class.forName("笔记.反射.Studen");
// 获取该class所有的公共构造方法
Constructor<?>[] constructors = aClass.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
2
3
4
5
6
# getDeclaredConstructors()
返回所有的构造方法,无视修饰符
Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
2
3
4
# getConstructor()
返回指定的公共构造方法,必须要与类中的构造方法形参一致,否则无法找到指定构造方法,并抛出异常
Constructor<?> constructor = aClass.getConstructor(String.class,int.class);
System.out.println(constructor);
2
# getDeclaredConstructor()
返回单个指定构造方法 无视修饰符
# newInstance () 创建对象
获取到构造方法后我们可以使用 newInstance () 来创建对象 该方法返回一个对象 默认为 object 类型,需要强转为类的类型
Studen zhangsan = (Studen) declaredConstructor.newInstance("zhangsan", 23);
System.out.println(zhangsan);
2
如果构造方法为空参 我们可以直接在获取 class 后 的 class 对象直接 newInstance (), 该方法已经过时,不推荐使用
# 被 parivate 修饰的情况
如果该反射对象不是公共修饰符,则创建对象时会发生异常,需要临时取消访问检查
setAccessible (boolean); 临时取消访问检查 暴力反射
// 获取class类 Class<?> aClass1 = Class.forName("笔记.反射.Studen"); // 获取所有构造方法 Constructor<?> declaredConstructor1 = aClass1.getDeclaredConstructor(String.class); // 临时取消访问检查 declaredConstructor1.setAccessible(true); // 创建对象 并 强转成Studen类 Studen lisi = (Studen) declaredConstructor1.newInstance("lisi"); System.out.println(lisi);1
2
3
4
5
6
7
8
9
10
11
12
13
# 获取反射的成员变量
getFields (); 返回所有公共的成员变量对象的数组
getDeclaredFields (): 返回所有成员变量的数组 无视修饰符
getField (String name); 指定成员变量名字 返回单个公共成员变量对象
getDeclaredField (String name): 返回单个公共成员变量对象 无视修饰符
Class<?> aClass1 = Class.forName("笔记.反射.Studen"); Field[] fields = aClass1.getFields(); for (Field field : fields) { System.out.println(field); } Field age = aClass1.getDeclaredField("age"); System.out.println(age);1
2
3
4
5
6
7
8
9
10
注意 获取的成员变量必须真实存在 否则会报错 并且注意修饰符
# 赋值
set (object obj,object value): 赋值
get (object obj): 获取值
Field w = aClass1.getField("w"); w.set(lisi,123); System.out.println(w.get(lisi));1
2
3
4
注意:
对象参数传递 newinstance () 方法创建的对象
如果为私有属性 必须临时取消访问检查 setAccessible (boolean) 先获取 field 对象再取消检查
# 获取成员方法
getMethods (): 返回所有公共成员方法对象的数组,包括继承的
getDeclaredMethods (): 返回所有的成员方法对象的数组,不包括继承的方法
getMethod(String name,Class
<?>... parmeterTypres): 返回指定名称的公共成员方法 Class 为形参 必须传递类型的 class 对象geDeclaredtMethod(String name,Class
<?>... parmeterTypres): 返回指定名称的成员方法Method setName = aClass1.getMethod("setName", String.class); System.out.println(setName);1
2
# 使用反射后方法
invoke (object obj,object args): 运行指定方法
- 参数一:用 obj 对象调用该方法 newinstance 出来的对象
- 参数二:调用方法的传递参数 (可省)
Method setName = aClass1.getMethod("setName", String.class); Studen lisi = (Studen) declaredConstructor1.newInstance("lisi"); setName.invoke(lisi,"haha");1
2
3
4
5