@
Java反射
Java語言允許通過程序化的方式間接對Class進行操作。Class文件由類裝載器裝載后,在JVM中將形成一份描述Class結構的元信息對象,通過該元信息對象可以獲知Class的結構信息,如構造函數、屬性和方法等。Java允許用戶借由這個與Class相關的元信息對象間接調用Class對象的功能,這就為使用程序化方式操作Class對象開辟了途徑。
簡單實例
我們將從一個簡單的例子開始探訪Java反射機制的征程。下面的Car類擁有兩個構造函數、一個方法及3個屬性,如代碼清單4-9所示。
代碼清單4-9 Car
package com.smart.reflect;
public class Car {
private String brand;
private String color;
private int maxSpeed;
public Car() {
System.out.println("init 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);
}
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;
}
}
一般情況下,我們會使用如下代碼創建Car的實例:
Car car = new Car();
car.setBrand("紅旗CA72");
或者:
Car car = new Car("紅旗CA72","黑色");
以上兩種方法都采用傳統方式直接調用目標類的方法。下面我們通過Java反射機制以一種間接的方式操控目標類,如代碼清單4-10所示。
代碼清單4-10 ReflectTest
package com.smart.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class ReflectTest {
public static Car initByDefaultConst() throws Throwable {
//①通過類裝載器獲取Car類對象
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class clazz = loader.loadClass("com.smart.reflect.Car");
//②獲取類的默認構造器對象並通過它實例化Car
Constructor cons = clazz.getDeclaredConstructor((Class[]) null);
Car car = (Car) cons.newInstance();
//③通過反射方法設置屬性
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);
return car;
}
public static void main(String[] args) throws Throwable {
Car car = initByDefaultConst();
car.introduce();
}
}
運行以上程序,在控制台上將打印出以下信息:
brand:紅旗CA72;color:黑色;maxSpeed:200
這說明我們完全可以通過編程方式調用Class的各項功能,與通過構造函數和方法直接調用類功能的效果是一致的,只不過前者是間接調用,后者是直接調用罷了。
文章來源:
《精通Spring 4.x:企業應用開發實戰》4.2.1章節