2017-05-03 144 views
0

我在Java面試中被問到。正如我們所知,由於父代委託模式,Java類加載器只會加載一次類。所以我的答案是使用自定義類加載器來加載它。是對的嗎?如何回答這個問題?如何在JVM中使用類加載器加載類兩次?

+0

你的意思加載*類*兩次? – EJP

+0

@ EJP,是的,你是對的 – flower

+0

使用兩個不同的類加載器 –

回答

2

這取決於。合格名稱以java.開頭的類只能由引導加載程序加載,因此不會第二次加載。由bootstrap加載器加載的所有其他類只能由不遵循父代理模型的自定義類加載器實現加載,因爲引導加載器是所有加載器的父代。

對於由ClassLoader實例加載的所有其他類,可以根據父代委託模型構造標準類加載器,但不能將該加載器作爲父代。但是,當然,您也可以使用自定義加載程序來加載它們,而不是遵循委託模型。這個選擇可能取決於你想如何處理該類引用的其他類,這些類最初是由同一個裝載器加載的。您也可以重新加載它們,創建該環境的完整副本或嘗試將其加載重定向到原始加載程序,如果存在反向引用,則會造成問題。

下面的代碼示例演示了這種方法:

public class ReloadMySelf { 
    public static void main(String[] args) throws IOException, ClassNotFoundException { 
     final Class<?> o = ReloadMySelf.class; 
     URL loc = o.getProtectionDomain().getCodeSource().getLocation(); 
     ClassLoader parent = o.getClassLoader().getParent(); 
     try(URLClassLoader cl = new URLClassLoader(new URL[]{loc}, parent)) { 
      Class<?> duplicate = cl.loadClass(o.getName()); 
      System.out.println("original: "+o+" ("+o.getClassLoader()+')'); 
      System.out.println("duplicate: "+duplicate+" ("+duplicate.getClassLoader()+')'); 
     } 
    } 
}