指定类的 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 19:18:29  来源:igfitidea点击:

java.lang.ClassNotFoundException for a specified class

javaclassnotfoundexception

提问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.ClassNotFoundExceptionexception

抛出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.forNameresolves 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 imports in the calling class play any role.

Class.forName将完全限定的类名解析为类。由于一个方法不知道从哪里调用它,因此调用类的包和调用类中的imports都不起作用。

回答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 Threadfrom java.langpackage you need to write

比如java.lang.*java程序中不需要导入包,而是Threadjava.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 ClassLoaderthat 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 环境变量指定的一组目录树根;显然它不知道它被调用的地方(包)。这就是为什么它需要完全限定的名称。