我有一个班级
class Foo {
int increment(int x) {
return x + 1;
}
}
我想在运行时获取此类的副本,例如: G。像
这样的课程class Foo$Copy1 {
int increment(int x) {
return x + 1;
}
}
其中包含所有相同的方法,但名称不同。
Proxy
似乎有助于委派,但无法复制方法。
答案 0 :(得分:8)
您可以使用Byte Buddy:
Class<?> type = new ByteBuddy()
.redefine(Foo.class)
.name("Foo$Copy1")
.make()
.load(Foo.class.getClassLoader())
.getLoaded();
Method method = type.getDeclaredMethod("increment", int.class);
int result = (Integer) method.invoke(type.newInstance(), 1);
请注意,此方法重新定义了Foo
中类的任何用途,例如如果方法返回Foo
,则现在返回Foo$Copy1
。所有代码引用也是如此。
答案 1 :(得分:2)
@leventov这一个怎么样? https://gist.github.com/serkan-ozal/8737583841b4b12e3a42d39d4af051ae
答案 2 :(得分:1)
如果你能正常访问字节码,我认为使用Unsafe就足够了。
像Foo.class.getClassLoader().getResourceAsStream()
之类的东西可以为你提供类的字节码。
然后使用
sun.misc.Unsafe.defineClass(String name, byte[] code, int off, int len, ClassLoader classLoader, ProtectionDomain protectionDomain)
在同一个类加载器和保护域中将类定义为Foo,但名称不同。
细节要弄清楚,但它可能是没有任何第三方库的最简单的方法。