package innerclass;public class Parcel2{

class Contents {
private int i = 11;
public int value() {return i;}
} class Destination {
private String label;
Destination(String whereTo){
label = whereTo;
}
String readLabel() {return label;}
} public Destination to(String s){
return new Destination(s);
} public Contents contents() {
return new Contents();
} public void ship (String dest){
Contents c = contents();
Destination d = to(dest);
System.out.println(d.readLabel());
} public static void main(String[] args) {
Parcel2 p = new Parcel2();
p.ship("Tasmania"); Parcel2 q = new Parcel2();
Contents c = q.contents(); //静态方法中调用内部类,应该由外部列对象调用才行
Destination d = q.to("Borneo"); //如:Parcel2.Destination d = q.to("Borneo");
System.out.println(d.readLabel()); //但此类中没有用外部类对象,竟然没有报错,求解释?
}
}问题描述见注释
环境:jdk1.5

解决方案 »

  1.   

    Parcel2 q = new Parcel2();
    Contents c = q.contents();        //静态方法中调用内部类,应该由外部列对象调用才行
    contents是Parcel2的实例方法,在该方法内new Contents的,而该方法是通过对象q调用的,所以并不是static方法直接调用内部类,如果是直接调用应该是,Contents c = contents(); 即不通过对象调用,这显然是不行的,同理to方法也一样,这个外部类实例就是q,因为是通过q调用方法的。Destination d = q.to("Borneo");        //如:Parcel2.Destination d = q.to("Borneo");
    System.out.println(d.readLabel());    //但此类中没有用外部类对象,竟然没有报错,求解释?
      

  2.   

    还是用代码来解释吧
    public class Parcel2{
        String name; //追加一个外部类属性
        public Parcel2(String name) {this.name=name;} //追加一个外部类构造函数
        class Contents {
            private int i = 11;
            public int value() {return i;}
            public String getOuterName() {return Parcel2.name;} //追加一个查看外部类的方法
        }    class Destination {
            private String label;
            Destination(String whereTo){
                label = whereTo;
            }
            String readLabel() {return label;}
        }    public Destination to(String s){
            return new Destination(s);
        }    public Contents contents() {
            return new Contents();
        }    public void ship (String dest){
            Contents c = contents();
            Destination d = to(dest);
            System.out.println(d.readLabel());
        }    public static void main(String[] args) {
            //Parcel2 p = new Parcel2();
            //p.ship("Tasmania");        Parcel2 q = new Parcel2("I am q"); //生成外部类实例
            Contents c = q.contents(); 
            System.out.println(c.getOuterName()); //看看c的外部类实例是什么?
            Destination d = q.to("Borneo"); 
            System.out.println(d.readLabel()); 
        }
    }
      

  3.   

    这里改一下
    public String getOuterName() {return Parcel2.this.name;} //追加一个查看外部类的方法
      

  4.   

    public String getOuterName() {return Parcel2.this.name;} //追加一个查看外部类的方法
      

  5.   


    首先谢谢qybao
    确实解决我的问题和疑惑但是有一个地方我觉的应该是这样的
    在你的第一次回复中提到:“如果是直接调用应该是,Contents c = contents()”我将代码改成Contents c = contents()后
    编译报错:无法从静态上下文中引用非静态 方法 contents()
    这个应该是静态方法不能直接调用非静态方法的错误为了验证上面的猜想,在类中添加了writeStr()函数
    public void writeStr() {
    System.out.println("no-static && no inner class");
    }
    在main函数中直接调用该函数
    报错:无法从静态上下文中引用非静态 方法 writeStr()所以验证了我上面的结论:“Contents c = contents()”报错原因是:静态方法不能直接调用非静态方法的错误我觉得如果这样写“Contents c = new Contents()”就应该是静态方法直接调用内部类的错误了
      

  6.   


    谢谢你的建议
    我刚才试过了,如果在其他类中main,直接调用Parcel2的内部类
    报错是:找不到内部类其实我觉得就算在其他类中,在非静态类中,直接调用Parcel2的内部类,也会报同样的错误(未测试)
    因为内部类编译后,class文件名为Parcel2$Contents.class和Parcel2$Destination.class但是通过外部类调用内部类是没问题的
      

  7.   

    这两个是一样的错误,都是static不能直接调用static,如果Contents声明为static class就可以调用,同样的,contents声明为static也可以调用(不过这时你的contents方法内的代码就不能直接new内部类了)。
      

  8.   

    只要不是static的,就必须通过外部类实例调用,所以其他类也会一样报错的
      

  9.   

    LZ是不是不想通过实例方法返回,想通过new方法得到实例
    如果是这样的话,可以先new一个外部实例,再new内部实例

    Contents c = newParcel2().new Contents();
      

  10.   

    这是连着写的,像你原来的代码,可以
    Contents c = q.new Contents(); //也就是说需要个外部类实例
      

  11.   

    LZ是想讨论
    Parcel2.Destination

    Destination
    的区别吧
    以下是我的理解:
    我觉得他们在编译器眼里是一样的。
    即便你在Parcel2外部在定义一个Destination
    的类。他也不会调用外部定义的Destination
    类。而是直接调用内部类Destination感觉一般采用第一种写法,是为了让代码有更好的可读性。