我正计划使用自定义类加载器进行类的热部署。对于此任务,我编写了自定义类加载器。看起来像
public class CustomClassLoader extends ClassLoader{
public CustomClassLoader(ClassLoader parent) {
super(parent);
}
public Class loadClass(String name) throws ClassNotFoundException {
if(!"classLoader.TestCase".equals(name))
return super.loadClass(name);
try {
String url = null;
String clzName = null;
url = "file:/home/naveen/workspace/JavaConcept/bin/classLoader/TestCase.class";
clzName = "classLoader.TestCase";
}
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(clzName,classData, 0, classData.length);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
现在我有另一个名为TestCase的类,它有一个名为print()的方法。
public void print(){
System.out.println("Hello");
System.out.println("Bye");
}
我正在使用类似这样的主要方法调用它
public static void main(String arg[]) throws InstantiationException, IllegalAccessException{
TestCase t = new TestCase();
t.print();
try {
ClassLoader classLoader = CustomClassLoader.class.getClassLoader();
classLoader = new CustomClassLoader(classLoader);
Class clz = classLoader.loadClass("classLoader.TestCase");
TestCase t2 = new TestCase();
t2.print();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
现在我想在一个主要的t.print()方法中做一件事,它在控制台上打印hello和bye。现在我有一个这个Testcase类的打印方法的另一个版本,它只打印Hello。所以我做了什么,我在调试模式下声明了程序,让程序继续,直到classLoader.loadClass()行。然后我用目录结构替换了Testcase.class,新版本只打印hello.But仍显示输出Hello和Bye。 有人可以帮我解决这个程序有什么问题,或者我对类加载器的理解不正确。请纠正我并帮助完成我的任务。
答案 0 :(得分:0)
自定义类加载器很难实现,因为您需要记住许多规则。在你的情况下,我想问题是你的类文件是程序的一部分,这意味着如果你尝试加载一个类,默认的类加载器将在调用永远不会被调用的loadClass()方法之前加载它。尝试从类路径中删除类文件,使其不属于您的程序,然后调用loadClass()。
第二个问题是你正在使用new创建你的TestCase对象,它将调用默认的类加载器,更好的方法是调用classLoader.loadClass()然后从返回的类创建一个实例,但是如果你强制转换到TestCase,这意味着在默认的类加载器中定义了类,这导致了第一个问题。另一种方法是创建一个接口并强制转换为该接口,以便调用您的方法。