如果我有对象并且我想在父类中调用方法的版本,我可以像x.super.method()
或super.x.method()
那样调用它吗?
答案 0 :(得分:0)
不仅仅是一个小小的研究答案。这是一个有趣的问题,所以只是为了好玩,我破解了一些测试代码。由于评论不支持格式化,因此我会在此处发布结果。
我怀疑使用super进行方法调用并实际编译的唯一方法是使用super unqualified ,即没有前缀表达式。
bar.blarch()按预期编译并运行(参见下面的示例)。
bar.super.blarch()没有编译(我也期望)。
Bar bar = new Bar();
System.out.println("bar.super.blarch() ==> " + bar.super.blarch() );
然而,错误消息让我感到惊讶。事实证明,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
所以在这一点上看起来像是超级'在运行中并不是javac而是试图在条形图之后找到一个实例变量。表达
然后我认为反射可能会给你一种方法来调用你的首选方法实现,但这也看起来像是号码。
具体到输出中最后一个例子的下一个:
" 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
$
public class Foo {
public String blarch() { return "Foo.blarch"; }
}
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
}
}