Java class loader and java class loading

Source: Internet
Author: User

Java class loader and java class loading
Classloader description

The class Loader loads the. Class file into the memory and generates a java. lang. class instance for the Class.

Once a class is added to the JVM, the same class will not be added again. In JVM, the unique identifier of a class is: class name, class package name, and class loader.

When JVM is started, an initial class loader hierarchy consisting of three class loaders is formed:

  • BootStrap ClassLoader: Root loader;
  • Extension ClassLoader: Extension class loader;
  • System ClassLoader: System class loader.

Root loader,Load the java core class (that is, the jar package under JAVA_HOME/jre/lib ). When you use the-Xbootclasspath option or the-D option to specify the system attribute of sun. boot. class. path, you can also specify the attached class to be loaded. The root loader is special. It is not a subclass of java. lang. ClassLoader, but implemented by JVM itself.

Extended class loader,Load the jar package under the extension directory of JRE (JAVA_HOME/jre/lib/ext directory.

System class loader,Load the-classpath option or java from the java command during JVM startup. class. path System attribute, or the jar package and class path specified by the CLASSPATH environment variable, or the current class path. The program can obtain the system class loader through the static method getSystemClassLoader () of ClassLoader.

In addition to the three types of loaders provided by Java, developers can also implement their own class loaders. Custom class loaders are implemented by inheriting ClassLoader.

Hierarchy of the four types of loaders in JVM

: The root class loader is the parent class loader of the extension class loader, And the extension class loader is the parent class loader of the system class loader. If not specified, all user-defined class loaders use the system class loaders as parent loaders.

You need to mention that the parent-child relationship between classloaders is not the parent-child relationship of class inheritance, but the relationship between classloaders instances.

Class Loading Mechanism

The JVM class loading mechanism mainly includes the following three mechanisms:

  • Overall responsibility: the overall responsibility mechanism means that when a class loader is responsible for loading a class, the class loader will also be responsible for loading the classes dependent on and referenced by the class loader, unless it is explicitly loaded using another class loader;
  • Parent class delegation: the parent class delegation mechanism means that when a class loader is responsible for loading a class, the parent class loader first tries to load the class. If the class cannot be loaded, to load data from your own class path;
  • Cache Mechanism: The cache mechanism ensures that all loaded classes are cached. When a class loader is responsible for loading a class, it first searches for the class from the cache. Only when the class object does not exist in the cache will the class be loaded and stored in the cache. This is also the reason why we need to restart JVM after modifying a class to make the adjustment take effect.

The Class Loader generally takes eight steps to load the class:

Custom Class Loader

In JVM, all the class loaders except the root class loaders are instances of ClassLoader subclasses. Developers can inherit the ClassLoader and override the ClassLoader method to implement a custom class loader.

The ClassLoader class has three key methods:

  • LoadClass (String name, boolean resolve): This method is the entry point of ClassLoader. Classes are loaded Based on the specified binary name;
  • FindClass (String name): searches for classes based on the specified binary name;
  • DefineClass (String name, byte [] B, int off, int len): returns the bytecode file of the specified class (that is. class file) read the byte array byte [] B and convert it into a Class object. The bytecode file can be from the network or disk.

To implement a custom ClassLoader, You can override loadClass or findClass. However, it is generally recommended to rewrite findClass instead of loadClass. Let's take a look at the loadClass execution steps:

  • Use findLoadClass to check whether the class has been loaded. If the class has been loaded, return directly;
  • Call the loadClass method on the parent class loader. If the parent loader is null, the root loader is used for loading;
  • Call the findClass method to find the class.

From the above view, using the override findClass method can avoid overwriting the parent class delegate and cache mechanisms of the default class loader.

The following is an instance of a custom Class Loader:

Package com. zhyea. test; import java. io. file; import java. io. fileInputStream; import java. io. IOException; import java. io. inputStream; import java. lang. reflect. method; /*** custom class Loader instance * @ author robin **/public class MyClassLoader extends ClassLoader {/*** read class file ** @ param filePath * class file path * @ return * @ throws IOException */private byte [] getBytes (String filePath) throws IOException {InputStream in = nu Ll; try {File file = new File (filePath); long length = file. length (); in = new FileInputStream (file); byte [] buffer = new byte [(int) length]; int hasRead = in. read (buffer); if (hasRead! = Length) {throw new IOException ("all files cannot be read:" + hasRead + "! = "+ Length);} return buffer;} finally {if (null! = In) in. close ();}} /*** compile the Java file ** @ param javaFile * Java file * @ return * @ throws IOException * @ throws InterruptedException */private boolean compile (String javaFile) throws IOException, interruptedException {// call the system javac command Process p = runtime.getruntime(cmd.exe c ("javac" + javaFile); // force other threads to wait for this thread to finish p. waitFor (); // get the exit value of the javac thread int rtn = p. exitValue (); // returns whether the compilation is successful. return rtn = 0 ;}/*** Override the findClass Class of ClassLoader */@ Override protected Class <?> FindClass (String name) throws ClassNotFoundException {Class <?> Clazz = null; String javaPath = name. replace (". ","/"); String javaFileName = javaPath + ". java "; String classFileName = javaPath = ". class "; File javaFile = new File (javaFileName); File classFile = new File (classFileName); if (javaFile. exists ()&&(! ClassFile. exists () | javaFile. lastModified ()> classFile. lastModified () {try {if (! Compile (javaFileName) |! ClassFile. exists () {throw new ClassNotFoundException ("Class not found:" + javaFileName) ;}} catch (Exception e) {e. printStackTrace () ;}} if (classFile. exists () {try {byte [] raw = getBytes (classFileName); clazz = defineClass (name, raw, 0, raw. length);} catch (Exception e) {e. printStackTrace () ;}}if (null = clazz) {throw new ClassNotFoundException (name);} return clazz;} public static void main (St Ring [] args) throws Exception {String javaName = "com. zhyea. test. MyTest"; MyClassLoader mcl = new MyClassLoader (); Class <?> Clazz = mcl. loadClass (javaName); Method main = clazz. getMethod ("main", (new String [0]). getClass (); Object [] arrs = {args}; main. invoke (null, arrs );}}

Attached with the demo test class, it is actually very simple:

Package com. zhyea. test;/*** test class used by the user-defined class loader demonstration * @ author robin **/public class MyTest {public static void main (String [] args) {System. out. println ("This is a Test! ");}}

You can use the custom class loader to implement the following functions:

  • The digital signature is automatically verified before the code is executed;
  • Decrypts the code based on the password provided by the user, so that the Code obfuscators can be implemented to avoid decompilation of class files;
  • Dynamically load classes as needed;
  • Load other data to the application in the form of bytecode as needed.
URLClassLoader class

URLClassLoader is the parent class of the extended Class Loader class and the system class loader class. URLClassLoader has powerful functions. You can obtain java files locally to load classes, or obtain remote files to load classes.

Demo:

Package com. zhyea. test; import java.net. URL; import java.net. URLClassLoader; public class UCLTest {public static void main (String [] args) throws Exception {URL [] urls = {new URL ("file: com. zhyea. test. myTest. java ")}; URLClassLoader ucl = new URLClassLoader (urls); MyTest mt = (MyTest) ucl. loadClass ("com. zhyea. test. myTest "). newInstance (); mt. test (); ucl. close () ;}} package com. zhyea. test;/*** URLClassLo The test class * @ author robin **/public class MyTest {public void Test () {System. out. println ("This is a test 2! ");}}

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.