JAVA反射概念
JAVA反射(Reflection):在运行状态中,对于任意一类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
先决概念
在学习JAVA的反射机制前我们得先了解下JAVA中的几大对象 Class、Constructor、Field、Method.。
在JAVA程序运行时我们写的的Book.java文件,里面是Book对象有对应的属性和方法,我们通过编辑器IDEA编译运行,首先将Book.java转化为Book.class字节码文件,然后将字节码文件加载进jVM中,字节码文件会在JVM的方法区生成该类的类对象即Class对象,然后我们需要用到的时候根据该Class对象生成实例,生成的实例放在堆中,实例引用放在栈中。(以后有机会补JVM虚拟机内存分布以及类加载全过程)
emsp;获取Class对象有三种方法。我们拿Book举例
@Data
public class Book {
private int id;
private String name;
private String type;
}
获取Book的Class对象
Class book1=null;
Class book2=null;
Class book3=null;
//获取Class对象的第一种方法
try {
book1=Class.forName("cn.lovepi.reflection.bean.Book");
System.out.println("book1==>"+book1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//第二种方法
Book book=new Book();
Object object=book;
book2=object.getClass();
System.out.println("book2==>"+book2);
//第三种方法
book3=Book.class;
System.out.println("book3==>"+book3);
Class对象常用方法:
getName() 获得类中完整名称
getDeclaredFields() 获得类中的所有属性
getDeclaredMethods() 获得类中所有的方法
getConstructors() 获得类构造方法
newInstance() 实例化类对象
就是通过Class对象可以得到该类的所有信息包括属性,方法,构造器。
实际应用
我们先定义一个Car类
public class Car {
private String brand;
private String color;
private int maxSpeed;
//1.默认构造函数
public Car(){
System.out.println("init car!!");
}
//2.带参构造函数
public Car(String brand,String color,int maxSpeed){
this.brand = brand;
this.color = color;
this.maxSpeed = maxSpeed;
}
//3.未带参的方法
public void introduce() {
System.out.println("brand:"+brand+";color:"+color+";maxSpeed:"+maxSpeed);
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
}
Java反射机制
public class ReflectTest {
/**
* 通过默认的构造方法来实例化car,并获取car的相关属性。
* @return
* @throws Throwable
*/
public static Car initByDefaultConst() throws Throwable
{
//1.通过类装载器获取Car类对象
//使用当前线程获取类加载器
ClassLoader loader = Thread.currentThread().getContextClassLoader();
//通过使用全限定类名来装载Car类对应的反射实例
Class clazz = loader.loadClass("cn.lovepi.chapter02.reflect.Car");
//2.获取类的默认构造器对象并实例化Car
//通过Car的反射类对象来获取Car的构造函数对象.
Constructor cons = clazz.getDeclaredConstructor((Class[])null);
//通过构造函数对象的newInstance方法来实例化Car对象,其效果等同与new Car()
Car car = (Car)cons.newInstance();
//3.通过反射方法设置属性
//通过Car的反射类对象的getMethod方法来获取相应的set方法对象.
//第一个参数是目标class的方法,第二个参数是方法注册的对象类型
Method setBrand = clazz.getMethod("setBrand",String.class);
//通过invoke方法来调用目标类的方法
//该方法的第一个参数是操作的目标类示例,第二个参数则是目标方法的主参
setBrand.invoke(car,"奔驰");
Method setColor = clazz.getMethod("setColor",String.class);
setColor.invoke(car,"黑色");
Method setMaxSpeed = clazz.getMethod("setMaxSpeed",int.class);
setMaxSpeed.invoke(car,200);
return car;
}
/**
* 获取类的带有参数的构造器对象来实例化car并设置相关的属性
* @return
* @throws Throwable
*/
public static Car initByParamConst() throws Throwable{
//1.通过类装载器获取Car类对象
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class clazz = loader.loadClass("cn.lovepi.chapter02.reflect.Car");
//2.获取类的带有参数的构造器对象
Constructor cons = clazz.getDeclaredConstructor(new Class[]{String.class,String.class,int.class});
//3.使参数的构造器对象实例化Car
Car car = (Car)cons.newInstance(new Object[]{"宝马","红色",180});
return car;
}
public static void main(String[] args) throws Throwable {
Car car1 = initByDefaultConst();
Car car2 = initByParamConst();
car1.introduce();
car2.introduce();
}
}
总结所谓反射机制就是我们知道了这个Class就能干关于这个Class的一切事情。
网友评论