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
How do I use Maven or Gradle for advanced Java project management, build automation, and dependency resolution?How do I use Maven or Gradle for advanced Java project management, build automation, and dependency resolution?Mar 17, 2025 pm 05:46 PM

The article discusses using Maven and Gradle for Java project management, build automation, and dependency resolution, comparing their approaches and optimization strategies.

How do I create and use custom Java libraries (JAR files) with proper versioning and dependency management?How do I create and use custom Java libraries (JAR files) with proper versioning and dependency management?Mar 17, 2025 pm 05:45 PM

The article discusses creating and using custom Java libraries (JAR files) with proper versioning and dependency management, using tools like Maven and Gradle.

How do I implement multi-level caching in Java applications using libraries like Caffeine or Guava Cache?How do I implement multi-level caching in Java applications using libraries like Caffeine or Guava Cache?Mar 17, 2025 pm 05:44 PM

The article discusses implementing multi-level caching in Java using Caffeine and Guava Cache to enhance application performance. It covers setup, integration, and performance benefits, along with configuration and eviction policy management best pra

How can I use JPA (Java Persistence API) for object-relational mapping with advanced features like caching and lazy loading?How can I use JPA (Java Persistence API) for object-relational mapping with advanced features like caching and lazy loading?Mar 17, 2025 pm 05:43 PM

The article discusses using JPA for object-relational mapping with advanced features like caching and lazy loading. It covers setup, entity mapping, and best practices for optimizing performance while highlighting potential pitfalls.[159 characters]

How does Java's classloading mechanism work, including different classloaders and their delegation models?How does Java's classloading mechanism work, including different classloaders and their delegation models?Mar 17, 2025 pm 05:35 PM

Java's classloading involves loading, linking, and initializing classes using a hierarchical system with Bootstrap, Extension, and Application classloaders. The parent delegation model ensures core classes are loaded first, affecting custom class loa

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

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat Commands and How to Use Them
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.