2013-08-31 73 views
1

我測試從另一個類訪問私有方法的一個例子,得到了一個異常拋出java.lang.ClassNotFoundException:甲

public class WithoutMain 
{  
    public static void main(String args[]) throws Exception 
    { 
     Class c = Class.forName("A"); 
     Object o = c.newInstance(); 
     Method m = c.getDeclaredMethod("message", null); 
     m.setAccessible(true); 
     m.invoke(o, null); 
    } 
} 

public class A { 

    private void message(){ 
     System.out.println("This is a private method."); 
    } 
} 

獲得以下異常

Exception in thread "main" java.lang.ClassNotFoundException: A 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 
    at java.lang.Class.forName0(Native Method) 

這些2類駐留在同一個包。誰能告訴我爲什麼這個例外顯示?

+2

什麼包一中? – sanbhat

+0

這兩個類都駐留在同一個包中。 – skabir

+0

@skabir包名是什麼? – arshajii

回答

2

您必須提供該類的全限定名稱,而不僅僅是簡單的類名稱。

Class c = Class.forName("<package>.A"); 
1

嘗試改變

Class c = Class.forName("A"); 

Class c = Class.forName("yourPackagePath.A"); 

中的forName方法不參與帳戶的用戶呼叫的包。

1

您需要的FQN按the docs

參數:
     的className - 所需類的完全限定名。

4

你需要使用一個類的完全限定名稱使用Class.forName()

現在你可能會說爲什麼加載它?在你的情況下,這兩個類都在同一個目錄/包中。

我會以另一種方式爭論,在java中沒有規定類加載器將首先在同一目錄中查找的規則。

如果您想了解類加載是如何工作的,我建議你的源代碼的類java.lang.ClassLoader

因此,當你調用它採用委託和被分配的任務來加載這個類加載器的Class.forName班級不會知道當前的包裹或任何地點。因此,它需要完全合格的類名稱。

還有一個提示,在java中,加載類的全限定類名是<ClassLoader><packageName><className>。這就是JVM中的類是如何唯一標識的。

希望這有助於

編輯

您的代碼將只在一個條件下工作,那就是,如果兩個類都在默認包。

0

Java Class類不在您的包中,因此它需要知道類所在的位置,否則它不知道它在何處以便加載它(就像類加載器從完整文件加載它一樣路徑)。

所以

Class<? extends Object> c = Class.forName("A"); 

需求是

Class<? extends Object> c = Class.forName("package.A"); 

其中package是包的完整合格的名稱,因此,如果包是

foo.bar 

它會成爲

Class<? extends Object> c = Class.forName("foo.bar.A"); 
0

正如前面答案中所述,需要全名。

爲了避免手動輸入,你可以簡單地使用:

Class<?> clazz = Class.forName(A.class.getName()); 
相關問題