Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the loading, linking, and initialization of a class

2025-02-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article introduces the relevant knowledge of "what is the loading, linking and initialization of classes". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

Loading of Java class

Loading the Java class is done by the class loader.

Generally speaking, classloaders are divided into two categories: startup classloader (bootstrap) and user-defined classloader (user-defined).

The difference between the two is that the startup classloader is implemented by JVM's native code, while user-defined classloaders inherit from the java.lang.ClassLoader class in Java. In the user-defined classloader section, JVM generally provides some basic implementations. Application developers can also write their own class loaders as needed. The most commonly used in JVM is the system class loader (system), which is used to start loading Java applications. The loader object of this class can be obtained through the getSystemClassLoader () method of java.lang.ClassLoader.

The final function of the class loader is to define a Java class, which converts the Java byte code into an object of the java.lang.Class class in JVM. But the process of class loading is not that simple.

The Java classloader has two important features: hierarchical organization and proxy mode.

Hierarchical organization means that each class loader has a parent class loader, which can be obtained through the getParent () method. Classloaders are organized in this parent-descendant way to form a tree hierarchy. Proxy mode means that a class loader can not only complete the definition of Java classes by itself, but also act as agents to other class loaders. Because of the proxy pattern, the class loader that starts the loading process of a class may not be the same as the class loader that ultimately defines the class. The former is called the initial class loader, while the latter is called the definition class loader.

The relationship between the two is that the definition class loader of a Java class is the initial class loader of other Java classes imported by this class. For example, if class An imports class B through import, then the defined class loader of class An is responsible for starting the loading process of class B. A normal classloader proxies its parent class loader before trying to load a Java class itself. When the parent class loader cannot be found, it will try to load it itself. This logic is encapsulated in the loadClass () method of the java.lang.ClassLoader class. In general, the parent-first strategy is good enough. In some cases, you may need to take the opposite strategy, that is, try to load yourself first, and then proxy to the parent class loader when you can't find it. This practice is common in Java's Web containers and is recommended by the Servlet specification. For example, Apache Tomcat provides a separate class loader for each Web application, using its own priority loading strategy. IBM WebSphere Application Server allows Web applications to choose.

Policies used by class loaders

An important use of classloaders is to create isolated spaces in JVM for Java classes with the same name. In JVM, determining whether two classes are the same is not only based on the binary name of the class, but also on the definition of the class loader of the two classes. Two classes are considered to be the same only if they are exactly the same. Therefore, even if the same Java bytecode is defined by two different class loaders, the resulting Java class is different. If you try to assign a value between objects of two classes, a java.lang.ClassCastException is thrown. This feature creates conditions for Java classes of the same name to coexist in JVM. In practical applications, different versions of Java classes with the same name may be required to exist at the same time in JVM. This requirement can be met through a class loader. This technology has been widely used in OSGi.

Links to the Java class

The link to the Java class refers to the process of merging the binaries of the Java class into the running state of the JVM. This class must be successfully loaded before linking. The link to the class includes several steps such as validation, preparation, and parsing. Validation is used to ensure that the binary representation of the Java class is structurally correct. If there is an error in the validation process, a java.lang.VerifyError error is thrown.

The preparation process is to create static fields in the Java class and set the values of those fields to default values. The preparation process does not execute the code. A Java class contains formal references to other classes or interfaces, including its parent class, the interface implemented, the formal parameters of the method, and the Java class that returns the value. The parsing process is to ensure that these referenced classes are found correctly. The parsing process may cause other Java classes to be loaded. Different JVM implementations may choose different parsing strategies.

One way to do this is to recursively parse all dependent formal references when linking. Another approach might be to resolve a formal reference only when it is really needed. That is, if a Java class is only referenced but not actually used, then the class may not be parsed. Consider the following code:

Public class LinkTest {public static void main (String [] args) {ToBeLinked toBeLinked = null; System.out.println ("Test link.");}}

The class LinkTest refers to the class ToBeLinked, but doesn't actually use it, just declares a variable, and does not create an instance of the class or access the static domain in it.

In JDK 6 of Oracle, if you delete the Java bytecode of the compiled ToBeLinked and then run LinkTest, the program will not throw an error. This is because the ToBeLinked class is not really used, and the linking strategy adopted by Oracle's JDK 6 prevents the ToBeLinked class from being loaded, so you won't find that ToBeLinked's Java bytecode actually doesn't exist. If you change the code to ToBeLinked toBeLinked = new ToBeLinked (); and then run it the same way, an exception will be thrown. Because the ToBeLinked class is really used at this time, you will need to load this class.

Initialization of the Java class

When a Java class is actually used for the first time, JVM initializes the class. The main operation of the initialization process is to execute the static code block and initialize the static domain. Before a class can be initialized, its immediate parent class also needs to be initialized. However, the initialization of an interface does not cause initialization of its parent interface. During initialization, static code blocks and initialized static fields are executed in the order from top to bottom in the source code. Consider the following code:

Public class StaticTest {public static int X = 10; public static void main (String [] args) {System.out.println (Y); / / output 60} static {X = 30;} public static int Y = X * 2;}

In the above code, during initialization, the initialization of the static domain and the execution of the static code block are executed from top to bottom. So the value of variable X is initialized to 10 and then assigned to 30, while the value of variable Y is initialized to 60.

Timing of initialization of Java classes and interfaces

Initialization of Java classes and interfaces occurs only at specific times, including:

Create an instance of the Java class. Such as

MyClass obj = new MyClass ()

Call a static method in a Java class. Such as

MyClass.sayHello ()

Assign a value to a static field declared in a Java class or interface. Such as

MyClass.value = 10

Accesses a static domain declared in a Java class or interface, and the field is not a constant variable. Such as

Int value = MyClass.value

Execute the assert statement in the top-level Java class.

Assert true

Reflecting API through Java may also result in initialization of classes and interfaces. It is important to note that when accessing a static domain in a Java class or interface, only the class or interface that actually declares the domain is initialized. As shown in the following code.

Package io.mykit.binghe.test; class B {static int value = 100; static {System.out.println ("Class B is initialized."); / / output}} class An extends B {static {System.out.println ("Class An is initialized."); / / No output}} public class InitTest {public static void main (String [] args) {System.out.println (A.value); / / output 100}}

In the above code, the class InitTest references the static domain value declared in class B through A.value. Because value is declared in class B, only class B will be initialized, while class A will not be initialized.

Create your own class loader

During the Java application development process, you may need to create your own class loader for the application. Typical scenarios include the implementation of specific Java bytecode lookups, the encryption / decryption of bytecode, and the isolation of Java classes with the same name. Creating your own class loader is not a complex task; you just need to inherit from the java.lang.ClassLoader class and override the corresponding methods. There are many methods available in java.lang.ClassLoader. Here are a few things to consider when creating a classloader:

DefineClass (): this method is used to complete the conversion from a byte array of Java bytecode to java.lang.Class. This method cannot be overridden and is generally implemented in native code.

FindLoadedClass (): this method is used to find the loaded Java class by name. A class loader does not repeatedly load a class with the same name.

FindClass (): this method is used to find and load the Java class by name.

LoadClass (): this method is used to load the Java class by name.

ResolveClass (): this method is used to link a Java class.

What is easy to confuse here is the role of the findClass () method and the loadClass () method. As mentioned earlier, during the linking process of the Java class, the Java class needs to be parsed, and parsing may cause other Java classes referenced by the current Java class to be loaded. At this point, JVM loads other classes by calling the current class's loadClass () method that defines the classloader. The findClass () method is the extension point of the class loader created by the application. Applying your own classloader should override the findClass () method to add custom classloading logic. The default implementation of the loadClass () method is responsible for calling the findClass () method. As mentioned earlier, the proxy mode of the classloader defaults to the parent class first policy. The implementation of this strategy is encapsulated in the loadClass () method. If you want to modify this policy, you need to override the loadClass () method.

The following code shows a common implementation pattern for custom class loading

Public class MyClassLoader extends ClassLoader {protected Class findClass (String name) throws ClassNotFoundException {byte [] b = null; / / find or generate the bytecode return defineClass (name, b, 0, b.length) of the Java class;}} "what is the loading, linking, and initialization of the class"? thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report