现有一个接口
public interface ISuper{
/*不定义任何的方法和字段*/
}
一个普通类,实现接口ISuper
public class Super implements ISuper{
/*无任何的方法和字段*/
}
public class Test{
public static void main(String[] args){
ISuper super = new Super();
super.toString();//为何任然可调用Object类的方法
}
}注:
1.ISuper没有定义任何方法和字段.
2.向上转型会丢失子类接口
个人猜想:
1.单根继承
2.特殊处理
public interface ISuper{
/*不定义任何的方法和字段*/
}
一个普通类,实现接口ISuper
public class Super implements ISuper{
/*无任何的方法和字段*/
}
public class Test{
public static void main(String[] args){
ISuper super = new Super();
super.toString();//为何任然可调用Object类的方法
}
}注:
1.ISuper没有定义任何方法和字段.
2.向上转型会丢失子类接口
个人猜想:
1.单根继承
2.特殊处理
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. 也就是说接口中隐式的声明了与Object类中方法签名相同的方法。
/*无任何的方法和字段*/
}Super类默认已经继承了java.lang.Object类(任何类都是这样)。
http://blog.csdn.net/ZangXT/archive/2008/11/27/3389395.aspx
如果编译器发现你调用的是Object类的方法,它自动处理了。编译器的实现和java语言规范的说法仔细看来并不一致。比如这个例子:interface ITest{
void test();
}public class Test implements ITest{
public void test(){
System.out.println("test");
}
public static void main(String[] args){
ITest i = new Test();
i.toString();
i.test();
}
}看编译、反汇编之后的代码:public static void main(java.lang.String[]);
Code:
0: new #5; //class Test
3: dup
4: invokespecial #6; //Method "<init>":()V
7: astore_1
8: aload_1
9: invokevirtual #7; //Method java/lang/Object.toString:()Ljava/lang/String;
12: pop
13: aload_1
14: invokeinterface #8, 1; //InterfaceMethod ITest.test:()V
19: return我们能发现,调用Object类的方法时,编译产生的是invokevirtual指令,而非invokeinterface指令。
super.toString();//为何任然可调用Object类的方法
编译时,编译器能够发现super变量为接口类型的引用,如果调用的方法是Object类定义的方法,编译器直接开绿灯就是了。
可为什么出现invokevirtual指令呢
再说从性能上讲invokevirtual要比invokeinterface好的。因为invokevirtual是直接根据索引定义方法,而invokeinterface要挨着查。因此,编译器的这种选择也无可厚非。反正表现上不影响java的语义。
public void testInterface();
}class SuperTest{
public void testSuperClass(){
System.out.println("SuperTest's testSuperClass()!");
}
}
public class Test extends SuperTest implements InterfaceTest{ public static void main(String[] args) {
InterfaceTest t = new Test();
t.testInterface();
// t.testSuperClass();
} public void testInterface() {
System.out.println("InterfaceTest's testInterface()!");
}
}
InterfaceTest t = new Test();
虽然t实际指向的对象是SuperTest的子类,但我们不能通过t来调用testSuperClass(),因为不管t指向的实际对象是什么,t的类型是InterfaceTest ,而这个接口中没有定义testSuperClass()方法,所以不能够使用t.testSuperClass();
同样道理,InterfaceTest 接口中没有定义toString()等方法,那为什么可以调用呢?这就是编译器的特殊处理了。注意,有人说接口继承Object类,那是明显错误的。接口不能继承类,这是java的规则。
因此可以访问到object的方法
2. 要不误认为interface隐含继承Object.
因此可以访问到object的方法
public class Super extends Object implements ISuper{
/*无任何的方法和字段*/
}
Java code
public class Super extends Object implements ISuper{
/*无任何的方法和字段*/
}
/*无任何的方法和字段*/
}
@Override
public String toString();
}
而不能这么写interface Interface {
public void toString();
}
interface相当于把Object的方法抽象了 这些方法是被隐藏的
interface本身不能被实例化 当一个interface的引用指向一个类的对象的时候
interface里的那些隐藏方法就被这个类给实现了
public void toString();
}
eclipse提示错误:
The return type is incompatible with Object.toString()public interface Xx {
@Override
public String toString();
}
eclipse提示错误:
The method toString() of type Xx must override a superclass methodpublic class OoXx extends Oo implements Xx
在Oo中重写toString方法return null,则
Oo oo=new OoXx();
Xx xx=new OoXx();
oo.toString()和xx.toString()都返回Null;
Object.class反编译代码:package java.lang;public class Object
{
private static native void registerNatives();
public final native Class getClass();
public native int hashCode();
public boolean equals(Object object_0_) {
return this == object_0_;
}
protected native Object clone() throws CloneNotSupportedException;
public String toString() {
return new StringBuilder().append(getClass().getName()).append("@")
.append
(Integer.toHexString(hashCode())).toString();
}
public final native void notify();
public final native void notifyAll();
public final native void wait(long l) throws InterruptedException;
public final void wait(long l, int i) throws InterruptedException {
if (l < 0L)
throw new IllegalArgumentException("timeout value is negative");
if (i < 0 || i > 999999)
throw new IllegalArgumentException
("nanosecond timeout value out of range");
if (i >= 500000 || i != 0 && l == 0L)
l++;
wait(l);
}
public final void wait() throws InterruptedException {
wait(0L);
}
protected void finalize() throws Throwable {
/* empty */
}
static {
registerNatives();
}
}