精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2004-05-24
逆变:contravariant,是指字类型同名方法,接受的参数包含父类型所能接受的参数。 参见: http://icecloud.51.net/nemo/archives/000098.html http://icecloud.51.net/nemo/archives/000071.html 看如下代码: public class AncestorClass { } public class ParentClass extends AncestorClass { int set(ParentClass p);{ System.out.println("set Parent");; return 1; } } public class ChildClass extends ParentClass { int set(AncestorClass c);{ System.out.println("set Ancestor");; return 2; } public static void main(String[] agrs);{ ChildClass s = new ChildClass();; System.out.println(s.set(new ChildClass();););; // 1 System.out.println(s.set(new ParentClass();););; // 2 System.out.println(s.set(new AncestorClass();););; //3 } } 执行ChildClass 理论上,1,2应该是出现编译错误。在Eclipse2.1,M8,Jbuilder中测试都是出错。 而在EclipseM9中,居然编译和执行通过了。把class的类型选为1.3,就和上面的版本一样报错。而用JDK1.4编译也能够通过!! 结果分别是: set Parent 1 set Parent 1 set Ancestor 2 这就很令人困惑了。是1.4修改了类型逆变的规则? 同样是1.4,为什么M8编译不过? 难道EclipseM9之前的版本都自带了词法分析器来进行语法检查,而这次升级了编译器? 实在是郁闷。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2004-05-24
我先后在同样的文件路径里装了两个不同的jdk,并在eclipse里指定该文件为jre路径:
一个是1.4.2_03-b02 一个是1.4.2_04-b05 结果: dos下,前一个无法编译,后一个输出同贴主 eclipse2.1.3 都是无法编译 eclipse3.0m9 都可以编译,输出同贴主 可见 1.eclipse编译并不是通过jdk这么简单,具体还请高人指点 2.贴主说"类型逆变规则的修改"确实在jdk里发生了,不过修改后不是更清楚?在调用方法时先按继承体系从下往上寻找有相同类型的args的方法,找不到则upcast,再寻找,... |
|
返回顶楼 | |
发表时间:2004-05-24
是啊,修改是好事,但是问题是兼容性。
如果同样是1.4.2的不同版本都不一样 那这样的代码适应范围就太小了阿 |
|
返回顶楼 | |
发表时间:2004-05-24
public class Overwrite { public static void main(String[] agrs); { ChildClass s = new ChildClass();; //right System.out.println(s.set(new AncestorClass();, new ChildClass();););; //wrong //System.out.println(s.set(new ChildClass();, new ParentClass();););; } } class AncestorClass { } class ParentClass extends AncestorClass { int set(AncestorClass c, ParentClass d); { return 1; } } class ChildClass extends ParentClass { int set(ParentClass d, AncestorClass c); { return 2; } } 为什么 //right System.out.println(s.set(new AncestorClass();, new ChildClass();););; //wrong System.out.println(s.set(new ChildClass();, new ParentClass();););; 一个是right,一个是wrong? 去掉System.out.println(s.set(new ChildClass(), new ParentClass())); 的注释,强行执行 m9报致命错误: java.lang.Error: Unresolved compilation problem: The method set(ParentClass, AncestorClass) is ambiguous for the type ChildClass at japp.sample.syntax.Overwrite.main(Overwrite.java:17) Exception in thread "main" |
|
返回顶楼 | |
发表时间:2004-05-25
不明白 @@
|
|
返回顶楼 | |
发表时间:2004-05-25
System.out.println(s.set(new ChildClass();, new ParentClass();););; 这一句,按照规则,上面两个 set 方法: class ParentClass extends AncestorClass { int set(AncestorClass c, ParentClass d); { return 1; } } class ChildClass extends ParentClass { int set(ParentClass d, AncestorClass c); { return 2; } } 似乎都符合,所以编译器感觉困惑了。 这样的代码还是尽量少写,想办法绕过它。因为写这样代码的必要性不大,而且还影响了程序的可读性,我认为是代码的臭味之一。 |
|
返回顶楼 | |
发表时间:2004-05-25
dlee说的有理! 程序要方便阅读,干嘛写那么复杂有歧义的。 受教了~
|
|
返回顶楼 | |
发表时间:2004-05-25
C++爱好者一般喜欢研究这种机巧的东西
|
|
返回顶楼 | |
发表时间:2004-05-26
这个和Eclipse,Jb没什么关系把,
|
|
返回顶楼 | |
发表时间:2004-05-27
不知道大家是在什么情况下才有的呢??
我试过用 1.4.0_01的JDK和eclipse 2.1.1,没有这个问题呀!! [补:原来少继承了一层] .. |
|
返回顶楼 | |