其实这个问题讨论起来没什么意义,不过大半夜睡不着,写点东西散个分.下面是一个最简单的interface:
interface I {}
这个 I 和 Object 到底有什么关系呢?问题一:
public class T {
public static void main(String[] args) {
I i;
}
}
上面一个简单的类,用eclipse的时候在I i;下面面输入"i."会出现Object的方法列表.
显然即时编译器编译通过了才会出现这种结果.为什么?问题二:
interface Test {
public int toString();
}
接口改成上面这个样子.编译后有如下错误:
Test.java:2: Test 中的 toString() 无法覆盖 java.lang.Object 中的 toString();正在尝试使用不兼容的返回类型
找到: int
需要: java.lang.String
        public int toString();
                   ^
1 错误问题三:
再改改这个接口:
interface Test {
public void wait();
}
编译后有如下错误:
Test.java:2: Test 中的 wait() 无法覆盖 java.lang.Object 中的 wait();被覆盖的方法为 final
        public void wait();
                    ^
1 错误
要回答这三个问题,就先要回答interface和Object的关系.
从java程序设计语言的角度上将interface不是类,而Object是所有类的最终超类.
所以从这里看interface和Object没有必然联系.但是看看java language specification中怎么说:
If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface. It is a compile-time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.It follows that is a compile-time error if the interface declares a method with a signature that is override-equivalent (§8.4.2) to a public method of Object, but has a different return type or incompatible throws clause.简单的说就是:
如果接口没有直接超接口,那么该接口会隐式声明一些public abstract的方法,这些方法和Object中的public方法具有对应的方法签名,返回类型,异常列表.
如果在接口中显示声明了Object中的final的方法,报错.
如果在接口中声明的方法和Object中的方法具有相同的方法签名,但是返回类型不同或者异常列表不相容,报错.按照上面的说法,给与了前三个问题合理的解释.
interface不是类,与Object的关系更谈不上继承.但它和Object的关系密切,它将Object的public方法都声明为了abstract.但是问题并没有就此结束...
还是这个interface I {}
编译后javap -verbose看看:
常量池Constant pool:
const #1 = class        #5;     //  I
const #2 = class        #6;     //  java/lang/Object
const #3 = Asciz        SourceFile;
const #4 = Asciz        I.java;
const #5 = Asciz        I;
const #6 = Asciz        java/lang/Object;
可以明确的说:
const #1 = class为this_class项所指.
const #2 = class为super_class项所指.再看看这个:
interface M extends i {}
常量池  Constant pool:
const #1 = class        #6;     //  M
const #2 = class        #7;     //  java/lang/Object
const #3 = class        #8;     //  I
const #4 = Asciz        SourceFile;
const #5 = Asciz        I.java;
const #6 = Asciz        M;
const #7 = Asciz        java/lang/Object;
const #8 = Asciz        I;
其中
const #1 = class仍为this_class项所指.
const #2 = class仍为super_class项所指.仍然是java/lang/Object
而const #3 = class是interfaces数组项所指.
I被指为M的interface,相当于implements,而并不像声明中说的extends.insideJVM中指出任何interface的super_class项均为java/lang/Object.
只有java/lang/Object的super_class项为0.再看下下面的代码
class Test {
void f() {
I i = null;
i.toString();
}
}
f()的指令操作码:
void f();
  Code:
   Stack=1, Locals=2, Args_size=1
   0:   aconst_null
   1:   astore_1
   2:   aload_1
   3:   invokevirtual   #2; //Method java/lang/Object.toString:()Ljava/lang/String;
   6:   pop
   7:   return关键的这句:
3:   invokevirtual   #2; //Method java/lang/Object.toString:()Ljava/lang/String;
编译器在处理i.toString()的时候是查看的i的声明类型,也就是I. 
要知道这个时候编译器只知道i的类型是I,对i的实际类型是不知道的.如果I没有toString方法,那么编译器就会去I的super_class项指定的类中去找.
而最后动态绑定上的是Object的toString. 
当然可以按前面的解释,interface隐式声明了toString方法,然后映射到Object的toString的方法.但是与其用这种牵强的解释,不如解释成interface的超类就是Object(至少在编译器和虚拟机是这么看的)来的合适.最后我想说的是,规范和实现是两个层面上的东西,不能混为一谈,但又经常分不清...

解决方案 »

  1.   

    Q:下面是一个最简单的interface:
    interface I {}
    这个 I 和 Object 到底有什么关系呢?A:这个I和Object没有任何关系,Object是类和抽象类的基类,而不是接口的基类。
      

  2.   

    问题二:
    interface Test {
    public int toString();
    }
    接口改成上面这个样子.编译后有如下错误:
    Test.java:2: Test 中的 toString() 无法覆盖 java.lang.Object 中的 toString();正在尝试使用不兼容的返回类型
    找到: int
    需要: java.lang.String
            public int toString();
                       ^
    1 错误答案:因为任何一个接口的存在的目的是让一个具体的类去实现它,而实现这个接口的这个类,即默认的继承了Object的toString,由于接口又定义了toString方法,这两个方法它们的返回类型仅仅不同,因此,会有错的。
      

  3.   

    问题三:
    再改改这个接口:
    interface Test {
    public void wait();
    }
    编译后有如下错误:
    Test.java:2: Test 中的 wait() 无法覆盖 java.lang.Object 中的 wait();被覆盖的方法为 final
            public void wait();
                        ^
    1 错误问题和上面的第二个问题类似,因为Object里面的wait是final的,因此,改方法不能被继承重写,而接口Test定义了一个wait方法,改方法和Object方法的唯一不同是,Object的wait方法
    的原型是final的,在Java中,不能有一个类,继承一个类A和一个接口B,类A有一个和接口B相同的方法,而类A的方法确实final的,不知道说清楚了没有?
      

  4.   

    我刚学JAVA一个星期,还没看懂你所说的东东,不过以后我还会来看你的帖的。
    UP!!
      

  5.   

    恩.强.以前只注意到object 是所有类的超类,没有注意这些.jf
      

  6.   

    尽信书 不如无书
    书不是规范 只不过是前人理解的总结I.class instanceof Object
    这个是ture的
    那说明interface 应该是继承Object的另外从interface的文件也是.class来看 interface应该是一个特殊的类
    特殊的类 叫接口
    另外 就算用一个interface声明 来持有一个对象  
    也是可以肯定这个对象是继承Object的 所以其中的方法肯定是存在的
    所以完全可以对interface声明调用Object方法
      

  7.   

    楼上的意思我理解,我原本也是坚持interface是继承Object的,而且本身这篇帖子也是倾向于这点.
    但是有书在那摆着,也不好说什么.而且毕竟将interface解释成继承Object还是有一些地方说不通的.另外编译器和虚拟机的实现也是各有差异的.
    顺便问一句,说到规范,那
    <Java Language Specification>算不算规范?
    <Java Virtual Machine Specification>算不算规范?
      

  8.   

    其实只需要简单的理解成,接口和类没有关系,但接口不被类实现就没有意义。而如果一个接口一旦被某个类实现,那这个类就一定会具有Object的方法。因此一个接口中申明的方法不能和Object的方法冲突。或者,可以理解为Interface也是从Object继承。所以一个接口类型的变量会具有Object的方法。但是,由于这个变量的值实际是null,所以即使调用这个Object中的某些方法,也只会得到NulLPointerException。语法上虽然没有问题,但执行起来却是个不折不扣的毫无意义的东西。
      

  9.   

    类和接口可以看成两个平级的,在一个类里面不可以new接口,只能new接口的实现类
      

  10.   

    .class instanceof Object
    这个是ture的
    那说明interface 应该是继承Object的另外从interface的文件也是.class来看 interface应该是一个特殊的类
    特殊的类 叫接口
    另外 就算用一个interface声明 来持有一个对象  
    也是可以肯定这个对象是继承Object的 所以其中的方法肯定是存在的
    所以完全可以对interface声明调用Object方法
      

  11.   

    .class instanceof Object
    这个是ture的
    那说明interface 应该是继承Object的我不知道所说的.class表示什么意思?为什么.class可以用于instanceof 操作?任何一个继承自Object的类,都应该有个class静态常量,但是任何一个interface却没有这个常量?从这一点上,敢说interface继承自Object?再一点,Object作为一个具体的类类型,占用实际的内存空间8个字节,而地球人都知道Interface实际上是不占用空间的,从这一点上,敢说interface继承自Object?这个问题讨论下去没什么意义了,
    既然是散分贴,请散分接贴吧。
      

  12.   

    JavaEE高手进入 
    QQ群 5294054
      

  13.   

    单单从任何实现类都是Object的子类来判断,就说interface也是Object的子类,似乎有点说不通啊,因为Java中总是有一些默认的规定,如果任何实现类都是默认继承自Object的,那就有必要更深入地探讨了.
    不过从.class instanceof Object的结果为true来看,倒是很有道理的.
      

  14.   

    .class instanceof Object
    ...
    这句话能判断是不是继承Object?
    那String.class instanceof String呢?