在类加载器中投掷?

我该如何做到这一点:

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. 通过作为调用代码和创build的类加载器的父类的类加载器加载类(或单独的接口)
  2. 序列化和反序列化对象。

不可能。 类标识由完全限定的名称和类加载器组成。

将一个对象转换成不同类加载器加载的同名类与将StringInteger没有区别,因为尽pipe名称相同,但这些类实际上可能完全不同。

我刚刚花了最后两天挣扎在这个确切的问题,我终于通过使用Javareflection来解决问题:

 // '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[] {}); } 

希望这有助于某人。

也许使用接口和java.lang.reflect.Proxy会适合你的喜好。 使用一个InvocationHandler来查找和调用目标类上的相关方法。 (请注意,如果您这样做,您所拥有的任何移动代码安全性将会被击穿。)

如果需要投射的类实现Serializable,那么:

 private <T> T castObj(Object o) throws IOException, ClassNotFoundException { if (o != null) { ByteArrayOutputStream baous = new ByteArrayOutputStream(); { ObjectOutputStream oos = new ObjectOutputStream(baous); try { oos.writeObject(o); } finally { try { oos.close(); } catch (Exception e) { } } } byte[] bb = baous.toByteArray(); if (bb != null && bb.length > 0) { ByteArrayInputStream bais = new ByteArrayInputStream(bb); ObjectInputStream ois = new ObjectInputStream(bais); T res = (T) ois.readObject(); return res; } } return null; } 

用法:

 Object o1; // MyObj from different class loader MyObj o2 = castObj(o1); 

没有可能投在不同的类加载器。

你有Gson这个解决方法 ,例如铸造对象YourObject(对象是一个YourObject类,但在其他classLoader):

 Object o = ... Gson gson = new Gson(); YourObject yo = gson.fromJson(gson.toJson(o), YourObject.class); 

我使用这个解决方法,因为我在WebApp(在Tomcat上)编译任何Java代码。 此解决方法在生产中运行。

这是我到达的一个旧post,因为我想做几乎相同的事情,但它的一个更简单的版本…

它实际上工作,如果Foo和加载类(在我的情况下从另一个包中的.java类文件)扩展相同的类,例如AbstractTestClass。

代码片段:

 public AbstractTestClass load(String toLoad) { try{ Class test = Class.forName("testsFolder.testLoadable"); Constructor ctorlist[] = test.getDeclaredConstructors(); for(Constructor aConstructor : ctorlist){ if(...){// find the good constructor Object loadedTest = aConstructor.newInstance(new Object[]{/*params*/}); return (AbstractTestClass) test; } } }catch(...){} return new defaultTestClass(); } 

这样我可以将加载的类插入一个ArrayList<AbstractTestClass>