Multiple instances of static variables

前端 未结 4 1306
自闭症患者
自闭症患者 2021-02-13 14:42

I\'m experimenting with using different classloaders to load a particular class, and see if the static variables in that class can have different instances.

Basically,

相关标签:
4条回答
  • 2021-02-13 15:38

    If you look at the ClassLoader source or even javadocs you'll find out that by default the ClassLoader delegates to the default system ClassLoader, which in fact is shared among the instances.

    0 讨论(0)
  • 2021-02-13 15:39

    I had the same problem (integration tests) and tried it with @Michael Borgwardt approach. Here some example code:

    URLClassLoader classLoader1 = new URLClassLoader(new URL[]{new URL("file:///path/to/jar/my-classes.jar")}, null);
    URLClassLoader classLoader2 = new URLClassLoader(new URL[]{new URL("file:///path/to/jar/my-classes.jar")}, null);
    
    // Load with classLoader1
    Class<?> myClass1 = classLoader1.loadClass("MyClass");
    Constructor<?> constructor1 = myClass1.getConstructor();
    Object instance1 = constructor1.newInstance();
    
    // Load with classLoader2
    Class<?> myClass2 = classLoader2.loadClass("MyClass");
    Constructor<?> constructor2 = myClass2.getConstructor();
    Object instance2 = constructor2.newInstance();
    
    // Load with system classloader
    MyClass myClass = new MyClass();
    
    // ...
    
    0 讨论(0)
  • 2021-02-13 15:44

    It looks as though the class "A" is being loaded by the parent class loader, rather than your CustomClassLoader (because you call super.loadClass).

    The following untested amendment should allow you to define the "A" class using your own class loader (while delegating everything else to the parent loader).

    Apologies for the horrible bodge where I assume the single inputStream.read() will read everything! But you can hopefully see what I mean.

        public Class loadClass(String classname)  throws ClassNotFoundException {
        if (classname.equals("A")) {
            InputStream is = getResourceAsStream("A.class");
            byte[] bodge = new byte[8192];  // Should read until EOF
            try {
                int len = is.read(bodge);
                return defineClass("A", bodge, 0, len);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        return super.loadClass(classname, true);
    }
    

    You'll probably then end up with ClasscastExceptions or something similar...

    0 讨论(0)
  • 2021-02-13 15:48

    Your problem is that new CustomClassLoader() creates a classloader that will try to delegate loading classes to the system classloader - and that will be the same for both instances. Your CustomClassLoader also isn't even able to load classes itself. Try using an URLClassLoader and passing null as parent.

    As for real world applications: it's essential for Java Web containers and app servers by allowing different apps to be completely isolated from each other even though they may be using many of the same classes.

    0 讨论(0)
提交回复
热议问题