public class demo187
{
public static void main(String args[])
{
Comparable c =null;
c =30; //因为Integer实现了Comparable接口 30可以自动装箱为Integer
System.out.println(c);
}
}
输出结果为:30
直接输出c可以输出30,应该可以确定输出是调用了toString()方法,我在想此段程序是通过向上转型实现的那么c是Compareable的实例,那么c是不可以实现非接口里面的方法的,那为什么还可以调用toString()方法输出30呢?照理说toString()方法是Object类中的方法,Object 类又是所有对象的超类,跟接口是没有关系的。
[quote]
而且说接口继承了Object也是不对的,只是说接口引用的对象确实有Object的功能,我们不妨做个测试,你把任何一个类前面加个extends Object,这样是可以的,但是你把接口前面放个extends Object,是编译错误的,所以至少从语义上讲,接口的不是Object的子类,只能说,接口确实拥有Object的任何方法签名。
[/quote]
不是,通过我上面说的这段话,说明接口不是继承object的,只是接口有了object的所有方法签名,然后在接口引用类的时候,在调用toString这种方法签名的时候,运行时动态 后绑定接口指向的类,然后就调用了这个类的toString。就相当于它有这个方法签名而已。
接口,其实也是继承自Object的
If the value of the super_class item is zero, then this class file must represent the class Object , the only class or interface without a direct superclass.
For an interface, the value of the super_class item must always be a valid index into the constant_pool table. Thec onstant_pool entry at that index must be a CONSTANT_Class_info structure representing the class Object .
——摘自《JVMS-JavaSE7》4.1The ClassFile Structure中的super_class
[quote]那么c是不可以实现非接口里面的方法的[/quote]
这句话不对,它假如没有父类(注意 不是父接口),那么默认会继承object,所以就调用了object的toString啦。
而且说接口继承了Object也是不对的,只是说接口引用的对象确实有Object的功能,我们不妨做个测试,你把任何一个类前面加个extends Object,这样是可以的,但是你把接口前面放个extends Object,是编译错误的,所以至少从语义上讲,接口的不是Object的子类,只能说,接口确实拥有Object的任何方法签名。
不知道我的回答你满意不
ls说的欠妥,能不能编译完全是编译器在做一些事情,如下面的代码:
[code="java"]public class Test{
static {
i = 10;
//System.out.println(i);
}
private static int i;
} [/code]
加上sysout就不能编译了,其实如果编译器放宽条件完全是可以编译通过的,且也不会出现运行问题,因为上面i的内存分配肯定是在static块执行之前执行的,但编译器就是不让它通过编译。
只从字节码的角度来看,编译后的超类信息就是放在ClassFile的super_class条目中。虽然从接口的Class.getSuperClass返回的结果也是null,但我个人认为这是api给它做了一个限制,这个API有这样的声明([color=red]如果此 Class 表示 Object 类、一个接口、一个基本类型或 void,则返回 null[/color]),所以,只要判断是接口,根本就不用去取super_class条目代表的Constant_Class_info了,直接返回null了
javac编译器虽然对接口有限制,但我们还有其他编译器可以用,可以让接口extends Object
我们使用javassist
如下代码:
[code="java"]import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
public class TestCompiler {
public static void main(String[] args) throws Exception, NotFoundException {
CtClass ctClass = ClassPool.getDefault().makeInterface("MyInterface");
ctClass.setSuperclass(ClassPool.getDefault().get("java.lang.Object"));
ctClass.writeFile();
}
}[/code]
会生成一个MyInterface.class,用jd-gui反编译一下,我们就发现如下结果:
public abstract interface MyInterface extends Object
{
}
接口中肯定有toString方法
以下代码完全没问题啊:
[code="java"]public class TestInterface {
public static void main(String[] args) {
A a = null;
String str = a.toString();
}
}
interface A {
}[/code]