开发者

Difference between loadClass(String name) and loadClass(String name, boolean resolve)

What is the difference between loadClass(String name) and loadClass(String name, boolean resolve) ?

The only difference I know is loadClass(String name, boolean resolve) calls findLoadedClass(String) if the resolve parameter is true?

So when is true or false passed to resolve parameter ?

I'm confused a lot between this two fu开发者_JAVA技巧nctions.

Thanks.


The resolve parameter controls whether the class that's loaded is linked or not. During linking, static constants are initialized and have their memory allocated. Additionally, the class is verified for correctness, and possibly links to other classes will be resolved.

This could be useful, for example, if you wanted to load in a new class that may be malformed and don't want the JVM to throw verification errors in the event that the class is buggy.


The class is linked anyway when it is first used (or at least the used parts) - with the resolve flag you can cause the VM to do this linking (and throw the relevant errors) immediately instead of later.


You can make a try.

public class Test3  {

    static{
         new Test();
    }   
}

After compiling,change the Test Class from a concrete class to a interface.but remain Test3 link to a concrete Class Test.Then if resolve is false, JVM will not find this error.It's very interesting. Actually, Class someClass1= Class.forName("Test3",false,cls) will not resolve Test3,either.It means no error will be thrown.

But if you set resolve true in subClass or Class.forName("Test3"), then JVM in the runtime will find the class link error.

Exception in thread "main" java.lang.InstantiationError: Test
    at Test3.<clinit>(Test3.java:6)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:169)

For your reference, the Java Language Specification - 12.3 Linking of Classes and Interfaces explain what resolveClass does.

12.3 Linking of Classes and Interfaces Linking is the process of taking a binary form of a class or interface type and combining it into the runtime state of the Java virtual machine, so that it can be executed. A class or interface type is always loaded before it is linked. Three different activities are involved in linking: verification, preparation, and resolution of symbolic references.The precise semantics of linking are given in chapter 5 of The Java Virtual Machine Specification, Second Edition. Here we present an overview of the process from the viewpoint of the Java programming language.

12.3.3 Resolution of Symbolic References The binary representation of a class or interface references other classes and interfaces and their fields, methods, and constructors symbolically, using the binary names (§13.1) of the other classes and interfaces (§13.1). For fields and methods, these symbolic references include the name of the class or interface type that declares the field or method as well as the name of the field or method itself, together with appropriate type information. Before a symbolic reference can be used it must undergo resolution, wherein a symbolic reference is checked to be correct and, typically, replaced with a direct reference that can be more efficiently processed if the reference is used repeatedly.

If an error occurs during resolution, then an error will be thrown. Most typically, this will be an instance of one of the following subclasses of the class IncompatibleClassChangeError, but it may also be an instance of some other subclass of IncompatibleClassChangeError or even an instance of the class IncompatibleClassChangeError itself. This error may be thrown at any point in the program that uses a symbolic reference to the type, directly or indirectly:

IllegalAccessError: A symbolic reference has been encountered that specifies a use or assignment of a field, or invocation of a method, or creation of an instance of a class, to which the code containing the reference does not have access because the field or method was declared private, protected, or default access (not public), or because the class was not declared public. This can occur, for example, if a field that is originally declared public is changed to be private after another class that refers to the field has been compiled (§13.4.6).

InstantiationError: A symbolic reference has been encountered that is used in a class instance creation expression, but an instance cannot be created because the reference turns out to refer to an interface or to an abstract class. This can occur, for example, if a class that is originally not abstract is changed to be abstract after another class that refers to the class in question has been compiled (§13.4.1).

NoSuchFieldError: A symbolic reference has been encountered that refers to a specific field of a specific class or interface, but the class or interface does not contain a field of that name. This can occur, for example, if a field declaration was deleted from a class after another class that refers to the field was compiled (§13.4.7).

NoSuchMethodError: A symbolic reference has been encountered that refers to a specific method of a specific class or interface, but the class or interface does not contain a method of that signature. This can occur, for example, if a method declaration was deleted from a class after another class that refers to the method was compiled (§13.4.11). Additionally, an UnsatisfiedLinkError (a subclass of LinkageError) may be thrown if a class declares a native method for which no implementation can be found. The error will occur if the method is used, or earlier, depending on what kind of resolution strategy is being used by the virtual machine (§12.3).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜