简体   繁体   中英

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

when I use the full path like 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.*; but still it throws the exception if I don't set the full path javatests.Book . Can someone explain to me why?

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.

From docs Class#forName

 public static Class<?> forName(String className)
                    throws ClassNotFoundException

Parameters:
className - the fully qualified name of the desired class.

So this will not throw 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

Class t = Class.forName("java.lang.Thread");

the above code fragment returns the runtime Class descriptor for the class named 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"); 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.

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.

I hope my answer is helpful :)

JLS provides the following description:

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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