我这里提一个关于匿名类的问题,主要涉及匿名类的初始化顺序。
代码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:
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类及它带参数的构造函数,但是自己却没有构造函数来调用基类的构造函数,为什么创建对象时不会编译错误。这个值究竟是通过什么样的过程来传到基类里的?
楼主【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 %
敬礼!
public int value() {
return super.value() * 47;
}
};
这里Wrapping(x)就是调用了父类的构造方法.
return new Wrapping(x) { //这里直接调用父类的带参数的构造方法,初始化父类中定义的private int i;
public int value() {
return super.value() * 47;//得到父类中的i,并乘以47,返回结果.
}
}; 匿名内部类无法定义构造方法,原因上面已经说过.
我觉得Tinking in Java 这书在这节中,又明显的误导之嫌,为什么这么说呢,看了代码1、代码2后给人感觉是匿名类其实就是创建一个普通的类,只不过这个类没有名字。
但在其他地方我看到,所谓的匿名类就是为给定的类进行扩展,为接口进行具体的实现,这多清楚啊,干嘛非要给你脑子里绕个圈子啊,而且在代码1、2后还写了段话来加深这错误的理解。书上原话“ 创建一个继承自 Contents 的匿名类的对象。通过new表达式返回的引用被自动向上转型为对 Contents 的引用。”
尤其遇到了代码3后,更加搞不清楚了,从代码1、2中看出,首先是定义这个匿名类,然后是生成这个匿名类的对象,最后再进行向上转型,如果没有构造函数,那么还是可以理解的,但是在有构造函数的情况就根本没办法理解了。除非想成匿名类有一个匿名的构造函数,而这个特殊的构造函数将通过特殊的方式将调用基类的构造函数,将参数传进去,而且只要基类的构造函数形参和传进去的参数类型一致,那么JVM就能够自动完成这个操作。(自己疯想出来的,仅仅只为了自己逻辑上能够想通)。
但如果按照为给定的类进行扩展,为接口进行具体的实现,那不就容易理解的多了嘛,所以我也搞不清楚了,这鸟匿名类究竟是怎么一回事啊,前面想着想着把类型转换给想糊涂了,真是光火啊~!!!
换书吧,《Thinking in Java》不太适合初学者学语法,看《Core Java》(Java核心技术)吧。