2013-08-31 137 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()); 
相关问题