一、Java反射机制的实例、
packagecom.xiaoxiao.reflect;public classCar {privateString brand;privateString color;private intmaxSpeed;publicCar(){
}public Car(String brand, String color, intmaxSpeed) {this.brand =brand;this.color =color;this.maxSpeed =maxSpeed;
}publicString getBrand() {returnbrand;
}public voidsetBrand(String brand) {this.brand =brand;
}publicString getColor() {returncolor;
}public voidsetColor(String color) {this.color =color;
}public intgetMaxSpeed() {returnmaxSpeed;
}public void setMaxSpeed(intmaxSpeed) {this.maxSpeed =maxSpeed;
}public voidintroduce(){
System.out.println("brand:"+brand+";color:"+color+";maxSpeed"+maxSpeed);
}
}
方法一、通过直接调用方法来创建Car的实例,这属于一般方法
Car car = newCar();
car.setBrand("红旗CA72");
Car car2= new Car("红旗CA72","黑色",300);
方法二、通过java反射机制来完成Car实例的创建,即通过编程方式调用Class的各项功能,步骤如下:
1、获取当前线程的ClassLoader,然后通过制定的全限定类名“com.xiaoxiao.reflect.Car”装载Car类对应的反射实例;
2、通过Car的反射实例对象获取Car的构造器函数对象cons,通过构造函数对象的newInstance()方法实例化Car对象,其效果等同于new Car()
3、通过Car的反射类对象的getMethod(String methodName, Class paramClass)获取属性的Setter方法对象,其中第一个参数是目标Class的方法名;第二个参数是方法入参的对象类型。在获得方法反射对象后,即可通过invoke(Object obj,Object param)方法调用目标类的方法,该方法的第一个参数是操作的目标类对象实例,第二个参数是目标方法的入参。
packagecom.xiaoxiao.reflect;importjava.lang.reflect.Constructor;importjava.lang.reflect.Method;public classReflectTest {public static Car initByDefaultConst() throwsThrowable {//1。通过类装载器获取Car类对象
ClassLoader loader =Thread.currentThread().getContextClassLoader();
Class> clazz = loader.loadClass("com.xiaoxiao.reflect.Car");//2.获取类的默认构造器对象并通过它 实例化Car
Constructor> cons = clazz.getDeclaredConstructor((Class[])null);
Car car=(Car) cons.newInstance();//3.通过反射方法设置属性
Method setBrand = clazz.getMethod("setBrand", String.class);
setBrand.invoke(car,"红旗CA72");
Method setColor= clazz.getMethod("setColor", String.class);
setColor.invoke(car,"黑色");
Method setMaxSpeed= clazz.getMethod("setMaxSpeed", int.class);
setMaxSpeed.invoke(car,200);returncar;
}public static void main(String[] args) throwsThrowable {
Car car=initByDefaultConst();
car.introduce();
}
}
注解: 在Reflect中有几个重要的反射类,分别是ClassLoader、Class、Constructor和Method,通过这些反射类就可以间接调用目标Class的各项功能。ClassLoader是一个重要的Java运行时系统组件,它负责在JVM运行时查找和装入Class字节码文件。类装载器ClassLoader结构分层:根装载器、ExtClassLoader(扩展类装载器)、和AppClassLoader(应用类装载器),获取类装载器:
packagecom.xiaoxiao.reflect;public classClassLoaderTest {public static voidmain(String[] args) {
ClassLoader classLoader= newClassLoader() {
};
classLoader=Thread.currentThread().getContextClassLoader();
System.out.println("当前装载器:"+classLoader.getClass());
System.out.println("父类装载器:"+classLoader.getParent());
System.err.println("grandparent根装载器:"+classLoader.getParent().getParent());
}
}
结果:
运行以上代码,在控制台将打印出以下信息:
当前装载器:classsun.misc.Launcher$AppClassLoader//根装载器在Java中访问不到,所以返回null
grandparent装载器:null父类装载器:sun.misc.Launcher$ExtClassLoader@6d06d69c
JVM装载类时使用“全盘负责委托机制”,“全盘负责”是指当一个ClassLoder装载一个类时,除非显式地使用另一个ClassLoder,该类所依赖及引用的类也由这个ClassLoder载入;“委托机制”是指先委托父装载器寻找目标类,只有在找不到的情况下才从自己的类路径中查找并装载目标类。正由于这种“全盘负责负责委托机制”,java.lang.String永远是由根装载器来装载的。
二、Java反射机制
Class反射对象描述类语义结构,可以从Class对象中获取构造函数、成员变量、方法类等类元素的反射对象,并以编程的方式通过这些反射对象对目标类对象进行操作。这些反射对象元素类在java.lang.reflect包中定义,下面介绍3个主要的反射类:
Constructor:类的构造函数反射类,通过Class#getConstructors()方法可以获取类的所有构造函数反射对象数组。
Method:类方法的反射类,通过Class#getDeclaredMethods()方法可以获取类的所有方法反射类对象数组Method[]
Field:类的成员变量的反射类,通过Class#getDeclaredFields()方法可以获取类的成员变量数组