[英]Call non-abstract method of abstract class without its instance
考慮以下代碼:
public interface IRegistryClass
{
public IRegistryClass get();
}
public abstract class Skill implements IRegistryClass
{
@Override
public Skill get()
{
return new SkillFake();
}
private final class SkillFake extends Skill
{}
}
僅在Skill.class提供時可以調用skill#get()嗎?
常規Java不允許對#newInstance()抽象類進行分類。 問題是:有辦法嗎?
注意:我不能使用static關鍵字。 我需要繼承這一點。
編輯:我讀過關於不安全的信息-在這種情況下有幫助嗎? 我知道您的日常Java在這里沒有用。 需要一些極端的東西。
即使使用Unsafe
也不能執行此操作,因為Unsafe.allocateInstance
為抽象類拋出java.lang.InstantiationException
。 唯一可能的解決方案是創建一個像這樣的匿名類:
new Skill() {}.get();
這並不是您想要的,因為匿名類仍然是繼承了Skill
類的新類。 但這在許多情況下是令人滿意的。
更新:如果您真的想要一些極端的東西,可以在運行時旋轉匿名類。 例如,這是使用ASM庫完成的方法:
// Generate subclass which extends existing Skill.class
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
String superClassName = Skill.class.getName().replace('.', '/');
cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER + Opcodes.ACC_FINAL
+ Opcodes.ACC_SYNTHETIC, "anonymous", null, superClassName, null);
// Create constructor which calls superclass constructor
MethodVisitor ctor = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
ctor.visitCode();
// load this
ctor.visitVarInsn(Opcodes.ALOAD, 0);
// call superclass constructor
ctor.visitMethodInsn(Opcodes.INVOKESPECIAL, superClassName, "<init>", "()V", false);
// return
ctor.visitInsn(Opcodes.RETURN);
ctor.visitMaxs(-1, -1);
ctor.visitEnd();
cw.visitEnd();
// Get the Unsafe object
Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
sun.misc.Unsafe UNSAFE = (sun.misc.Unsafe) field.get(null);
// Create new anonymous class
Class<? extends Skill> clazz = UNSAFE.defineAnonymousClass(Skill.class,
cw.toByteArray(), null).asSubclass(Skill.class);
// instantiate new class and call the `get()` method
clazz.newInstance().get();
這樣,您就可以在運行時中對抽象類進行子類化(子類在已編譯的代碼中不存在)。 當然,應當指出,這樣的解決方案絕對是不安全的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.