指定类的 java.lang.ClassNotFoundException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19675138/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java.lang.ClassNotFoundException for a specified class
提问by Avraam Mavridis
In my main I have the following statement
在我的主要我有以下声明
Class booki = Class.forName("Book");
Class booki = Class.forName("Book");
which throws a java.lang.ClassNotFoundException
exception
抛出java.lang.ClassNotFoundException
异常
when I use the full path like Class booki = Class.forName("javatests.Book");
it is ok.
当我使用完整路径时Class booki = Class.forName("javatests.Book");
就可以了。
The main class and the Book class are in the same package, I also tried using import static javatests.Book.*;
but still it throws the exception if I don't set the full path javatests.Book
. Can someone explain to me why?
主类和 Book 类在同一个包中,我也尝试使用,import static javatests.Book.*;
但如果我不设置完整路径,它仍然会抛出异常javatests.Book
。有人可以向我解释为什么吗?
采纳答案by Henry
Class.forName
resolves a fully qualified class name to the class. Since a method does not know where it is called from neither the package of the calling class nor import
s in the calling class play any role.
Class.forName
将完全限定的类名解析为类。由于一个方法不知道从哪里调用它,因此调用类的包和调用类中的import
s都不起作用。
回答by Aniket Kulkarni
From docs Class#forName
来自文档Class#forName
public static Class<?> forName(String className)
throws ClassNotFoundException
Parameters:
className - the fully qualified name of the desired class.
参数:
className - 所需类的完全限定名称。
So this will not throw ClassNotFoundException
所以这不会抛出 ClassNotFoundException
Class booki = Class.forName("javatests.Book");
For example, it is not needed to import java.lang.*
package in java program but to load class Thread
from java.lang
package you need to write
比如java.lang.*
java程序中不需要导入包,而是Thread
从java.lang
包中加载类需要编写
Class t = Class.forName("java.lang.Thread");
the above code fragment returns the runtime Class descriptor for the class named java.lang.Thread
上面的代码片段返回名为的类的运行时类描述符 java.lang.Thread
回答by Vigilant
You always need a qualified class name unlessit's inside the same package. If i define a class foo in my package i can call a method Class testClass = Class.forName("foo")
, but i can't call Class testClass = Class.forName("SecureRandom");
even if I import SecureRandom. That's just how the function works. It probably has a shortcut where it tries to find things inside local packages, but doesn't do much behind that.
你总是需要一个限定的类名,除非它在同一个包中。如果我在我的包中定义了一个类 foo 我可以调用一个方法Class testClass = Class.forName("foo")
,但Class testClass = Class.forName("SecureRandom");
即使我导入 SecureRandom我也不能调用。这就是该功能的工作方式。它可能有一个快捷方式,可以尝试在本地包中查找内容,但在这之后并没有做太多事情。
回答by kaya.rong
Firstly the Book class must be in the package javatests.
the JVM load the class by name,through the classpath.
There is no class named "Book" in the classpath.
So JVM give you a ClassNotFoundException when excuse Class.forName("Book").
But 'Class.forName("javatests.Book")' tells JVM the class named 'Book' is in package 'javatests'.
So the JVM can find it and load it.
首先,Book 类必须在包 javatests 中。
JVM 通过类路径按名称加载类。类路径中没有名为“Book”的类。所以 JVM 在借口 Class.forName("Book") 时会给你一个 ClassNotFoundException。但是 'Class.forName("javatests.Book")' 告诉 JVM 名为 'Book' 的类在包 'javatests' 中。所以JVM可以找到它并加载它。
I hope my answer is helpful :)
我希望我的回答有帮助:)
回答by Ean V
JLS provides the following description:
JLS 提供以下说明:
Class lookup is always on behalf of a referencing class and is done through an instance of
ClassLoader
. Given the fully qualified name of a class, this method attempts to locate, load, and link the class.
类查找始终代表引用类,并通过
ClassLoader
. 给定类的完全限定名称,此方法尝试定位、加载和链接该类。
The JDK uses one instance of ClassLoader
that searches the set of directory tree roots specified by the CLASSPATH environment variable; and obviously it is not aware of the place (package) it has been called. That is why it needs fully qualified name.
JDK 使用一个实例ClassLoader
来搜索由 CLASSPATH 环境变量指定的一组目录树根;显然它不知道它被调用的地方(包)。这就是为什么它需要完全限定的名称。