2012-03-13 87 views
5

我有一個小問題。我學習java SE並找到類ClassLoader。我嘗試在下面的代碼中使用它: 我正嘗試使用URLClassLoader在運行時動態加載類。ClassLoader的Java示例

URLClassLoader urlcl = new URLClassLoader(new URL[] {new URL("file:///I:/Studia/PW/Sem6/_repozytorium/workspace/Test/testJavaLoader.jar")}); 
Class<?> classS = urlcl.loadClass("michal.collection.Stack"); 
for(Method field: classS.getMethods()) { 
    System.out.println(field.getName()); 
} 
Object object = classS.newInstance(); 
michal.collection.Stack new_name = (michal.collection.Stack) object; 

Java虛擬機沒有看到我的班,我也得到了以下異常:

Exception in thread "main" java.lang.Error: Unresolved compilation problems: michal cannot be resolved to a type michal cannot be resolved to a type at Main.main(Main.java:62) 

你知道我怎麼能解決這個問題?

+0

你可以發佈你得到的異常和堆棧跟蹤嗎? – Shaunak 2012-03-13 20:50:09

+0

當然:異常在線程「主要」 java.lang.Error的:未解決的編譯問題: \t米哈爾不能被解析爲一個類型 \t米哈爾不能被解析爲一個類型 \t在Main.main(Main.java: 62) – 2012-03-13 20:56:59

回答

4
Class<?> classS = urlcl.loadClass("michal.collection.Stack"); 
[...] 
Object object = classS.newInstance(); 
michal.collection.Stack new_name = (michal.collection.Stack) object; 

所以你試圖動態加載一個類,然後靜態引用它。如果你已經可以靜態鏈接到它,那麼它的加載,你不能再加載它。你需要通過反射來訪問這些方法。

你通常會做的是加載的類實現父類加載器的接口。在創建實例(通常只是一個實例)後,可以通過具有該類型接口的引用來引用它。

public interface Stack { 
    [...] 
} 
[...] 
    URLClassLoader urlcl = URLClassLoader.newInstance(new URL[] { 
     new URL(
      "file:///I:/Studia/PW/Sem6/_repozytorium/workspace/Test/testJavaLoader.jar" 
     ) 
    }); 
    Class<?> clazz = urlcl.loadClass("michal.collection.StackImpl"); 
    Class<? extends Stack> stackClass = clazz.asSubclass(Stack.class); 
    Constructor<? extends Stack> ctor = stackClass.getConstructor(); 
    Stack stack = ctor.newInstance(); 

(約與其說平時堆棧溢出聲明中編譯。)

你需要添加錯誤處理的味道。 URLClassLoader.newInstanceURLClassLoader增加了一點改進。 Class.newInstance已完全打破異常處理,應該避免。

+0

那麼我如何使用這個類的方法呢? – 2012-03-13 21:07:55

+0

@ user1267483您需要在項目中創建一個接口,使用您的michal.collection.Stack實現的堆棧使用URLClassloader。 – 2012-03-13 21:21:39

+0

@ user1267483請注意,我已將Stack的名稱更改爲StackImpl(不是最好的名稱,而是常規名稱),並引入了一個新的接口Stack。 – 2012-03-13 21:40:53

0

您不能在代碼中使用名稱來引用動態加載的類型,因爲這必須在編譯時解析。您需要使用從loadClass()獲取的Class對象的newInstance()函數。

+1

OP在'loadClass'的'Class'對象上使用'Class.newInstance'。 – 2012-03-13 21:04:42

0

以上答案都是錯誤的,他們不瞭解根本問題。你的主要引用由一個類加載器加載的Stack類。您的urlclassloader正在嘗試加載具有相同名稱的類。您不能將加載的內容轉換爲引用,因爲它們不相同,它們屬於不同的類加載器。你可以打印每個的代碼,看看它們是不同的。平等測試也會顯示cclass引用不同。你的問題可能是因爲sstack引用的依賴類可以找到,它會在NoClassDefErrors等中發生。你的main可能會因類classcastexception而失敗。