Java class loading mechanism

Source: Internet
Author: User

Start by throwing a few of your own programs that often raise questions.

1. When does the Java class load?

2, class loading mechanism?

3. How do I load a custom java.lang.String?

Class loading Overview and timing

Java class loading refers to the virtual machine load the class file into memory, and the data for validation, conversion parsing and initialization, the final form can be used directly by the virtual machine Java type.

In Java, the loading, joining, and initialization of types are done during the run of the program, which makes the class load less performance, but provides a high degree of flexibility for Java, which is inherently dynamically extensible in Java, depending on the nature of the runtime dynamic loading and dynamic connection.

Class is loaded into the memory of the virtual machine, and its life cycle includes the following phases, until the memory is unloaded.

Where the order of the 5 stages of loading, validating, preparing, initializing, unloading is determined, the class's loading process must follow that order. However, the parsing phase is not necessarily, it is possible to initialize the branch, which is to support the Java Voice Runtime binding is dynamic binding (polymorphic).

Under what circumstances do you need to start the first phase of class loading: Load? The Java Virtual Machine specification does not impose constraints and is freely grasped by the virtual machine. However, in the initialization phase, the virtual machine specification strictly requires only five cases (load, verify, prepare to start before)

1) Instantiate the object with new, get static (read today's field), put static (set static field), Invoke static (execute static method). The final modified static variable, which has been put into a constant pool at compile time, does not initialize the class.

2) Use Java.lang.reflect

3) When initializing a class, its parent class is not initialized and its parent class is initialized first

4) When the virtual machine starts, the user needs to specify a main class to execute (the class that contains the main () method), and the virtual opportunity initializes the class first

5) When using jdk1.7 's dynamic language support, if a java.lang.invoke.MethodHandle instance finally resolves the result ref_getstatic, Ref_putstatic, re_invokestatic method handle, And the class that corresponds to this method handle is not initialized, it needs to be triggered before it is initialized.

We use the following code as a simple test.

Parent class:

public class Superclass {static{system.out.println ("superclass init!");} public static int val1 = 123;public final static int val2=123;}

Sub-class:

public class subclass extends Superclass{static{system.out.println ("Subclass init!");}}

Test class:

public class Notinitialization {public static void main (string[] args) {System.out.println (SUBCLASS.VAL1);//superclass [] SCA = new Superclass[10];//system.out.println (SUBCLASS.VAL2);}}

The first line prints the code, and only "superclass init" is output, not subclasses. For a static field, only the class that directly defines the field is instantiated. The second line of printed code and the third line of printed code do not initialize the corresponding class. The second line does not initialize superclass because the array is also a type, and it actually initializes the array class that the virtual machine automatically generates, with the properties of the array (such as length). The third line is because it is a constant.


The process of class loading

1, "Load" is a stage of the class loading process. During the load phase, the virtual machine needs to complete the following 3 things

1) obtain a binary byte stream that defines this class by using the fully qualified name of the class

2) Convert the static storage structure represented by this byte stream into the runtime data structure of the method area

3) Generate a Java.lang.Class object representing this class in memory as the access entry for various data of this class in the method area.

2, verification, verification is the first step of the connection. Ensure that the information contained in the byte stream of the class file checks the requirements of the current virtual machine and does not compromise the security of the virtual machine.

3. Preparation, the preparation phase is the stage that formally allocates memory for class variables and sets the initial value of class variables, and the memory used by these variables is allocated in the method area.

At this point the memory allocation is nearly included in the class variable (the static modified variable), not including the instance variable, the instance variable will be in the object instantiation when the Suizhou object is allocated in the Java heap. Second, the usual initial value is the 0 value of the data type (the final decorated static variable, which is assigned at that stage). Such as:

public static int value = 123;

The initial value of the variable value after the prep phase is 0 instead of 123, and the action that assigns value to 123 will not be executed until the initialization stage.

4, parsing, parsing phase is the process by which a virtual machine replaces a symbolic reference within a constant pool with a direct reference.


5, initialization, initialization is the last step of class loading, the previous class loading process, in addition to the loading phase of the user can participate through the custom class loader, the rest of the action is completely dominated and controlled by the virtual machine. Until the initialization phase, the Java code is actually executed.


Class Loader


The role of the ClassLoader is to obtain a binary byte stream that describes this class through the fully qualified name of a class.

Typically we divide the ClassLoader into 3 types

1. Launch class loader (BootStrap ClassLoader) 2, Extension class loader (Extension ClassLoader) 3, Application ClassLoader (Application ClassLoader)


The delegate mechanism of the class loader

When Java virtual machines load a class, what kind of loader does it send to load?

1) The class loader of the current thread is first loaded to load the first class in a thread

2) If Class B is referenced in Class A, the Java Virtual machine will use the class loader that loads class A to load Class B

3) You can also call the Classloader.loadclass () method directly to specify a class loader to load a class.

Each classloader itself can only load classes in specific locations and directories individually, but they may delegate other class loaders to load classes, which is the class loader's delegate mode. class loader-level delegation to the Bootstrap class loader, when bootstrap cannot load the class that is currently being loaded, and then rolls back to the descendant class loader for a true load. When you fall back to the original class loader, you should report the classnotfoundexception exception if it cannot complete the load of the class itself.

Advantages of using the delegation mechanism: To make Java classes loaded with hierarchical precedence, to prevent Java classes from being loaded by different classloader, to ensure that each class in memory is loaded only once, increasing the security and stability of the program.

Custom Class Loaders

The class loader is primarily done by executing the Loadclass,findclass,defineclass 3 methods in turn

Here we define a simple classloader that references the in-depth understanding of Java virtual machines

public class Myclassloader extends ClassLoader {@Overridepublic class<?> loadclass (String name) throws Classnotfoundexception{system.out.println ("Name:" +name); try{string fileName = name.substring (Name.lastindexof (".") +1) + ". Class"; InputStream is = GetClass (). getResourceAsStream (FileName), if (is = = null) {return super.loadclass (name);} Byte[] B = new byte[is.available ()];is.read (b); return defineclass (name, b, 0, b.length);} catch (IOException e) {throw new ClassNotFoundException ();}}}

Test code

public class Classloadertest {public static void main (string[] args) throws Exception {excute1 ();} static void Excute1 () throws Exception{classloader Myloader = new Myclassloader (); Object obj = Myloader.loadclass ("com.ba Se.classloading.item3.ClassLoaderTest "). newinstance (); System.out.println (obj instanceof com.base.classloading.item3.ClassLoaderTest);((classloadertest) obj). Printmsg ()    ;}    public void Printmsg () {System.out.println ("test"); }}

Execution Result:

Name:com.base.classloading.item3.ClassLoaderTestname:java.lang.Objectname:java.lang.ClassLoadername:com.base.classloading . Item3. Myclassloaderfalseexception in thread "main" java.lang.ClassCastException: Com.base.classloading.item3.ClassLoaderTest cannot is cast to Com.base.classloading.item3.ClassLoaderTestat Com.base.classloading.item3.ClassLoaderTest.excute1 (classloadertest.java:11) at Com.base.classloading.item3.ClassLoaderTest.main (Classloadertest.java:5)

By running the results we can see that myclassloader in addition to loading classloadertest will also load related classes. However, the object that is loaded and instantiated with the custom loader does a type check return false, and the owning method cannot be called.

This is because there are two classloadertest in the system , one is myclassloader loaded, and the other is appclassloader loaded. Classes that are loaded by different classloader are not equal.

Now let's load the next java.lang.String with this classloader. Because this classloader can only load classes under the same package, you need to rewrite the next program

Public class<?> loadclass (String name) throws Classnotfoundexception{system.out.println ("name:" +name); try{ String fileName = "/" +name.replace (".", "/") + ". Class"; InputStream is = GetClass (). getResourceAsStream (filename); = = null) {return super.loadclass (name);} Byte[] B = new byte[is.available ()];is.read (b); return defineclass (name, b, 0, b.length);} catch (IOException e) {throw new ClassNotFoundException ();}}

Run

ClassLoader Myloader = new Myclassloader (); Myloader.loadclass ("java.lang.String");

return results

Name:java.lang.StringException in thread "main" java.lang.SecurityException:Prohibited package Name:java.langat Java.lang.ClassLoader.preDefineClass (Unknown source) at Java.lang.ClassLoader.defineClassCond (Unknown source) at Java.lang.ClassLoader.defineClass (Unknown source) at Java.lang.ClassLoader.defineClass (Unknown source) at Com.base.classloading.item3.MyClassLoader.loadClass (myclassloader.java:38) at Com.base.classloading.item3.ClassLoaderTest.excute1 (Classloadertest.java:9) at Com.base.classloading.item3.ClassLoaderTest.main (Classloadertest.java:5)

It can be seen that our own class loader is not authorized to load the Java.lang class below.

Now there is a problem, as we said earlier, class loading uses a delegate mechanism, so when our custom ClassLoader loads the class, it should be delegated to the previous layer, and why there are two exceptions.

The main reason here is that this class loader is a bit of a problem. It was too violent, and it was forced to load the class directly in the LoadClass () method.

After Jdk1.2 has not advocated the user to overwrite the LoadClass () method, but should write their own class load logic into the Findclass () method, in the logic of the LoadClass () method if the parent class fails to load, it will call its own findclass () method to complete the load, so that the newly written ClassLoader is guaranteed to be in compliance with the delegation mechanism.

We remove the previous LoadClass method, overriding the Findclass () method of the parent class, in the overriding implementation ClassLoader

@Overrideprotected class<?> Findclass (String name) throws ClassNotFoundException {InputStream is = null;try {is = NE W FileInputStream (name); byte[] B = new byte[is.available ()];is.read (b); return defineclass (b,0,b.length);} catch (Exception e) {e.printstacktrace ();} Finally{try{is.close ();} catch (Exception e) {e.printstacktrace ();}} return Super.findclass (name);}

Now we are testing the previous code, the discovery will be able to pass the normal, in fact, these classes are entrusted to the Appclassloader. If we are going to load these classes, we can put these classes into a class file in a directory, like Tomcat.

Now let's test the java.lang.String this class file into a directory and load it

Object obj = Myloader.loadclass ("H:/codelover/commonjavaexample/temp/class/classloadertest.class"). NewInstance (); System.out.println (Obj.getclass (). getClassLoader ()); Myloader.loadclass ("h:/codelover/commonjavaexample/temp/ Class/string.class ");

To tell the truth, I have always hoped that this is can be loaded, because each interview I say that can be loaded, the interviewer laughs without words. The result is

[Email protected]java.lang.securityexception:prohibited Package Name:java.langat Java.lang.ClassLoader.defineClass1 (Native Method) at Java.lang.ClassLoader.defineClassCond (Unknown Source) at Java.lang.ClassLoader.defineClass (Unknown source) at Java.lang.ClassLoader.defineClass (Unknown source) at Com.base.classloading.item4.MyClassLoader.findClass (myclassloader.java:15) at Java.lang.ClassLoader.loadClass ( Unknown source) at Java.lang.ClassLoader.loadClass (Unknown source) at Com.base.classloading.item4.ClassLoaderTest.excute1 (classloadertest.java:22) at Com.base.classloading.item4.ClassLoaderTest.main (CLASSLOADERTEST.JAVA:10)

The visible class loader should be the root path of the class from which we cannot load java.lang.String.










Java class loading mechanism

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.