interface I
以下隐含地将class Object
的公共方法作为抽象成员。其中之一是toString()
interface I{
void test(int i);
//implicitly has abstract members matching every public method of 'class Object'
// one of them is toString()
}
以下class W
继承了class Object
个公开方法,其中一个是toString
,
class W implements I{
public static void main(String[] args){
I w = new W();
w.toString(); //How toString() method is resolved here?
}
}
两者,I
的超级接口(Object
)和超类(class W
) {{1}方法,
toString()
在编译时如何解析javac
?我了解到这里使用了w.toString()
指令。
jvm如何在运行时解析invokevirtual
?
答案 0 :(得分:3)
因为在类型为/auth/*
的表达式(接口类型)上调用该方法,所以字节码将包含相应方法的invokeinterface
指令。
在运行时,调用的方法将确定为
让
I
成为C
的类。要调用的实际方法是 通过以下查找过程选择:
- 如果
objectref
包含与已解析方法具有相同名称和描述符的实例方法的声明,则它是要调用的方法。- 否则,如果
C
有一个超类,则搜索与已解析的名称和描述符相同的实例方法的声明 从C
和的直接超类开始执行方法 继续该类的直接超类,等等, 直到找到匹配或不存在其他超类。如果匹配 发现,那就是要调用的方法。- 否则,如果
C
的超级接口中只有一个最大特定方法(第5.4.3.3节)与已解决的匹配 方法的名称和描述符并不是抽象的,那就是 要调用的方法。
在您的情况下,C
是对objectref
类型对象的引用。 W
不包含包含与已解析方法具有相同名称和描述符的实例方法的声明。因此,我们会检查W
,W
的超类。 Object
确实有这样的方法。因此调用该方法。
答案 1 :(得分:1)
interface
不会覆盖方法。
此外,您的课程不会覆盖方法toString()
。您必须重写方法toString()
才能过度使用它。
所以简单地称它为超类toString()
的{{1}}的实现。
答案 2 :(得分:0)
接口不会覆盖任何类的方法。当您使用toString()
方法时,默认toString()
会从Object
类执行,因为您的班级W
来自Object
。有关详细说明,请覆盖班级toString()
中的W
方法。
@Override
public String toString() {
return "Yo, baby! M here!";
}
然后输出将是:
Yo, baby! M here!
答案 3 :(得分:-2)
接口没有任何超类,甚至不包括Object类,例如
public class Main {
public static void main(String[] argv) throws Exception {
Class cls = java.lang.Cloneable.class;
Class sup = cls.getSuperclass(); // will return null
}
}
因此,接口永远不会覆盖Object类的方法。
当一个接口没有直接的SuperInterface时,它会创建 所有那些公共方法的抽象公共方法 对象类。