简体   繁体   English

指定类的java.lang.ClassNotFoundException

[英]java.lang.ClassNotFoundException for a specified class

In my main I have the following statement 在我的主要内容中,我有以下声明

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"); 当我使用像Class booki = Class.forName("javatests.Book");这样的完整路径时Class booki = Class.forName("javatests.Book"); it is ok. 没关系。

The main class and the Book class are in the same package, I also tried using import static javatests.Book.*; 主类和Book类在同一个包中,我也尝试使用import static javatests.Book.*; but still it throws the exception if I don't set the full path javatests.Book . 但如果我没有设置完整路径javatests.Book它仍会引发异常。 Can someone explain to me why? 有人能解释一下为什么吗?

Class.forName resolves a fully qualified class name to the class. Class.forName将类的完全限定类名解析。 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. 由于方法不知道调用类的包,调用类的包和调用类中的import都不起作用。

From docs Class#forName 来自docs 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程序中导入java.lang.*包,而是从java.lang包加载类Thread需要编写

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的类的运行时类描述符

You always need a qualified class name unless it'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"); 如果我在我的包中定义一个类foo,我可以调用一个方法Class testClass = Class.forName("foo") ,但我不能调用Class testClass = Class.forName("SecureRandom"); even if I import SecureRandom. 即使我导入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. 它可能有一个快捷方式,它试图在本地包中找到东西,但在这背后没有做太多。

Firstly the Book class must be in the package javatests. 首先,Book类必须在包javatests中。
the JVM load the class by name,through the classpath. JVM通过类路径按名称加载类。 There is no class named "Book" in the classpath. 类路径中没有名为“Book”的类。 So JVM give you a ClassNotFoundException when excuse Class.forName("Book"). 所以当借口Class.forName(“Book”)时,JVM会给你一个ClassNotFoundException。 But 'Class.forName("javatests.Book")' tells JVM the class named 'Book' is in package 'javatests'. 但'Class.forName(“javatests.Book”)'告诉JVM名为'Book'的类在包'javatests'中。 So the JVM can find it and load it. 所以JVM可以找到并加载它。

I hope my answer is helpful :) 我希望我的回答很有帮助:)

JLS provides the following description: JLS提供以下描述:

Class lookup is always on behalf of a referencing class and is done through an instance of ClassLoader . 类查找始终代表引用类,并通过ClassLoader实例完成。 Given the fully qualified name of a class , this method attempts to locate, load, and link the class. 给定类的完全限定名称 ,此方法尝试查找,加载和链接类。

The JDK uses one instance of ClassLoader that searches the set of directory tree roots specified by the CLASSPATH environment variable; JDK使用一个ClassLoader实例来搜索由CLASSPATH环境变量指定的目录树根集; and obviously it is not aware of the place (package) it has been called. 显然它不知道它被称为的地方(包)。 That is why it needs fully qualified name. 这就是它需要完全限定名称的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM