都说反射是框架的灵魂,但是反射到底是啥呢,今天就聊聊反射的基础操作,也是必备操作。
反射机制是在程序运行时,对任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能调用他的任意一个属性和方法,将类的各个组成部分封装成对象,这就是反射机制。也就是说一个程序,在刚写好时是一个.java文件,当你编译之后,此时会生成.class字节码文件,这个时候的文件都是在硬盘中存储的,而并未加载到内存中,要想把硬盘中的字节码文件加载到内存,也就是类加载器(ClassLoader),可以把字节码文件加载到内存中,在内存中有一个Class类对象用来描述.class字节码文件,也就创建出来了我们经常见到的Person p = new Person();
在这里演示一下Class类对象的方法,首先我们创建一个Person类
public class Person {private String name;private int age;public String a;protected String b;String c;private String d;public Person(){}public Person(String name,int age){this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", a='" + a + '\'' +", b='" + b + '\'' +", c='" + c + '\'' +", d='" + d + '\'' +'}';}public void eat(){System.out.println("eat...");}public void eat(String food){System.out.println("eat..."+food);}}
一、获取成员变量
在这里可以获取成员变量,然后能够对成员变量进行赋值和获取它的值
import java.lang.reflect.Field;public class ReflectDemo {public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {//获取Person的Class对象Class personClass = Person.class;//获取所有的public修饰的成员变量Field[] fields = personClass.getFields();for(Field field : fields){System.out.println(field);}//获取单个public修饰的成员变量Field a = personClass.getField("a");//获取成员变量a的值Person p = new Person();Object value = a.get(p);System.out.println(value);//设置a的值a.set(p,"张三");System.out.println(p);//获取所有的成员变量,不考虑修饰符Field[] declaredFields = personClass.getDeclaredFields();for(Field declaredField : declaredFields){System.out.println(declaredField);}//获取单个的成员变量Field d = personClass.getDeclaredField("d");//由于d是私有的,所以需要忽略访问权限修饰符的安全检查d.setAccessible(true);//暴力反射Object value2 = d.get(p);System.out.println(value2);}}
运行结果:
二、获取构造方法
可以获取有参构造和无参构造,有参构造可以设置参数
package com.zhiying;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;public class ReflectDemo1 {public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//获取Person的Class对象Class personClass = Person.class;//获取构造方法,这里以有参构造为例Constructor constructor = personClass.getConstructor(String.class,int.class);System.out.println(constructor);//创建对象Object person = constructor.newInstance("张三",20);System.out.println(person);//无参构造Constructor constructor1 = personClass.getConstructor();System.out.println(constructor1);Object person1 = constructor1.newInstance();System.out.println(person1);}}
运行结果:
三、获取成员方法及类名
可以获取成员方法,有参的可以设置参数,其中包括Object中的方法,获取类的时候,getName()方法
package com.zhiying;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class ReflectDemo2 {public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {//获取Person的Class对象Class personClass = Person.class;//获取指定方法名称//无参Method eatMethod = personClass.getMethod("eat");Person p = new Person();eatMethod.invoke(p);//有参Method eatMethod1 = personClass.getMethod("eat", String.class);eatMethod1.invoke(p,"饭");//获取所有public修饰的方法及方法名称,其中包括Object方法Method[] methods = personClass.getMethods();for(Method method : methods){System.out.println("我是方法:"+method);System.out.println("我是方法名:"+method.getName());}//获取类名String className = personClass.getName();System.out.println("我是类名:"+className);}}