Unloading and Reloading classes

2008-02-23 09:45:32来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

轉Java.sun.com

The July 22, 2003 Tech Tip titled "Compiling Source Directly From a Program" offered a way to compile source files directly from your Java program. It presented a simple editor in which you can name a class and provide the source. That approach works fine, provided the class is not one that you already compiled and loaded during the current execution run. If indeed you previously compiled and loaded the class, you can't then edit it and recompile it using the approach covered in the previous Tech Tip. The issue here is the underlying class loader. All classes loaded through the system class loader will never be unloaded. To allow the program to let you reedit the source for a class, and then recompile and reload it, you need to work with a different class loader. In this tip, you'll learn how to create a custom class loader, one that lets you load your newly compiled class (or any class). You'll also learn how to discard the class such that the next time you compile the class, the newly compiled class is loaded.

An instance of the ClassLoader class of the java.lang package is responsible for loading all classes. For system classes, that class loader is available through the getSystemClassLoader method of ClassLoader. For user classes, if that class is already loaded, you can ask for the ClassLoader with the getClassLoader method of Class.

In the RunIt program from the earlier Tech Tip, the forName method of Class was used to load the class data (that is, to get an instance of Class). If you want to use a different class loader, you have to use the loadClass method of ClassLoader to load the class data. In other words, you need to code this:

String className = ...;
Class aClass = loader.loadClass(className);

instead of this:

String className = ...;
Class aClass = Class.forName(className);

Functionally, the two code blocks above are identical when loading through the same class loader. The first block loads the class through the same loader as where the code is found. The second loads the class through the class loader specified by the loader variable. In both cases, you would then call something like newInstance to create an instance of the class.

Repeated calls to Class.forName load the same class (assuming the class loader of the calling class doesn't change). Repeated calls to loader.loadClass load the same class. However, the second block allows you to reload a class. To do that, you create a new ClassLoader:

String className = ...;
// create new loader instance
ClassLoader loader = ...;
Class aClass = loader.loadClass(className);

In this particular code block, a new loader is created between calls to loadClass. If the class definition for className changes between calls, the new version of the class is loaded the second time through.

If you change the RunIt program to use this mechanism, you can edit the source after compiling and running the program. The program should generate output appropriate to the new source, not the old.

The only thing left is where to get the ClassLoader. The ClassLoader class is itself an abstract class. Predefined loaders include the SecureClassLoader of java.security, which adds permission support, and the URLClassLoader of java.net. Of the two predefined loaders, only URLClassLoader offers support for public construction through either its constructors or static newInstance methods. See the documentation for URLClassLoader for further details.

Creating a URLClassLoader involves creating an array of URL objects. These URL objects serve as the locations that the custom class loader uses to find classes. You specify the elements of the array similarly to the way you specify path elements for the CLASSPATH environment variable, where the path elements are separated by a ; on Windows and a : on Unix machines. Each element in the URL array can be a located locally or on a remote host. Anything ending in a "/" is presumed to be a directory. Anything else is presumed to be a JAR file.

For instance, if you want to create a ClassLoader that works like the default classpath, that is, only searching in the current directory, you can code the following:

File file = new File(".");
ClassLoader loader = new URLClassLoader(
new URL[] {file.toURL()}
);

The first line creates a File object, referencing the current directory. The second line calls the URLClassLoader constructor. Passed into the constructor is an array of one URL object: the URL to the File.

If you change the RunIt program to include the following code, recompile it, and run it, the program will discard the loaded classes between runs and reload them. Notice that unlike the RunIt program in the earlier Tech Tip, the following code does not create an instance of the class to invoke the main method. There is no need to create an instance of the class because the main method is static,

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Java异常处理--尽量不要从try区段中返回(return)

下一篇:Java模式--工厂模式的简单用例