谁用反射调用对象的超级方法?

时间:2014-11-27 11:31:05

标签: java reflection

我有以下设置

class A {

    @Override
    public String toString(){
        return "A's toString";
    }

}

class B extends A {

    @Override
    public String toString(){
        return "B's toString";
    }

}

我有一个B类的实例,我想只使用反射调用B.super.toString。请注意,A类和B类不是特定的,我正在使用除A或B以外的对象,但我正在寻找的方法肯定在课堂上。我尝试了以下但没有取得任何成功:

1

...
private void callSuperToString(Object object){
    //class B is an example for object.getClass in this example
    String value = (String) object.getClass()
                .getSuperclass()
                .getMethod("toString")
                .invoke(object.getClass().getSuperclass().newInstance());
}

在上面的情况下,值将是“A的toString”,这是我所期望的,但这对我不利,因为这需要超类的实例化,这并不总是可能的(例如,超类是抽象的)此外,新实例'字段与对象的超类字段不同。对我来说不是解决方案。

2:

...
private void callSuperToString(Object object){
    Method method = object.getClass().superClass().getDeclaredMethod("toString");
    String value = (String) method.invoke(object);
}

在这种情况下,值将是“B的toString”,它不是预期的“A的toString”。是否有可能实现我在这里要做的事情?

编辑:

3

...
private void callSuperToString(Object object){
    MethodHandle handle = MethodHandles.lookup()
        .findSpecial(object.getClass().getSuperclass(), "toString",
        MethodType.methodType(String.class),
        object.getClass());
    value= (String) handle.invoke(object);
}

以下引发此异常:java.lang.IllegalAccessException:invokespecial没有私有访问权限

编辑2:

是的,这可能是重复的。我在提供的链接中找到了答案,这不是公认的答案。以下工作完美:

解决方案:

...
private void callSuperToString(Object object){
    Field IMPL_LOOKUP = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
    IMPL_LOOKUP.setAccessible(true);
    MethodHandles.Lookup lkp = (MethodHandles.Lookup) IMPL_LOOKUP.get(null);
    MethodHandle h1 = lkp.findSpecial(object.getClass().getSuperclass(), "toString",
        MethodType.methodType(String.class),
        object.getClass());
    value= (String) h1.invoke(object);
}

0 个答案:

没有答案