如何在运行时复制 Java class?
How to make a copy of a Java class in runtime?
我有一个class
class Foo {
int increment(int x) {
return x + 1;
}
}
我想在运行时获取此 class 的副本,例如。 G。一个class喜欢
class Foo$Copy1 {
int increment(int x) {
return x + 1;
}
}
它具有所有相同的方法,但名称不同。
Proxy
似乎有助于 委派 ,但不能 复制 方法。
您可以为此使用 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
中 class 的任何用法,例如如果一个方法 returned Foo
,它现在会 return Foo$Copy1
。所有代码引用也是如此。
我认为如果您可以正常访问字节码,使用 Unsafe 就足够了。
类似 Foo.class.getClassLoader().getResourceAsStream()
的内容可以为您提供 class 的字节码。
然后使用
sun.misc.Unsafe.defineClass(String name, byte[] code, int off, int len, ClassLoader classLoader, ProtectionDomain protectionDomain)
在与 Foo 相同的 classloader 和保护域中定义 class 但名称不同。
细节有待弄清楚,但这可能是没有任何第三方库的最简单方法。
@leventov 这个怎么样? https://gist.github.com/serkan-ozal/8737583841b4b12e3a42d39d4af051ae
我有一个class
class Foo {
int increment(int x) {
return x + 1;
}
}
我想在运行时获取此 class 的副本,例如。 G。一个class喜欢
class Foo$Copy1 {
int increment(int x) {
return x + 1;
}
}
它具有所有相同的方法,但名称不同。
Proxy
似乎有助于 委派 ,但不能 复制 方法。
您可以为此使用 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
中 class 的任何用法,例如如果一个方法 returned Foo
,它现在会 return Foo$Copy1
。所有代码引用也是如此。
我认为如果您可以正常访问字节码,使用 Unsafe 就足够了。
类似 Foo.class.getClassLoader().getResourceAsStream()
的内容可以为您提供 class 的字节码。
然后使用
sun.misc.Unsafe.defineClass(String name, byte[] code, int off, int len, ClassLoader classLoader, ProtectionDomain protectionDomain)
在与 Foo 相同的 classloader 和保护域中定义 class 但名称不同。
细节有待弄清楚,但这可能是没有任何第三方库的最简单方法。
@leventov 这个怎么样? https://gist.github.com/serkan-ozal/8737583841b4b12e3a42d39d4af051ae