1. 反射

利用反射我们可以使用任意一个类中的,所有方法和属性,无视修饰符

用反射创建对象,反射调用成员变量/方法

利用反射可以无视修饰符获取类里面所有的属性和方法

先获取配置文件中的信息,动态获取信息并创建对象和调用方法

2. 获取class类的对象

2.1. Class.forName()

  1. Class<?> aClass = Class.forName("笔记.反射.Studen");
  2. System.out.println(aClass);

通过forName传递全类名(包名+类名)获取

2.2. 类名.class

  1. Class<Studen> studenClass = Studen.class;
  2. System.out.println(studenClass);

对象.getclass()

  1. Studen s =new Studen();
  2. Class<? extends Studen> aClass1 = s.getClass();
  3. System.out.println(aClass1);

获取Constructor对象

Constructor为构造方法对象,在反射中所有方法属性都为对象

2.3. getConstructors()

该方法获取该class所有的公共构造方法

  1. Class<?> aClass = Class.forName("笔记.反射.Studen");
  2. // 获取该class所有的公共构造方法
  3. Constructor<?>[] constructors = aClass.getConstructors();
  4. for (Constructor<?> constructor : constructors) {
  5. System.out.println(constructor);
  6. }

2.4. getDeclaredConstructors()

返回所有的构造方法,无视修饰符

  1. Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
  2. for (Constructor<?> declaredConstructor : declaredConstructors) {
  3. System.out.println(declaredConstructor);
  4. }

2.5. getConstructor()

返回指定的公共构造方法,必须要与类中的构造方法形参一致,否则无法找到指定构造方法,并抛出异常

  1. Constructor<?> constructor = aClass.getConstructor(String.class,int.class);
  2. System.out.println(constructor);

2.6. getDeclaredConstructor()

返回单个指定构造方法 无视修饰符

3. newInstance() 创建对象

获取到构造方法后我们可以使用 newInstance() 来创建对象 该方法返回一个对象 默认为object类型,需要强转为类的类型

  1. Studen zhangsan = (Studen) declaredConstructor.newInstance("zhangsan", 23);
  2. System.out.println(zhangsan);

如果构造方法为空参 我们可以直接在获取class后 的class对象直接newInstance(),该方法已经过时,不推荐使用

3.1. 被parivate修饰的情况

如果该反射对象不是公共修饰符,则创建对象时会发生异常,需要临时取消访问检查

  • setAccessible(boolean ); 临时取消访问检查 暴力反射

  • ```java // 获取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. <a name="e5e49444"></a>
  2. # 4. 获取反射的成员变量
  3. -
  4. getFields(); 返回所有公共的成员变量对象的数组
  5. -
  6. getDeclaredFields(): 返回所有成员变量的数组 无视修饰符
  7. -
  8. getField(String name); 指定成员变量名字 返回单个公共成员变量对象
  9. -
  10. getDeclaredField(String name): 返回单个公共成员变量对象 无视修饰符
  11. -
  12. ```java
  13. Class<?> aClass1 = Class.forName("笔记.反射.Studen");
  14. Field[] fields = aClass1.getFields();
  15. for (Field field : fields) {
  16. System.out.println(field);
  17. }
  18. Field age = aClass1.getDeclaredField("age");
  19. System.out.println(age);

注意 获取的成员变量必须真实存在 否则会报错 并且注意修饰符

4.1. 赋值

  • set(object obj,object value): 赋值

  • get(object obj): 获取值

  • ```java Field w = aClass1.getField(“w”);

w.set(lisi,123); System.out.println(w.get(lisi));

  1. 注意:
  2. 1.
  3. 对象参数传递 newinstance()方法创建的对象
  4. 2.
  5. 如果为私有属性 必须临时取消访问检查 setAccessible(boolean ) 先获取field对象再取消检查
  6. <a name="d62b4bfe"></a>
  7. # 5. 获取成员方法
  8. -
  9. getMethods(): 返回所有公共成员方法对象的数组,包括继承的
  10. -
  11. getDeclaredMethods(): 返回所有的成员方法对象的数组,不包括继承的方法
  12. -
  13. getMethod(String name,Class`<?>`... parmeterTypres): 返回指定名称的公共成员方法 Class为形参 必须传递类型的class对象
  14. -
  15. geDeclaredtMethod(String name,Class`<?>`... parmeterTypres): 返回指定名称的成员方法
  16. -

Method setName = aClass1.getMethod(“setName”, String.class); System.out.println(setName);

  1. <a name="a34d8510"></a>
  2. ### 5.1. 使用反射后方法
  3. -
  4. invoke(object obj,object args): 运行指定方法
  5. - 参数一: 用obj对象调用该方法 newinstance出来的对象
  6. - 参数二:调用方法的传递参数(可省)
  7. -
  8. ```java
  9. Method setName = aClass1.getMethod("setName", String.class);
  10. Studen lisi = (Studen) declaredConstructor1.newInstance("lisi");
  11. setName.invoke(lisi,"haha");