Parsing the initialization of classes in Java virtual machines and the parent delegation mechanism of loaders _java

Source: Internet
Author: User

Initialization of a class
in the initialization phase, the Java virtual machine executes the initialization statement of the class, giving the initial value to the static variable of the class.

In a program, there are two ways to initialize a static variable:

1. Initialize at the declaration of static variable;

2. Initialize in static block of code.

A static variable without an explicit initialization will have the original value.

One of the more bizarre examples:

Package com.mengdd.classloader;

Class Singleton {

  //private static Singleton minstance = new Singleton ()//position 1
  //position 1 output:
  //Counter1:1
  counter2:0 public
  static int counter1;
  public static int counter2 = 0;

  private static Singleton minstance = new Singleton ()//Position 2

  //Position 2 output:
  //Counter1:1
  //counter2:1

  pri Vate Singleton () {
    counter1++;
    counter2++;
  }

  public static Singleton Getinstantce () {return
    minstance;
  }
}

public class Test1 {public

  static void Main (string[] args) {

    Singleton Singleton = Singleton.getinstantce (); 
   system.out.println ("Counter1:" + singleton.counter1);
    System.out.println ("Counter2:" + singleton.counter2);
  }


It is visible that the statement of the generated object is placed in two locations and the output is different (the corresponding location's output is indicated in the program annotation).

This is because the initialization statements are executed in order.

The declaration statements of static variables, as well as static blocks of code, are considered initialization statements for classes, and Java virtual opportunities execute them sequentially in the order in which they are initialized in the class file.

Initialization steps for a class
1. If this class has not yet been loaded and connected, then load and connect first.

2. If the class has a direct parent class, and the parent class has not been initialized, initialize the direct parent class first.

3. If there are initialization statements in the class, the initialization statements are executed sequentially.

Initialization time for class
Java programs can be used in two different ways for classes:

1. Active use

2. Passive use

All Java Virtual machine implementations must initialize each class or interface when it is first actively used by the Java program.

Six types of active use:

1. Create an instance of the class.

New Test ();

2. Access the static variable of a class or interface, or assign a value to the static variable.

int b = TEST.A;
TEST.A = b;

  

3. Calling a static method of a class

Test.dosomething ();

  

4. Reflection

Class.forName ("Com.mengdd.Test");

  

5. Initializes a subclass of a class

Class parent{
}
class Child extends parent{public
   static int a = 3;
}
CHILD.A = 4;

  

A class that is marked as a startup class when the 6.Java virtual machine is started

Java com.mengdd.Test

In addition to the above six scenarios, other ways of using Java classes are considered passive use of classes and do not cause the initialization of classes.

The particularity of the interface
When a Java virtual machine Initializes a class, all of its parent classes are required to be initialized, but this rule does not apply to interfaces.

When a class is initialized, the interface it implements is not initialized first.

When an interface is initialized, its parent interface is not initialized first.

Therefore, a parent interface is not initialized because of its sub-interface or the initialization of the implementation class, which causes the interface to be initialized only when the program first uses the static variables of a particular interface.

Final type of static variable
whether a final type of static variable is a compile-time or a variable affects the execution of the initialization statement block.

If the value of a static variable is a compile-time constant, the type is not initialized (the static block of the class is not executed);

If the value of a static variable is a constant that is not compiled, that is, only the runtime will have a definite initialization value, the type is initialized (the static block of the class executes).

Example code:

Package com.mengdd.classloader;

Import Java.util.Random;

Class FinalTest1 {public
  static final int x = 6/3;//compile time has already known its value is 2, is a constant
  //type does not need to initialize the
  static {
    System.ou T.println ("Static block in FinalTest1");
    This segment statement will not be executed, that is, no output
  }
}

class FinalTest2 {public
  static final int x = new Random (). Nextint (100);/Only Runtime To get
  the value static {
    System.out.println ("Static block in FinalTest2");
    Initialization of the class, that is, the static statement block executes, has output
  }
} public

class Inittest {public

  static void Main (string[] args) {
    System.out.println ("FinalTest1:" + finaltest1.x);
    System.out.println ("FinalTest2:" + finaltest2.x);
  }


Ownership clarity of active use
the active use of a class or interface can only be considered if the static variable or static method that the program accesses is actually defined in the current class or the current interface.

Package com.mengdd.classloader;

Class Parent {
  static int a = 3;

  static {
    System.out.println ("Parent static Block");
  }

  static void DoSomething () {
    System.out.println ("do something");
  }

Class Child extends Parent {
  static {
    System.out.println (' Child static Block ');
  }

public class Parenttest {public

  static void Main (string[] args) {

    System.out.println ("child.a:" + child.a); 
   child.dosomething ();

    The static code block for the child class is not executed, stating that the child class is not initialized
    //This is because the active variables and methods are defined in the parent class
  }


ClassLoader class
invoking the LoadClass () method of the ClassLoader class loads a class, not the active use of the class, and does not cause the class to be initialized.

 Package com.mengdd.classloader;

Class CL {

  static {
    System.out.println ("Static block in CL");
  }

public class Classloaderinittest {public

  static void Main (string[] args) throws Exception {ClassLoader
    loader = Classloader.getsystemclassloader ();
    Class<?> clazz = Loader.loadclass ("Com.mengdd.classloader.CL");
    The LoadClass method loads a class, not the active use of the class, and does not cause the initialization of the class

    System.out.println ("----------------");
    Clazz = Class.forName ("Com.mengdd.classloader.CL");
  }



Parent delegate mechanism of class loader

Class Loader
the ClassLoader is used to load the class into the Java virtual machine.

Type of class loader
There are two types of class loaders:

1.JVM Loader with self:

Root class loader (Bootstrap)

Extended class loader (Extension)

Systems class Loader (System)

2. User-defined ClassLoader:

Java.lang.ClassLoader, the user can customize how the class is loaded.

The JVM's own loader
the Java Virtual machine has its own following loaders.

1. Root (Bootstrap) class loader:

The loader does not have a parent loader.

It is responsible for loading the core class libraries of virtual machines, such as java.lang.*.

The root class loader loads the class library from the directory specified by the system attribute Sun.boot.class.path.

The implementation of the root class loader relies on the underlying operating system, which is part of the implementation of the virtual machine, and does not inherit the Java.lang.ClassLoader class, which is written in C + +.

2. Extension (Extension) class loader:

Its parent loader is the root class loader.

It loads the class library from the directory specified by the Java.ext.dirs system attribute, or loads the class library from the Jre\lib\ext subdirectory (extended directory) of the JDK's installation directory, which is automatically loaded by the Extended class loader if the jar file created by the user is placed in this directory.

The extended class loader is a pure Java class and is a subclass of the Java.lang.ClassLoader class.

3. Systems (System) class loader:

Also known as the Application class loader, its parent loader is an extended class loader.

It loads the class from the environment variable classpath or the directory specified by the system attribute Java.class.path, which is the default parent loader for user-defined ClassLoader.

The System class loader is a pure Java class and is a subclass of the Java.lang.ClassLoader class.

Note: The parent loader concept here does not refer to the inheritance of the class, and the child loader does not necessarily inherit the parent loader (which is actually a combined relationship).

User-defined class loader
In addition to the class loaders that are brought in by the above virtual machines, users can also customize their class loaders (User-defined class Loader).

Java provides an abstract class Java.lang.ClassLoader, and all user-defined ClassLoader should inherit the ClassLoader class.

Parent delegate mechanism loaded by class
starting with the JDK version 1.2, the class loading process uses the Father delegation mechanism, which can better guarantee the security of the Java platform.

In the parent delegate mechanism, in addition to the root class loader that is brought by the Java Virtual machine, the rest of the ClassLoader has and has only one parent loader, and each loader forms a tree structure based on parent-child relationships.

When the Java Program request loader Loader1 loading the sample class, Loader1 first entrusts its own parent loader to load the sample class, if the parent loader can load, the parent loader completes the load task, otherwise the sample class is loaded by the loader1 itself.

An example of a specific process:

Loader2 first finds whether the sample class has been loaded from its own namespace, and if it has been loaded, returns a reference to the class object representing the sample class.

If the sample class has not been loaded, Loader2 first request Loader1 to load, loader1 and then request the System class loader on behalf of loading, the System class loader and then request the Extended class loader on behalf of loading, extended class loader and then request the root class loader on behalf of loading.

If neither the root class loader nor the extended class loader can load, the System class loader tries to load, and if the load succeeds, the reference of the class object corresponding to the sample class is returned to the Loader1,loader1 and returned to Loader2 to successfully load the sample class into the virtual machine.

If the system loader cannot load the sample class, then Loader1 attempts to load the sample class, and if Loader1 cannot successfully load, then LOADER2 attempts to load it.

If all the parent loaders and loader2 themselves cannot be loaded, the ClassNotFoundException exception is thrown.

The conclusion is:

Each loader takes precedence over the parent class, tries to load itself if the parent class cannot load, returns the class object to the subclass if it succeeds, and tells the subclass to load itself if it fails. Throws an exception if all fails.

Defining the class loader and the initial class loader
if a class loader can successfully load the sample class, then the ClassLoader is called the definition class loader.

All class loaders that successfully return a reference to a class object, including the definition class loader, which includes the definition class loader and all the child loaders underneath it, are called the initial class loaders.

Assuming that Loader1 actually loaded the sample class, Loader1 is the class loader for the definition of the sample class, Loader2 and Loader1 are the initial class loaders for the sample class.

Parent-child Relationship
It should be noted that the parent-child relationship between the loaders actually refers to the wrapper relationship between the loader objects rather than the inheritance relationships between the classes.

A pair of parent-child loaders may or may not be two instances of the same loader class.

A parent loader object is wrapped in a child loader object.

For example, Loader1 and Loader2 are instances of the Myclassloader class, and Loader2 wrap Loader1,loader1 as the parent loader of Loader2.

When a custom class loader instance is generated, the System class loader becomes the parent loader of the class loader if its parent loader (the ClassLoader constructor method has no parameters) is not specified.

Advantages of parent delegation mechanism
The advantage of Father entrust mechanism is that it can improve the security of software system.

Because of this mechanism, user-defined class loaders cannot load trusted classes that should be loaded by the parent loader, thereby preventing unreliable or even malicious code from replacing reliable code loaded by the parent loader.

For example, the Java.lang.Object class is always loaded by the root class loader, and any other user-defined ClassLoader cannot load java.lang.Object classes that contain malicious code.

Name space
each class loader has its own namespace, which consists of a class loaded by the loader and all the parent loaders.

In the same namespace, the full name of the class (including the package name of the Class) does not appear with the same two classes.

In different namespaces, it is possible to have the same two classes with the full name of the class, including the package name of the class.

Run-time Package
a Run-time package is composed of classes that belong to the same package loaded by the same class of loaders.

Decide whether the two classes belong to the same run-time package, not only to see if their package names are the same, but also to see if the definition class loader is the same.

Only classes that belong to the same Run-time package can access the class and class members of the package visible (that is, the default access level).

Such restrictions prevent user-defined classes from impersonating the core class library's classes to access the package visible members of the core class library.

The

assumes that the user has defined a class java.lang.Spy and is loaded by a user-defined ClassLoader, because the Java.lang.Spy and core class libraries java.lang.* are loaded by different classloader, and they belong to different run-time packages. Therefore, java.lang.Spy cannot access the package visible members in the core class library Java.lang package.

Related Article

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.