我这里提一个关于匿名类的问题,主要涉及匿名类的初始化顺序。
代码1:
public interface Contents {
  int value();
}public class Parcel7b {  //这是一段普通代码
  class MyContents implements Contents {
    private int i = 11;
    public int value() { return i; }
  }
  public Contents contents() { return new MyContents(); }
  public static void main(String[] args) {
    Parcel7b p = new Parcel7b();
    Contents c = p.contents();
  }
代码2:
public class Parcel7 {  //这是上段普通代码的匿名类形式
  public Contents contents() {
    return new Contents() { 
      private int i = 11;
      public int value() { return i; }
    }; 
  }
  public static void main(String[] args) {
    Parcel7 p = new Parcel7();
    Contents c = p.contents();
  }
}代码3:
public class Wrapping {
  private int i;
  public Wrapping(int x) { i = x; }
  public int value() { return i; }
}public class Parcel8 {  //这是基类带构造器的匿名类形式
  public Wrapping wrapping(int x) {
    return new Wrapping(x) { 
      public int value() {
        return super.value() * 47;
      }
    }; 
  }
  public static void main(String[] args) {
    Parcel8 p = new Parcel8();
    Wrapping w = p.wrapping(10);
    System.out.println(w + " ");
  }
}代码1和代码2完全用于演示,问题是代码3。按照代码1、2的演示,知道匿名类是先定义类,然后再生成对象向上转型的,但是代码3中的匿名类中并没有构造函数,如果这个匿名类继承了Wrapping类及它带参数的构造函数,但是自己却没有构造函数来调用基类的构造函数,为什么创建对象时不会编译错误。这个值究竟是通过什么样的过程来传到基类里的?

解决方案 »

  1.   

    此回复为自动发出,仅用于显示而已,并无任何其他特殊作用
    楼主【llm0528】截止到2008-07-28 12:01:52的历史汇总数据(不包括此帖):
    发帖的总数量:63                       发帖的总分数:1300                     每贴平均分数:20                       
    回帖的总数量:55                       得分贴总数量:0                        回帖的得分率:0%                       
    结贴的总数量:63                       结贴的总分数:1300                     
    无满意结贴数:0                        无满意结贴分:0                        
    未结的帖子数:0                        未结的总分数:0                        
    结贴的百分比:100.00%               结分的百分比:100.00%                  
    无满意结贴率:0.00  %               无满意结分率:0.00  %                  
    敬礼!
      

  2.   

     return new Wrapping(x) { 
          public int value() {
            return super.value() * 47;
          }
        }; 
    这里Wrapping(x)就是调用了父类的构造方法.
      

  3.   


    return new Wrapping(x) { //这里直接调用父类的带参数的构造方法,初始化父类中定义的private int i;
          public int value() {
            return super.value() * 47;//得到父类中的i,并乘以47,返回结果.
          }
        }; 匿名内部类无法定义构造方法,原因上面已经说过.
      

  4.   

    2楼正确,匿名内部类比较特殊,有些东西不能当常规类去理解,常规的类构造方法是不能从超类继承下来的,匿名内部类编译器作了些特殊处理,所以如2楼所说 Wrapping(x) 就是调用了父类的构造方法。
      

  5.   

    想来想去还是想搞清楚!!
      我觉得Tinking in Java 这书在这节中,又明显的误导之嫌,为什么这么说呢,看了代码1、代码2后给人感觉是匿名类其实就是创建一个普通的类,只不过这个类没有名字。
      但在其他地方我看到,所谓的匿名类就是为给定的类进行扩展,为接口进行具体的实现,这多清楚啊,干嘛非要给你脑子里绕个圈子啊,而且在代码1、2后还写了段话来加深这错误的理解。书上原话“ 创建一个继承自 Contents 的匿名类的对象。通过new表达式返回的引用被自动向上转型为对 Contents 的引用。”
      尤其遇到了代码3后,更加搞不清楚了,从代码1、2中看出,首先是定义这个匿名类,然后是生成这个匿名类的对象,最后再进行向上转型,如果没有构造函数,那么还是可以理解的,但是在有构造函数的情况就根本没办法理解了。除非想成匿名类有一个匿名的构造函数,而这个特殊的构造函数将通过特殊的方式将调用基类的构造函数,将参数传进去,而且只要基类的构造函数形参和传进去的参数类型一致,那么JVM就能够自动完成这个操作。(自己疯想出来的,仅仅只为了自己逻辑上能够想通)。
      但如果按照为给定的类进行扩展,为接口进行具体的实现,那不就容易理解的多了嘛,所以我也搞不清楚了,这鸟匿名类究竟是怎么一回事啊,前面想着想着把类型转换给想糊涂了,真是光火啊~!!!
      

  6.   

    不是拿Thinking in Java作为入门书吧?
      

  7.   

    没有~之前看过其他基础书的,不过仅仅是一部分。并没有把所有知识点都看过,所以不是从Thinking in java入手的
      

  8.   


    换书吧,《Thinking in Java》不太适合初学者学语法,看《Core Java》(Java核心技术)吧。
      

  9.   

    呵呵~Thinking in java其实还是能看看的啦,因为之前已经看过其他一些书的,虽然没有看到很深的部分,但是总的来说还是有点基础的。Java核心技术其实反倒省略了很多基础的东西,所以我不太喜欢这书