search
HomeJavajavaTutorialDetailed introduction to Java dynamic class loading and reloading

This article brings you a detailed introduction to Java dynamic class loading and reloading. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Classes can be loaded and reloaded at runtime in Java, although it is not as simple as we think. This article will explain when and how to load and reload classes in Java.
You can argue whether dynamically loading classes is part of Java reflection or part of Java core. Anyway, I put it in Java Reflection for lack of a better place to put it.

Class Loader

All classes in a Java program are loaded using some subclasses of java.lang.ClassLoader. Therefore, dynamically loaded classes must also use a subclass of java.lang.ClassLoader.
When a class is loaded, the classes it references will also be loaded. Class loading mode loads recursively until all required classes are loaded. This may not be all classes for the application. Unreferenced classes are not loaded until they are referenced.

Class loading hierarchy

Class loading in Java is organized into hierarchies. When you create a standalone ClassLoader, you must provide a parent ClassLoader. If a ClassLoader is asked to load a class, it will ask its parent ClassLoader to load it. If the parent class loader cannot find the class, the child class loader will try to load it itself.

Class loading

The steps for the class loader to load a class are as follows:

  1. Check whether the class has been loaded

  2. If the class is not loaded, request the parent class loader to load it

  3. If the parent class loader cannot load the class, try to use the current class loader to load it

When you implement a class loader that can overload classes, you need to deviate a little from this sequence. The parent class loader should not be asked to load the class to be reloaded. More on that later.

Dynamic Class Loading

Dynamic loading of classes is very simple. All you need to do is get a ClassLoader and call its loadClass() method. An example is as follows:

public class MainClass {

  public static void main(String[] args){

    ClassLoader classLoader = MainClass.class.getClassLoader();

    try {
        Class aClass = classLoader.loadClass("com.jenkov.MyClass");
        System.out.println("aClass.getName() = " + aClass.getName());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

}

Dynamic Class Reloading

Dynamic class reloading has some challenges. Java's built-in class loader always checks whether the class has been loaded before loading it. Therefore, it is not possible to reload a class using Java's built-in class loader. To reload a class you must implement your own ClassLoader subclass.
Even with custom subclasses of class loaders, there are challenges. All loaded classes need to be linked. This method is final and therefore cannot be overridden by your ClassLoader subclasses. The resolve() method does not allow a ClassLoader instance to link to a class twice. Therefore, whenever you need to reload a class, you must recreate an instance of the ClassLoader class. It's not impossible, but one has to know when to design the class to reload.

Class overloading code design

As mentioned above, the ClassLoader that loads the specified class cannot be used to reload this class. Therefore, a different ClassLoader must be used to load this class. However, this creates new problems.
Each class loaded in a Java program is identified by its fully qualified name (package name class name) and is loaded by a ClassLoader instance. This means that the class MyObject loaded by class loader A is different from the same class MyObject loaded by class loader B. The simulation code is as follows:

MyObject object = (MyObject)
    myClassReloadingFactory.newInstance("com.jenkov.MyObject");

Note how the class MyObject is referenced in the code as a variable of type object. This causes the MyObject class to be loaded by the class loader that already loaded the resident code for this class.
If the myClassReloadingFactory object factory uses a different class loader than the resident code to load MyObject, you cannot cast the reloaded Object type variable MyObject to the MyObject type. Because the two MyObjects are loaded by different class loaders, they are considered different classes, even though they have the same fully qualified name. Attempting to cast an object's class as a reference to another class will throw a ClassCastException.
It is possible to get around this limitation, but you have to change your code in two ways:

  1. Use interface as variable type, and only reload the implementation class

  2. Use superclass as variable type and only reload subclasses

Here is the sample code:

MyObjectInterface object = (MyObjectInterface)
    myClassReloadingFactory.newInstance("com.jenkov.MyObject");
MyObjectSuperclass object = (MyObjectSuperclass)
    myClassReloadingFactory.newInstance("com.jenkov.MyObject");

If the variable type is Interface or superclass, the above code will run normally, the interface or superclass will not be reloaded when the implementation or subclass is reloaded.
In order for the above code to run normally, you certainly need to implement your own class loader so that the interface or super class is loaded by its parent class. When your class loader is asked to load MyObject, it will also be asked to load the MyObjectInterface interface or MyObjectSuperclass class, because they are referenced internally by the MyObject class. Your class loader must delegate class loading to the same class loader that loaded the interface or superclass.

类加载器加载/重新加载示例

上文包含了很多内容。让我们看一下简单的示例。下面是一个简单的ClassLoader子类。注意它如何将类加载委托给它的父类,除了它想要重装的一个类之外。如果类加载被委派给了它的父类,它以后将不能被重新加载。记住,一个类只能被同一个ClassLoader实例加载。
如前所述,这只是一个示例,它显示了类加载器的行为的基本知识。这并不是一个你的类加载器的生产就绪的模板。你的类加载器可能并不仅限于一个类,可能是一个你想要重新加载的类的集合。此外,你也不能硬编码class path。

public class MyClassLoader extends ClassLoader{

    public MyClassLoader(ClassLoader parent) {
        super(parent);
    }

    public Class loadClass(String name) throws ClassNotFoundException {
        if(!"reflection.MyObject".equals(name))
                return super.loadClass(name);

        try {
            String url = "file:C:/data/projects/tutorials/web/WEB-INF/" +
                            "classes/reflection/MyObject.class";
            URL myUrl = new URL(url);
            URLConnection connection = myUrl.openConnection();
            InputStream input = connection.getInputStream();
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            int data = input.read();

            while(data != -1){
                buffer.write(data);
                data = input.read();
            }

            input.close();

            byte[] classData = buffer.toByteArray();

            return defineClass("reflection.MyObject",
                    classData, 0, classData.length);

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

}

下面是使用MyClassLoader的示例:

public static void main(String[] args) throws
    ClassNotFoundException,
    IllegalAccessException,
    InstantiationException {

    ClassLoader parentClassLoader = MyClassLoader.class.getClassLoader();
    MyClassLoader classLoader = new MyClassLoader(parentClassLoader);
    Class myObjectClass = classLoader.loadClass("reflection.MyObject");

    AnInterface2       object1 =
            (AnInterface2) myObjectClass.newInstance();

    MyObjectSuperClass object2 =
            (MyObjectSuperClass) myObjectClass.newInstance();

    //create new class loader so classes can be reloaded.
    classLoader = new MyClassLoader(parentClassLoader);
    myObjectClass = classLoader.loadClass("reflection.MyObject");

    object1 = (AnInterface2)       myObjectClass.newInstance();
    object2 = (MyObjectSuperClass) myObjectClass.newInstance();

}

reflection.MyObject类是由自定义类加载器加载的。注意,它是如何继承一个超类、实现一个接口的。这只是为了这个例子。在你的代码中,只需要两个中的一个,继承超类或实现接口。

public class MyObject extends MyObjectSuperClass implements AnInterface2{
    //... body of class ... override superclass methods
    //    or implement interface methods
}

The above is the detailed content of Detailed introduction to Java dynamic class loading and reloading. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:segmentfault思否. If there is any infringement, please contact admin@php.cn delete
Why does the browser fail to correctly process the 401 status code when developing a WebSocket server using Netty?Why does the browser fail to correctly process the 401 status code when developing a WebSocket server using Netty?Apr 19, 2025 pm 07:21 PM

在使用Netty开发WebSocket服务器时,可能会遇到浏览器在尝试连接时未能正确处理服务器返回的401状态码的情况。 �...

Java compilation failed: What should I do if the javac command cannot generate the class file?Java compilation failed: What should I do if the javac command cannot generate the class file?Apr 19, 2025 pm 07:18 PM

Java compilation failed: Running window javac command cannot generate class file Many Java beginners will encounter this problem during the learning process: running window...

How to correctly divide business logic and non-business logic in hierarchical architecture in back-end development?How to correctly divide business logic and non-business logic in hierarchical architecture in back-end development?Apr 19, 2025 pm 07:15 PM

Discussing the hierarchical architecture problem in back-end development. In back-end development, common hierarchical architectures include controller, service and dao...

Java compilation error: How do package declaration and access permissions change after moving the class file?Java compilation error: How do package declaration and access permissions change after moving the class file?Apr 19, 2025 pm 07:12 PM

Packages and Directories in Java: The logic behind compiler errors In Java development, you often encounter problems with packages and directories. This article will explore Java in depth...

Is JWT suitable for dynamic permission change scenarios?Is JWT suitable for dynamic permission change scenarios?Apr 19, 2025 pm 07:06 PM

JWT and Session Choice: Tradeoffs under Dynamic Permission Changes Many Beginners on JWT and Session...

How to properly configure apple-app-site-association file in pagoda nginx to avoid 404 errors?How to properly configure apple-app-site-association file in pagoda nginx to avoid 404 errors?Apr 19, 2025 pm 07:03 PM

How to correctly configure apple-app-site-association file in Baota nginx? Recently, the company's iOS department sent an apple-app-site-association file and...

What are the differences in the classification and implementation methods of the two consistency consensus algorithms?What are the differences in the classification and implementation methods of the two consistency consensus algorithms?Apr 19, 2025 pm 07:00 PM

How to understand the classification and implementation methods of two consistency consensus algorithms? At the protocol level, there has been no new members in the selection of consistency algorithms for many years. ...

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.