Java反射机制
2020-06-29 04:26
274 查看
什么是Java反射机制
反射就是指程序在运行时能够动态地获取到一个类的Class类型信息的一种操作。它是现代框架的灵魂,比如Spring框架的IoC(控制反转)就是利用反射机制。搞懂反射有助于我们理解框架的实现原理。
获取Class类型信息的三种方式
为了测试,定义一个People类,此处省略setter等一系列方法。
public class People { private String name; public Integer age; public void sayHelloPublic(){ System.out.println("HelloPublic"); } private void sayHelloPrivate(){ System.out.println("HelloPrivate"); } }
- 通过类名.class来获取
Class<People> peopleClass = People.class;
- 通过对象.class()来获取
People people = new People(); Class<? extends People> peopleClass = people.getClass();
- 通过Class.forName(“类的全路径名”)来获取
Class<?> peopleClass = Class.forName("org.staybug.pojo.People");
反射字段属性
Class中获取字段属性的方法有如下几种
- public Field[] getFields():返回该类型的所有 public 修饰的属性,包括父类的
- public Field getField(String name):根据字段名称返回相应的 public 修饰的字段
- public Field[] getDeclaredFields():返回本类型中申明的所有字段,包含非 public 修饰的但不包含父类中的
- public Field getDeclaredField(String name):同理
//获取People类中私有属性,并通过暴力访问的方式设置值 Class<?> peopleClass = Class.forName("org.staybug.pojo.People");People people = (People) peopleClass.newInstance();//获取People对象 Field name = peopleClass.getDeclaredField("name"); name.setAccessible(true);//开启暴力访问,使设置name的值时成功 name.set(people,"张三"); System.out.println(people.getName());
控制台打印出张三
反射方法
Class也提供了四种方法来反射方法
- public Method[] getMethods():返回所有的 public 方法,包括父类中的
- public Method getMethod(String name, Class<?>… parameterTypes):返回指定的public方法
- public Method[] getDeclaredMethods():返回本类申明的所有方法,包括非 public 修饰的,但不包括父类中的
- public Method getDeclaredMethod(String name, Class<?>… parameterTypes):同理
//获取Peop类中私有方法 Class<People> peopleClass = People.class;Method sayHelloPrivate = peopleClass.getDeclaredMethod("sayHelloPrivate"); sayHelloPrivate.setAccessible(true); People people = peopleClass.newInstance(); sayHelloPrivate.invoke(people);
控制台打印HelloPrivate
反射构造器
对于 Constructor 来说,Class 类依然为它提供了四种获取实例的方法:
- public Constructor<?>[] getConstructors():返回所有 public 修饰的构造器
- public Constructor<?>[] getDeclaredConstructors():返回所有的构造器,无视访问修饰符
- public Constructor getConstructor(Class<?>… parameterTypes):带指定参数的
- public Constructor getDeclaredConstructor(Class<?>… parameterTypes) :同理
Class<People> peopleClass = People.class;Constructor<People> declaredConstructor = peopleClass.getDeclaredConstructor(String.class,Integer.class); declaredConstructor.setAccessible(true); People people = declaredConstructor.newInstance("张三",18); System.out.println(people);
控制台打印People{name=‘张三’, age=18}
总结
- 反射的大部分应用场景是创建类的实例
第一种方式是通过Class对象.newInstance(),这种方式只能调用默认无参构造方法来创建实例,在Java9中已经被丢弃。
第二种方式是通过Constructor对象.newInstance(),这种方式可以根据传入的参数来调用对应的构造方法来创建实例。Java9中推荐使用。 - 对于被private修饰的方法、属性,要想访问都必须设置setAccessible属性为true