JAVA反射
什么是反射
反射是指在运行状态中,通过对Class字节码文件对象,调用某一个类的任意(包括私有)成员变量,构造方法,成员方法
获取Class对象的三种方式
1.类对象的getClass()方法(从Object类继承来的)例如:
Person p = new Person();
Class c = p.getClass();
2.基本类型的class属性 例如:
Class c = Person.class;
Class c1 = String.class;
3.Class类的forName(String classname)方法(最常用的,注意类名要填完整路径)
Class c = Class.forName("sss.Person");
通过Class对象,获取构造函数并调用
获取到所有的构造方法:Constructor[] con = c.getDeclaredConstructors();
获取到所有的公有构造方法:Constructor[] con = c.getConstructors();
获取任意一个构造方法:
public Constructor getDeclaredConstructor(Class<?>… parameterTypes)
此方法在使用的时候,参数是可变参数,无参数传递时,表示获取无参构造函数,传几个参数表示获取几参构造函数。(注意,参数需要的是Class对象,例如String.class),同时为了也可以获取到私有的方法,需要调用Constructor的setAccessible(true)方法
Constructor con = c.getDeclaredConstructor();
con.setAccessible(true) //获取无参构造函数
Constructor con = c.getDeclaredConstructor(String.class,int.class,String.class);
con.setAccessible(true) //获取三参构造函数
调用构造函数:用Object接收,其实它本质就是需要的类对象
Object obj = con.newInstance();// 无参构造就不传参数,有参数就传参数
通过Class对象,获取成员变量并使用(Field)
Class c = Class.forName("ssss.Person"); //获取类对象
Field[] fields = c.getDeclaredFields(); //获取所有的成员变量(包括私有的)
//获取单个的成员变量并赋值
//先创建一个Person对象
Constructor con = c.getConstructor(); //获取无参构造器
Object obj = con.newInstance();
//获取特定的属性(参数就是要获取的属性名字)
Field field = c.getDeclaredField("name");
field.setAccessible(true);
//给obj对象设置这个属性的值(第一个参数是对象,第二个参数是设置的属性值)
field.set(obj,"哇哈哈");
通过Class对象,获取成员方法并使用(Method)
Class c = Class.forName("ssss.Person"); //获取类对象
Method[] methods = c.getMethods(); //获取自己包括父类的所以公有方法
Method[] methods = c.getDeclaredMethods(); //获取自己的所以方法
//获取单个方法并使用
//先创建一个Person对象
Constructor con = c.getConstructor();
Object obj = con.newInstance();
//public Method getMethod(String name,Class<?>... parameterTypes)获取方法
//第一个参数表示需要的方法名,第二个参数是该方法需要的参数的class类型,是可变参数
//要获取无参的show方法
Method method = c.getDeclaredMethod("show");//因为是无参的,所以无第二个参数
method.setAccessible(true);
//获取一参的show方法
Method method = c.getDeclaredMethod("show",String.class);
method.setAccessible(true);
//public Object invoke(Object obj, Object... args) 调用方法
//第一个参数是类对象即obj,第二个参数是调用方法时的实际参数值。可变参数
//调用无参show方法
method.invoke(obj);
//调用一参show方法
method.invoke(obj,"哇哈哈");