有一個例子:如何加載不同的類(定義),而不是要求一個,保持相同的名稱
package bar;
public class Bar {
public void doSomething() {
System.out.println("Bar: " + getClass().getName());
}
}
package baz;
public class Baz {
public void doSomething() { // note the same signature
System.out.println("Baz: " + getClass().getName());
}
}
package foo;
public class Foo {
public static void main(String[] args) throws ClassNotFoundException {
Class.forName("bar.Bar", false, new MimicClassLoader(
Thread.currentThread().getContextClassLoader()));
// must print "Baz: bar.Bar"
new bar.Bar().doSomething();
}
}
package foo;
public class MimicClassLoader extends ClassLoader {
public MimicClassLoader(ClassLoader parent) {
super(parent);
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if ("bar.Bar".equals(name)) {
name = "baz.Baz";
}
return super.loadClass(name);
}
}
我嘗試了上面的代碼,但它並沒有爲我工作。拋出異常:
線程「main」中的異常java.lang.ClassNotFoundException:bar/Bar
類定義是否包含類的名稱?在裝載過程中是否有任何方法可以改變它?
UPDATE
我已經找到一種方法來修改類名稱中使用了Javassist庫:
public class MimicClassLoader extends ClassLoader {
public MimicClassLoader(ClassLoader parent) {
super(parent);
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if ("bar.Bar".equals(name)) {
byte[] bytes;
try {
bytes = javassist.ClassPool.getDefault()
.getAndRename("baz.Baz", "bar.Bar").toBytecode();
} catch (Exception e) {
throw new RuntimeException(e);
}
Class<?> clazz = defineClass(name, bytes, 0, bytes.length);
// prints "Baz: bar.Bar"
// clazz.getMethod("doSomething").invoke(clazz.newInstance());
return clazz;
}
return getParent().loadClass(name);
}
}
但使用new Bar().doSomething()
它仍然打印 「欄:bar.Bar」 的時候。
我想我已經錯過了一些代碼,所以存在兩個具有相同名稱的類(原始的和baz.Baz的重命名副本)。
嘗試刪除程序包名稱。而不是bar.Bar,只是Bar而不是baz.Baz,就是Baz。讓我知道它是否有效。你還確定Bar/Baz是classpath的一部分嗎? –