·簡單實例
package com.spring.basic;
public class Car {
private String brand;
private String color;
private int maxSpeed;
public Car(){}
public Car(String brand, String color, int maxSpeed) {
super();
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;
};
}
package com.spring.basic;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class ReflectTest {
public static void main(String[] args) throws Throwable {
//調用類加載器獲取Car對象
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class clazz = loader.loadClass("com.spring.basic.Car");
//獲取類的默認構造方法構造類對象并實例化Car
Constructor cons = clazz.getConstructor();
Car car = (Car) cons.newInstance();
Method setBrand = clazz.getDeclaredMethod("setBrand", String.class);
setBrand.invoke(car, "奔馳");
Method setColor = clazz.getDeclaredMethod("setColor", String.class);
setColor.invoke(car, "白色");
Method setMaxSpeed = clazz.getDeclaredMethod("setMaxSpeed", int.class);
setMaxSpeed.invoke(car, 200);
car.introduce();
}
}
輸出以下信息
brand:奔馳,color:白色,maxSpeed:200
上面實例是通過java反射機制來控制目標類的元信息
·類裝載器ClassLoader
·類裝載器工作機制
類裝載器就是尋找類的字節碼文件并構造出類在JVM內部表示的對象組件,在java中,類裝載器把一個類載入JVM中,要經過以下步驟:
1.裝載:查找和導入Class文件;
2.鏈接:執行校驗、準備和解析步驟,其中解析步驟是可以選擇的;
????a)校驗:檢查載入Class文件數據的正確性
????b)準備:給類的靜態變量分配存儲空間
????c)解析:將符號引用轉成直接引用
3.初始化:對類的靜態變量、靜態代碼塊執行初始化工作
類裝載工作由ClassLoader及其子類負責,ClassLoader是一個重要的Java運行時系統組件,它負責在運行時查找和載入Class字節碼。JVM在運行時會產生3個ClassLoader,根裝載器、ExtClassLoader(擴展類裝載器)和AppClassLoader(系統類裝載器)。其中,跟裝載器不是ClassLoader的子類,它使用C++編寫,因此我們在Java中看不到它,根裝載器負責裝載JRE的核心類庫,如JRE目標下的rt.jar、charsets.jar等。ExtClassLoader和AppClassLoader都是ClassLoader的子類,其中ExtClassLoader負責裝載JRE擴展目錄ext中的JAR類包,AppClassLoader負責裝載Classpath路徑下的類包。
????這3個類裝載器之間存在父子層級關系,即根裝載器是ExtClassLoader的父裝載器,ExtClassLoader是AppClassLoader的父裝載器默認情況下使用AppClassLoader裝載應用程序的類,我們可以做一個實驗:
package com.spring.basic;
public class ClassLoaderTest {
public static void main(String[] args) {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
System.out.println(loader);
System.out.println(loader.getParent());
System.out.println(loader.getParent().getParent());
}
}
sun.misc.Launcher$AppClassLoader@439a8942
sun.misc.Launcher$ExtClassLoader@56a96eba
//根裝載器在java中訪問不到,所以返回null
null
JVM在裝載類時使用“全盤負責委托機制”,“全盤委托”是指當一個類裝載一個類時,除非顯示的使用另一個ClassLoader,該類所依賴及引用的類也由這個ClassLoader載入;委托機制是指委托父類裝載器尋找目標類,只有在找不到的情況下才從自己的類路徑中查找并裝載目標類。這一點是從安全角度考慮的,試想如果有人編寫了一個惡意的基礎類并裝載到JVM中將會引起多么可怕的問題。