跨类加载器进行转换?

2022-09-01 11:39:57

我该怎么做:

class Foo {
  public static Foo get() throws Exception {
    ClassLoader cl = new URLClassLoader(new URL[]{"foo.jar"}, null); // Foo.class is in foo.jar
    return (Foo)cl.loadClass("Foo").newInstance(); // fails on class cast
  }
}

我需要的是让 JVM 将 cl 中的 Foo 实例视为来自执行代码的类加载器的 Foo 实例。

我见过这些方法,它们都不适合我(上面的例子是一个玩具的例子):

  1. 由类装入器装入类(或单独的接口),该类装入器是调用代码和创建的类装入器的父级
  2. 序列化和反序列化对象。

答案 1

不可能。类标识由完全限定名和类装入器组成。

将一个对象强制转换为由不同类装入器加载的具有相同名称的类与尝试将 a 强制转换为 没有什么不同,因为尽管这些类具有相同的名称,但实际上可能是完全不同的。StringInteger


答案 2

在过去的两天里,我只是在努力解决这个问题,我终于通过使用java反射解决了这个问题:

// 'source' is from another classloader
final Object source = events[0].getSource();

if (source.getClass().getName().equals("org.eclipse.wst.jsdt.debug.internal.core.model.JavaScriptThread")) {

    // I cannot cast to 'org.eclipse.wst.jsdt.debug.internal.core.model.JavaScriptThread'
    // so I invoke the method 'terminate()' manually
    Method method = source.getClass().getMethod("terminate", new Class[] {});
    method.invoke(source, new Object[] {});
}

希望这有助于某人。


推荐