我想强制使另一个库中的类对子类开放.类本身是public的,但它唯一的构造函数是package—private.我已经探索了用字节码生成一个类,以打开构造函数并进行super()
调用.在JASM(超级酷)中,类看起来是这样的:
public class com/internal/OpenChild
extends com/external/Parent
{
public <init>()V {
try {
ldc com/external/Parent
iconst 0
anewarray java/lang/Class
invokevirtual java/lang/Class.getDeclaredConstructor([java/lang/Class)java/lang/reflect/Constructor
iconst 1
invokevirtual java/lang/reflect/Constructor.setAccessible(Z)V
} catch (java/lang/Throwable) {
astore 0
new java/lang/RuntimeException
dup
aload 0
invokespecial java/lang/RuntimeException.<init>(java/lang/Throwable)V
athrow
}
aload 0
invokespecial com/external/Parent.<init>()V
return
}
}
这个类,com.internal.OpenChild
,扩展com.external.Parent
.它的public no—args构造函数使后者的package—private no—args构造函数可以访问,并随后调用super
.等效的Java可能看起来像这样:
package com.internal;
import com.external.Parent;
public class OpenChild extends Parent {
public OpenChild() {
try {
Parent.class.getDeclaredConstructor().setAccessible(true);
} catch (Throwable t) {
throw new RuntimeException(t);
}
super();
}
}
当反射工作正常时,超级调用会失败,并出现IllegalExcellent异常.我相信我可能还有希望——毕竟,使用反射来创建一个com.external.Parent
的实例是可能的.我的策略中缺少了什么?难道就不能动用这种黑魔法吗?