反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。 反射是Java被视为动态语言的关键。
Java万事万物皆对象,我们声明的类都被虚拟机视为对象,Class, Method,Field ,Constructor
class封装了对应当前类的信息。
使用场景:
使用各种框架时,不能实例化对象。
三种方法获取Class
Servant servant = new Servant();
//第一种方法 简单安全,不需要try~catch, 动态块 静态块 构造方法均不执行。
Class cls = servant.class;
//第二种方法 会执行静态块 动态块,构造方法。
Class cls1 = class.getClass();
//第三种方法 包名 +类名 需要try~catch, 会执行静态块,
Class cls2 = Class.forName("com.package.name.Servant");
cls.newInstance
类加载器

获取构造方法
Class<Person> clazz = Class.forName(" className");
Constructor<Person>[] constructors = (Constructor<Peron>[]) class.getConstructors();
for(Constructor<Person> construcot : contructors){
// 参数与构造方法类型一致,基本类型要用int.class double.class 等等。
construct.getConstructor(String.class,int.class);
Person person = constructor.newInstance("Tom",18);
}
Method[] method = clazz.getMethods(); //获取所有的方法,包括父类方法 。但是不能获取私有方法
Method[] methods = clazz.getDeclaredMethods(); //获取所有声明的方法,不包括父类方法。
// 可以获取指定的方法,包括私有方法。
Method method = clazz.getDeclaredMethods("methodName",String.class);
Method setAge = clazz.getDeclaredMethods("setAge",int.class);
//调用方法
Object obj = clazz.newInstance();
method.invoke(obj,"Mark");
setAge.invoke(obj,18);
//执行私有方法时:method.setAccessible(true);
method.setAccessible(true);
method.invoke(obj);
获取成员变量 属性
Field[] fields = clazz.getDeclaredFields(); //获取所有的字段,不能获取父类字段
for(Field field: fields){
System.out.println(field.getName());
}
//获取指定字段: 要传入字段的名称
Field field = Clazz.getDeclaredField("name");
//设置变量 ----要指定对象 指定对象的值
Person person = new Person("Mar",18);
Object val = field.get(person);
field.set(person,"Tom");
//字段是私有的 读或写 前要调用 field.setAccessible(true);
Field age = clazz.getDeclaredField("age");
age.setAccessible(true);
网友评论