You delegate to the same class loader. So you will see no difference.
What should yo do? Implement class loading in your class loader, don't just delegate. For instance, inherit your class loader from URLClassLoader, initialize it properly (it means, provide a valid class path to your class loader to initialize it). Then you will see, that classes loaded by you class loader are not euqal to the classes loaded by the standard class loader, and as a consequence, their static members will be different.
Often the context class loader is inherited from URLClassLoader and thus you don't have to spend much time configuring class path for it. Instead, to initialize you class loader you can just reuse the URLs of the context class loader, as follows:
public class MyIndependentClassLoader extends URLClassLoader {
public MyIndependentClassLoader(){
super(((URLClassLoader) Thread.currentThread().getContextClassLoader()).getURLs());
}
}
Now you can use your class loader and check static members.
What is the difference between this approach and the original approach?
You know that classes are also objects (of special type): they have their own member variables, name, serialVersionUID, annotationData,
etc., and their own methods, newInstance(), getFields(), getMethods(),
etc. When you call
Class c = loader.loadClass("com.my.package.MyClassX");
you get c
, this is an object that describes the loaded class "some class name". This c
not only allows to create instances, but holds also all static members.
In your code: Your class loader does not load class directly. Instead, it delegates to the context class loader. That's why if you compare two loaded classes
Class c = loader.loadClass("com.my.package.MyClassX");
Class ct = Thread.currentThread().getContextClassLoader().loadClass("com.my.package.MyClassX");
you will see, that c
and ct
is the same object. If you call c.equals(ct)
, it will give you true
. And if you call c == ct
, it will also give you true
. It means, this is the same
class instance. That's why - naturally - if you check static variables, they will be the same. If you change static variable in one class, it will also be changed in another class, and vice versa.
In my code: The essential difference is, that the class loader loads classes itself. It does not delegate it to other class loader. I suggested to extend it from URLClassLoader
to simplify our implementation (otherwise you would have implement from scratch dealing with class path, directories, jars, visibility, caching, etc.). And to avoid adding each class path element step by step I suggested to use the same class path (the same list of directories, jars, etc.) as the context class loader. So our class loader will be able to find the same classes as the context class loader.
Now check the class that this class loader loads. Let's call it ci
:
Class ci = new MyIndependentClassLoader().loadClass("com.my.package.MyClassX");
If you compare these classes, you will see that c.equals(ci)
gives false
. Means, they are different. That's why they have also independent static members. If you change static member in one class, ct
, it will not change in the other, ci
, and vice versa.