有一个例子:
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);
}
}
我尝试了上面的代码,但它对我不起作用。抛出异常:
线程&#34; main&#34;中的例外情况java.lang.ClassNotFoundException:bar / Bar
类定义是否包含类的名称?在加载过程中有没有办法改变它?
更新
我找到了一种使用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()
时,它仍会打印&#34; Bar:bar.Bar&#34;。
我想我已经错过了一些代码,因此存在两个具有相同名称的类(原始类和重命名的baz.Baz副本)。
答案 0 :(得分:0)
根据我的理解,您不能像在这种情况下那样更改类名。 Class.forName()从您请求的那个验证您加载的类并失败。您可以使用您定义的类加载器直接加载您的类。