In-depth understanding of Java: Class loading mechanism and reflection

Source: Internet
Author: User
Tags reflection

First, Java class loading mechanism

1. Overview

When the class file is loaded by the loader, a meta-information object describing the class structure is formed in the JVM, which can be used to learn the structure information of class, such as constructors, properties and methods, etc. Java allows the user to indirectly invoke the functionality of a class object by this class-related meta-information object.

The virtual machine loads the data of the description class from the class file into the memory, verifies the data, transforms parsing and initializing, and finally forms the Java type that can be used directly by the virtual machine, which is the class loading mechanism of the virtual machine.

2. Working mechanism

A class loader is a byte-code file that looks for a class and constructs an object component that the class represents within the JVM. In Java, the class loader loads a class into the JVM, taking the following steps:

(1) Loading: Find and import class files;

(2) Link: Merges the binary data of the class into the JRE;

(a) Verification: check the correctness of loading class file data;

(b) Preparation: Allocating storage space to static variables of the class;

(c) Parsing: Transferring symbolic references to direct references;

(3) Initialize: Static variable for class, static code block to initialize operation

Java programs can be dynamically extended by the runtime dynamic loading and dynamic link implementation, for example: If you write an application using an interface, you can wait until the runtime to specify its actual implementation (polymorphic), the parsing process can sometimes be executed after initialization, such as: Dynamic binding (polymorphic);

"Class initialization"

(1) When encountering the 4 bytecode directives of new, getstatic, putstatic, or invokestatic, if the class has not been initialized, it needs to trigger its initialization first. The most common Java code scenario for generating these 4 instructions is when instantiating an object with the new keyword, reading or setting the static field of a class (except for the static fields that were final decorated, which have been placed in the constant pool at compile time), and when invoking a static method of a class.

(2) When using the Java.lang.reflect package method to make a reflection call to a class, if the class has not been initialized, it needs to trigger its initialization first.

(3) When a class is initially initialized, it is necessary to trigger the initialization of its parent class if it finds that its parent class has not yet been initialized.

(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 main class first.

Only the above four situations trigger initialization, also known as an active reference to a class, except that all other methods do not trigger initialization, called a passive reference

Code Listing 1

Once the code is run, it will only output "---superclass init", not "subclass Init", and for static fields only classes that directly define the field will be initialized, so calling the static field of the parent class through the subclass will only trigger the initialization of the parent class. But this is to see different implementations of different virtual machines.

Code Listing 2

This does not cause superclass initialization, but it triggers the initialization of "[Ltest.superclass", as can be seen through arr.tostring (), which is not a valid class name for user code, it is generated automatically by the virtual machine. Directly inherits from the subclass of object, the creation action is triggered by the bytecode directive NewArray, when the array bounds check is accompanied by all the call procedures of the array object, the cross check is not encapsulated in the class accessed by the array element, but is encapsulated in the Xaload,xastore bytecode instruction of the array access .

Code Listing 3

The reference to the constant constclass.value is actually converted to the Notinitialization class's reference to its own constant pool, which does not have any contact after the two classes have been compiled into class.

Load

During the load phase, the virtual machine needs to complete the following 3 things

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

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

(3) A Java.lang.Class object representing this class is generated in the Java heap as the access entry for the data in the method area.

The virtual machine specification does not specify exactly where the binary stream should be obtained and how it is obtained, and it is possible to control how the byte stream is obtained by defining its own classloader.

Authentication

If the virtual machine does not check the input byte stream and fully trusts it, it is likely that the system will collapse because of the harmful byte stream loading.

Ready

The prep phase is a phase that formally assigns and sets the initial value of class variables to the class variables, which are allocated in the method area and need to be explained as follows:

The memory allocation at this time includes only class variables (static modified variables), not instance variables, and instance variables will be allocated in the Java heap along with the object when the object is instantiated, where the initial value "normal" is the 0 value of the data type, if:

public static int value = 123;

Value has an initial value of 0 instead of 123 after the Prep phase, and the putstatic instruction that assigns value to it will be executed at the initialization stage

class loader and parental delegation model

Class Loader

(1) Bootstrap ClassLoader: Will be stored in the <java_home>\lib directory, or in the path specified by the-xbootclasspath parameter, and is recognized by the virtual machine (only according to the name of the file, such as Rt.jar Class libraries with names that do not conform are loaded into virtual machine memory even if they are placed in the Lib directory. Startup ClassLoader cannot be referenced directly by Java programs

(2) Extension ClassLoader: Load the <java_home>\lib\ext directory or all class libraries in the path specified by the Java.ext.dirs system variable. Developers can use the extension class loader directly.

(3) Application ClassLoader: Responsible for loading the class library specified on the User class path (ClassPath), which can be used directly by the developer.

Working process: If a class loader receives a request for a class load, it first delegates the request to his parent class loader to complete, so that all the load requests should be routed to the start class loader at the top level. The child loader tries to load itself only when the parent loader has feedback that it cannot complete the load request (it does not find the desired class in the search scope).

Benefit: The Java class has a hierarchical relationship with precedence as its classloader. For example, the class Java.lang.Object, which is stored in Rt.jar, regardless of which class loader is loading the class, will eventually be delegated to the startup ClassLoader for loading, so the Object class is the same class in the various class loader environments of the program. Conversely, if the user writes a class named Java.lang.Object and puts it in the program's classpath, there will be several different object classes in the system, and the most basic behavior in the Java type System is not guaranteed and the application becomes chaotic.

Some of the most important methods in Java.lang.ClassLoader:

//loads the binary type of the specified name (including the package name) for the user to invoke the interface PublicClass<?>loadclass (String name);//loads the binary type of the specified name (including the package name) and specifies whether to parse it (however, the resolve parameter here does not really have the effect of parsing) for inheritanceprotected synchronizedClass<?> loadclass (String name,Booleanresolve);protectedClass<?>Findclass (String name)//define the type, generally in the Findclass method to read the corresponding bytecode after the call, you can see the non-inheritance (note: The JVM has implemented the corresponding specific functions, parsing the corresponding byte code, resulting in the corresponding internal data structure to the method area, so no need to overwrite, directly call on it can be) protected FinalClass<?> defineclass (String name,byte[] B,intOffintLenthrowsclassformaterror{}

The following is the main code that implements the parent delegation model:

Third, reflection

The reflection mechanism allows the program to use reflection APIs to obtain internal information for any class of known name, including: package, type parameters, superclass, implemented, in the course of execution. interfaces, inner classes, outer classes, fields, constructors, methods, modifiers, etc., and can be dynamically generated during the execution of instances, Change the contents of fields or evoke methods.

1. Get the Construction method

The class class provides four public methods for getting a class's construction method.

Constructor GetConstructor (class[] params)

Returns a concrete constructor with the public property, based on the parameters of the constructor

Constructor GetConstructors ()

Returns an array of all constructors with the public property

Constructor getdeclaredconstructor (class[] params)

Returns a concrete constructor (without public and non-public attributes) based on the parameters of the constructor

Constructor getdeclaredconstructors ()

Returns all the constructor arrays in the class (without public and non-public properties)

2. Get the Member method of the class

There are four ways to get member methods in the same way that you get a constructor method.

Method GetMethod (String name, class[] params)

Returns a specific method with the public property, based on the method name and arguments

Method[] GetMethods ()

Returns all array of methods with the public property

Method Getdeclaredmethod (String name, class[] params)

Returns a specific method (without public and non-public attributes), based on the method name and parameters

Method[] Getdeclaredmethods ()

Returns an array of all methods in the class (without public and non-public properties)

3. Gets the member variable (member property) of the class

There are four ways to get member properties

Field GetField (String name)

Returns a specific member variable with the public property, based on the variable name

Field[] GetFields ()

Returns an array of member variables with the public property

Field Getdeclaredfield (String name)

Returns a member variable (without public and non-public attributes), based on the variable name

Field[] Getdelcaredfields ()

Returns an array of all member variables (without public and non-public properties)

In-depth understanding of Java: Class loading mechanism and reflection

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.