java反射
案例
1.创建一个Car类
package com.hh.test;
public class Car {
private String brand;
private String color;
private int 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;
}
public Car() {
}
public Car(String brand, String color, int maxSpeed) {
this.brand = brand;
this.color = color;
this.maxSpeed = maxSpeed;
}
public void introduce(){
System.out.println("brand:"+brand+";color:"+color+";maxSpeed:"+maxSpeed);
}
}
2.通过一般思维创建Car实例
package com.hh.test;
public class CarTest {
public static void main(String[] args) {
Car car = new Car();
car.setBrand("宝马");
car.setColor("黑色");
car.setMaxSpeed(100);
car.introduce();
}
}
3.通过Java反射机制创建
package com.hh.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class ReflectTest {
public static Car initByDefaultConst() throws Exception {
//通过类转载器获取Car类对象
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class<?> clazz = loader.loadClass("com.hh.test.Car");
//获取类的默认构造器对象并通过它实例化Car
Constructor<?> cons = clazz.getDeclaredConstructor((Class[]) null);
Car car = (Car)cons.newInstance();
//通过反射方法设置属性
Method setBrand = clazz.getMethod("setBrand", String.class);
setBrand.invoke(car,"宝马");
Method setColor = clazz.getMethod("setColor", String.class);
setColor.invoke(car,"黑色");
Method setMaxSpeed = clazz.getMethod("setMaxSpeed", int.class);
setMaxSpeed.invoke(car,100);
return car;
}
public static void main(String[] args) throws Exception {
Car car = initByDefaultConst();
car.introduce();
}
}
4.两种运行结果都一样,如下:
类装载器
JVM在运行时会产生3个ClassLoader:根装载器,ExtClassLoader(扩展类装载器),AppClassLoader(应用类装载器)。
package com.hh.test;
public class ClassLoaderTest {
public static void main(String[] args) {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
System.out.println("current loader"+loader);
System.out.println("parent loader:"+loader.getParent());
System.out.println("grandparent loader:"+loader.getParent().getParent());
}
}
Java反射机制可以绕过private,protected进行调用
1.PrivateCar类
package com.hh.test;
public class PrivateCar {
//private成员变量:使用传统的类实例调用方式,只能在本类中访问
private String color;
//protected方法:使用传统的类实例调用方式,只能在子类和本包中访问
protected void driver(){
System.out.println("drive private car! the color is:"+color);
}
}
2.PrivateCarReflect类
package com.hh.test;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class PrivateCarReflect {
public static void main(String[] args) throws Exception {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class<?> clazz = loader.loadClass("com.hh.test.PrivateCar");
PrivateCar pCar = (PrivateCar) clazz.newInstance();
Field color = clazz.getDeclaredField("color");
//取消Java语言访问检查以访问private变量
color.setAccessible(true);
color.set(pCar,"黑色");
Method driverMethod = clazz.getDeclaredMethod("driver",(Class[])null);
//取消java语言访问检查以访问protected方法
driverMethod.setAccessible(true);
driverMethod.invoke(pCar,(Object[])null);
}
}
3.运行结果:
4.如果注释掉 color.setAccessible(true);
这行代码,则运行结果如下:
扫描关注下面二维码获得更多有用的资源!