繁体   English   中英

调用没有其实例的抽象类的非抽象方法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM