以下接口和类已成功编译。 问题在下面的输出中提到:
interface MyInterface{}
class MyClass implements MyInterface{}
class InterDoubt{
static MyInterface mi ;//= new MyClass() ;
public static void main(String[] args){
System.out.println("X") ;
try{
synchronized(mi){
try{
mi.wait(4000) ;
}
catch(InterruptedException ie){
System.out.println("Exception occured at main.") ;
}
}
}
catch(Exception e){
System.out.println("voilla, MyInterface is an interface,\n" +
"then why compiler allows compilation of\n" +
"mi.getClass(), mi.wait().\n" +
"Or how the methods of Object class are available in an interface."
);
}
System.out.println("Y") ;
}
}
输出
X
voilla,MyInterface是一个界面,
那么为什么编译器允许编译
mi.getClass(),mi.wait()。
或者如何在接口中使用Object类的方法。
ý
已修改: - 我接受来自disown的回答,因为它是最具说明性的。但在阅读完答案之后,还有另外一个问题: -
“请记住,如果接口尝试在Object类中声明一个声明为'final'的公共实例方法,那么它将导致编译时错误。例如,'public final Class getClass()'is在Object类中声明为'final'的公共实例方法,因此如果接口尝试使用此签名声明方法,则编译将失败“(引自解释)。
然后为什么以下代码被成功编译: -
interface MyInter{
public void method() ;
}
class MyClass implements MyInter{
public final void method() {
.......
.......
.......
}
}
答案 0 :(得分:5)
您正确指出的异常是在Java语言规范中指定的。接口将自动从类java.lang.Object中添加所有成员。来自here:
Java语言规范明确指出接口的成员是在接口中声明的成员和从直接超级接口继承的成员。如果接口没有直接超接口,则接口隐式声明与Object类中声明的每个公共实例方法对应的公共抽象成员方法,除非具有相同签名,相同返回类型和兼容throws子句的方法由那个界面。这使得Object方法的签名可供编译器使用,代码编译时没有任何错误。请记住,如果接口尝试在Object类中声明一个声明为'final'的公共实例方法,那么它将导致编译时错误。例如,'public final Class getClass()'是在Object类中声明为'final'的公共实例方法,因此如果接口尝试使用此签名声明方法,则编译将失败。
答案 1 :(得分:2)
在运行时,参考mi后面应该有一个真实对象(或null)。真实类型将实现此接口,因此编译器允许它。在运行时,任何实现该接口的类型都可以在那里。
答案 2 :(得分:0)
是的,除了Primitive值之外,所有Object的方法都可用。接口对象仍然是对象,因此它们具有Object的方法。
答案 3 :(得分:0)
演员(对象)mi将永远成功,所以为什么要求你提供它呢?
答案 4 :(得分:0)
Java语言规范明确指出接口的成员是在接口中声明的成员和从直接超级接口继承的成员。如果接口没有直接超接口,则接口隐式声明与Object类中声明的每个公共实例方法对应的公共抽象成员方法,除非具有相同签名,相同返回类型和兼容throws子句的方法由那个界面。