What is a Java ClassLoader?
@reference_2_oracle
Understanding Network Class Loaders
@reference_3_docs.oracle
Class ClassLoader
The bootstrap class loader loads the core Java libraries located in the
<JAVA_HOME>/jre/lib
directory. This class loader, which is part of the core JVM, is written in native code.The extensions class loader loads the code in the extensions directories (
<JAVA_HOME>/jre/lib/ext
, or any other directory specified by the java.ext.dirs
system property). It is implemented by the sun.misc.Launcher$ExtClassLoader
class.The system class loader loads code found on
java.class.path
, which maps to the CLASSPATH
environment variable. This is implemented by the sun.misc.Launcher$AppClassLoader
class.@reference_4_wikipedia
Every class loaded in a Java application is identified by its fully qualified name (package name + class name), and the ClassLoader instance that loaded it. That means, that a class MyObject loaded by class loader A, is not the same class as the MyObject class loaded with class loader B.
MyObject object = (MyObject) myClassReloadingFactory.newInstance("com.jenkov.MyObject");
Notice how the
MyObject
class is referenced in the code, as the type
of the object
variable. This causes the MyObject
class
to be loaded by the same class loader that loaded the class this code is residing in.
If the
myClassReloadingFactory
object factory reloads the MyObject
class using a different class loader than the class the above code resides in, you cannot
cast the instance of the reloaded MyObject
class to the MyObject
type of the object
variable. Since the two MyObject
classes were
loaded with different class loaders, the are regarded as different classes, even if they
have the same fully qualified class name. Trying to cast an object of the one class to a
reference of the other will result in a ClassCastException
.
It is possible to work around this limitation but you will have to change your code in either of two ways:
- Use an interface as the variable type, and just reload the implementing class.
- Use a superclass as the variable type, and just reload a subclass.
MyObjectInterface object = (MyObjectInterface) myClassReloadingFactory.newInstance("com.jenkov.MyObject");
MyObjectSuperclass object = (MyObjectSuperclass) myClassReloadingFactory.newInstance("com.jenkov.MyObject");
@reference_5_tutorials.jenkov.com
Java Reflection - Dynamic Class Loading and Reloading
No comments:
Post a Comment