与其说是一个答案,不如说是一个小小的研究。这是一个有趣的问题,所以只是为了好玩,我编写了一些测试代码。由于 cmets 不支持格式化,所以我在此处发布结果。
我怀疑将 super 用于方法调用并使其实际编译的唯一方法是使用 super unqualified,即没有前缀表达式。
bar.blarch() 按预期编译和运行(参见下面的示例)。
bar.super.blarch() 没有编译(我也预料到了)。
Bar bar = new Bar();
System.out.println("bar.super.blarch() ==> " + bar.super.blarch() );
但是,error 消息让我感到惊讶。原来javac抱怨“找不到符号”如下:
Bar.java:15: error: cannot find symbol
System.out.println("bar.super.blarch() ==> " + bar.super.blarch() ); // does not compile.
^
symbol: class bar
location: class Bar
所以在这一点上,'super' 似乎不在运行中,而 javac 正试图在 bar 之后找到一个实例变量。表达。
然后我认为反射可能为您提供了一种调用您的首选方法实现的方法,但这看起来也像否。
特别是输出中最后一个示例的旁边:
"fooBlarch.invoke(bar)=Bar.blarch"
尝试在 Bar 类型的实例上调用 Foo 类中的方法,但它仍以 Bar 开头并调用第一个匹配的方法名称 + 签名。
$ javac *.java
Note: Bar.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
$ java Bar
foo.blarch() ==> Foo.blarch
bar.blarch() ==> Bar.blarch
bar.superBlarch() ==> Foo.blarch
moreFoo.blarch() ==> Bar.blarch
fooClass=class Foo
fooBlarch=public java.lang.String Foo.blarch()
fooBlarch.invoke(foo)=Foo.blarch
fooBlarch.invoke(bar)=Bar.blarch
fooBlarch.invoke((Foo)bar)=Bar.blarch
$
Foo.java
public class Foo {
public String blarch() { return "Foo.blarch"; }
}
Bar.java
import java.lang.reflect.*;
public class Bar extends Foo {
public String blarch() { return "Bar.blarch"; }
public String superBlarch() { return super.blarch(); }
public static void main( String[] args ) throws Exception {
Foo foo = new Foo();
System.out.println("foo.blarch() ==> " + foo.blarch() ); // prints Foo.blarch
Bar bar = new Bar();
System.out.println("bar.blarch() ==> " + bar.blarch() ); // prints Bar.blarch
System.out.println("bar.superBlarch() ==> " + bar.superBlarch() ); // prints Foo.blarch
// System.out.println("bar.super.blarch() ==> " + bar.super.blarch() ); // does not compile.
// Bar.java:15: error: cannot find symbol
// System.out.println("bar.super.blarch() ==> " + bar.super.blarch() ); // does not compile.
// ^
// symbol: class bar
// location: class Bar
Foo moreFoo = new Bar();
System.out.println("moreFoo.blarch() ==> " + moreFoo.blarch() ); // prints Bar.blarch
Class fooClass = foo.getClass();
System.out.println("fooClass="+fooClass);
Method fooBlarch = fooClass.getDeclaredMethod( "blarch", new Class[] { } );
System.out.println("fooBlarch="+fooBlarch);
System.out.println("fooBlarch.invoke(foo)="+ fooBlarch.invoke( foo ) ); // yields Foo.blarch
// I think you're out of luck trying to use anything "super-like" outside of a given class.
// looks like Method.invoke() walks the full instance ancestors looking for a suitable implementation.
// I actually didn't expect this one to compile given that the method is from class Foo, not Bar.
System.out.println("fooBlarch.invoke(bar)="+ fooBlarch.invoke( bar ) ); // yields Bar.blarch
// casting matters not at all.
System.out.println("fooBlarch.invoke((Foo)bar)="+ fooBlarch.invoke( (Foo)bar ) ); // yields Bar.blarch
}
}