Java反射-類動態加載

VM在執行Java程序的時候,並不是一次性把所有用到的class全部加載到內存,而是第一次需要用到class時才加載。例如:

// Main.java
public class Main {
    public static void main(String[] args) {
        if (args.length > 0) {
            create(args[0]);
        }
    }

    static void create(String name) {
        Person p = new Person(name);
    }
}

當執行Main.java時,由於用到了Main,因此,JVM首先會把Main.class加載到內存。然而,並不會加載Person.class,除非程序執行到create()方法,JVM發現需要加載Person類時,纔會首次加載Person.class。如果沒有執行create()方法,那麼Person.class根本就不會被加載。

這就是JVM動態加載class的特性。

動態加載class的特性對於Java程序非常重要。利用JVM動態加載class的特性,我們才能在運行期根據條件加載不同的實現類。例如,Commons Logging總是優先使用Log4j,只有當Log4j不存在時,才使用JDK的logging。利用JVM動態加載特性,大致的實現代碼如下:

// Commons Logging優先使用Log4j:
LogFactory factory = null;
if (isClassPresent("org.apache.logging.log4j.Logger")) {
    factory = createLog4j();
} else {
    factory = createJdkLog();
}

boolean isClassPresent(String name) {
    try {
        Class.forName(name);
        return true;
    } catch (Exception e) {
        return false;
    }
}

這就是爲什麼我們只需要把Log4j的jar包放到classpath中,Commons Logging就會自動使用Log4j的原因。

小結

  • JVM爲每個加載的classinterface創建了對應的Class實例來保存classinterface的所有信息;
  • 獲取一個class對應的Class實例後,就可以獲取該class的所有信息;
  • 通過Class實例獲取class信息的方法稱爲反射(Reflection);
  • JVM總是動態加載class,可以在運行期根據條件來控制加載class。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章