接口是不能分配内存内间的,即Interface I1=new I1();会出现编译错误,抽象类也如此,但下面这段代码谁能解释一下?
abstract class I1{
private int i;

public void seti(int val){
i=val;
}

public int geti(){
return i;
}
abstract void p();
}
public class Test {

public static I1 getI1(){
return new I1(){ // ??
public void p(){
System.out.println("hello,pattern"); //没有执行??
}
};
}

public static void main(String[] args){
Test test=new Test();
I1 i1=test.getI1();
}
}
难道是java内部申请了一段内存空间,然后做了一个伪reference,用这段内存空间指向它?

解决方案 »

  1.   

    其实public static I1 getI1()返回了一个I1的子类,函数中有一个匿名的内类,该类实现p这个虚拟函数.至于你说的System.out.println("hello,pattern"); //没有执行??
    的问题,其实你根本就没有调用p这个函数.
      

  2.   

    new I1(){ // ??
    public void p(){
    System.out.println("hello,pattern"); //没有执行??
    }
    };
    这里定义了一个匿名的类,并且生成了一个该类的实例.
      

  3.   

    把接口理解为父类就ok了,这里只不过是upcast而已
      

  4.   

    晕,不好意思,说明一下,那个"//没有执行"不是错误,是以后用到的注释,问题在//??这里,即然I1是接口,怎么可以new I1()呢,还能通过编译??????
      

  5.   

    向上转型是java自己内部就做了?
      

  6.   

    abstract class I1
    {
    private int i;

    public void seti(int val)
            {
    i=val;
    }

    public int geti()
            {
    return i;
    }
    abstract void p();
    }
    public class Test 
    {

    public static I1 getI1()
            {
    return new I1()
                    { // ??
    public void p()
                            {
    System.out.println("hello,pattern"); //没有执行??
    }
    };
    }

    public static void main(String[] args)
            {
    Test test=new Test();
    I1 i1=test.getI1();
                    i1.p();
    }
    }
    这样就执行了
      

  7.   

    再解释一下,那个// 没有执行是以后程序调用没有执行的注释,和这个问题无关,我重写了一下:
    interface I1{
    void p();
    }public class Test {

    public static I1 getI1(){
    return new I1(){ // new I1()好像不符合java规范,不能给一个接口分配内存空间
    public void p(){
    System.out.println("hello,pattern");
    }
    };
    }

    public static void main(String[] args){
    Test test=new Test();
    I1 i1=test.getI1();
    }
    }
    这段程序能编译成功,请问java内部是如何实现的?
      

  8.   

    你生成匿名类是I1的子类,该类中已经实现了p方法,因此该类就不是抽象类了(虽然没有名字)。
    实际上,getI1()中创建的就是上述类的一个实例,而不是I1的实例。因为该类是I1的子类,故
    可以用I1作为该实例对象的引用类型,仅此而已。
      

  9.   

    我上面的是interface~~,编译能通过那是肯定的了,我试过,new I1()它这里面都做了哪些操作?
      

  10.   

    不管interface或者abstract class都是一样的,你仔细看看书吧.不明白什么是匿名内类的话,我们再怎么跟你说也说不明白的.看你程序里面有句hello,pattern,不是在看pattern吧?还是先不要看了.
      

  11.   

    这是匿名类public class Test {
    /`***********************************************************************************
    public static I1 getI1(){
    return new I1(){ // ??
    public void p(){
    System.out.println("hello,pattern"); //没有执行??
    }
    };
    }
    ***************************************************************************************/
    //这样就是隐式声明一个实现了I1接口的class(该class没有明确的名字,编译的时候,编译器会自动为该类命名为Test$I1),然后返回该class的一个实例
    上面的代码相当于
    ///////////////////////////////////////////////////////////////////////////////////////
    public static I1 getI1(){
    calss Test$I1 implements I1 {
    public void p(){
    System.out.println("hello,pattern"); //没有执行??
    }
    };
    return new Test$I1();
    }//这样就是显式声明一个实现了I1接口的class,然后返回该class的一个实例
    ////////////////////////////////////////////////////////////////////////////////////////
    public static void main(String[] args){
    Test test=new Test();
    I1 i1=test.getI1();
    }
    }
    至于System.out.println("hello,pattern"); //没有执行??
    那是因为你没有调用接口的 p()方法,这不是构造函数,不调用又怎么会自动执行呢?
      

  12.   

    这是java的匿名类机制,相当于一个实现了借口的类,只是没有名字