Java5 增加的泛型语法,使类型模板的应用得到了提升,但它的运行期擦拭的做法(为向前兼容),令人诟病,
使得一个Map集合,通过反射拿到的集合元素的泛型类型,不是实际使用类型,而是K和V(字节码编译期保留)。
另一个有争议的地方是:
泛型违反了里氏代换原则(Liskov's Substitution Principle),即:子类应该在任何地方都能替换父类。
假设一个函数:
void xxx(List<Object> list);
调用:
List<String> list = ...
xxx(list); // 编译出错
当然,你可以使用下面的变通方式就不会出错:
void xxx(List<? extends Object> list);
主要的问题在于:List<String> 是不是 List<Object> 的子类?
我觉得应该是,至少“人”认为是,面象对象的主要目的是什么?就是让人理解程序,而不是机器。
而官方给出的答案却是:List<String> 不是 List<Object> 的子类
Java泛型规格说明书 写道
让我们测试一下我们对泛型的理解。下面的代码片断合法么?
List<String> ls = new ArrayList<String>(); //1
List<Object> lo = ls; //2
第1行当然合法,但是这个问题的狡猾之处在于第2行。
这产生一个问题:
一个String的List是一个Object的List么?大多数人的直觉是回答:“当然!”。
好,在看下面的几行:
lo.add(new Object()); // 3
String s = ls.get(0); // 4: 试图把Object赋值给String
这里,我们使用lo指向ls。我们通过lo来访问ls,一个String的list。我们可以插入任意对象进去。结果是ls中保存的不再是String。当我们试图从中取出元素的时候,会得到意外的结果。
java编译器当然会阻止这种情况的发生。第2行会导致一个编译错误。
总之,如果Foo是Bar的一个子类型(子类或者子接口),而G是某种泛型声明,那么G<Foo>是G<Bar>的子类型并不成立!!
这可能是你学习泛型中最难理解的部分,因为它和你的直觉相反。
这种直觉的问题在于它假定这个集合不改变。我们的直觉认为这些东西都不可改变。
举例来说,如果一个交通部(DMV)提供一个驾驶员里表给人口普查局,这似乎很合理。我们想,一个List<Driver>是一个List<Person>,假定Driver是Person的子类型。实际上,我们传递的是一个驾驶员注册的拷贝。然而,人口普查局可能往驾驶员list中加入其他人,这破坏了交通部的记录。
为了处理这种情况,考虑一些更灵活的泛型类型很有用。到现在为止我们看到的规则限制比较大。
上面所描述的语义限制根本没有意义,如果想限制用户在List<String>中加入Object, 因为泛型的运行期擦拭,等于白做。
因为想做这个语义上的限制,而牺牲直观的理解非常不值,加一个"?"问号作为替代方案,只会使泛型更复杂,使用也不方便。
用户必须在"?"问号与"Object"间绕来绕去,烦也不烦,或许可以问:"?"问号等于"Object"吗?呵呵,maybe.
分享到:
相关推荐
Java泛型编程指南.pdf 此文章译自SUN的泛型编程指南
Java Generics and Collections 英文版,详细描述java 泛型技术
java 泛型接口示例 java 泛型接口示例 java 泛型接口示例
这是一个使用JAVA实现的泛型编程,分为两部分,第一部分创建泛型类,并实例化泛型对象,得出相加结果。 第二部分用户自行输入0--4,选择要进行的加减乘除运算或退出,再输入要进行运算的两个数,并返回运算结果及...
java 泛型类的类型识别示例 java 泛型类的类型识别示例 java 泛型类的类型识别示例
java 泛型方法使用示例 java 泛型方法使用示例 java 泛型方法使用示例
1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1....
java泛型技术之发展,学习JAVA 泛型的不错东东
java 泛型 java 泛型 java 泛型 java 泛型
4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip...
主要介绍了Java泛型的用法及T.class的获取过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
深入理解java泛型,包括类名泛型的定义,方法泛型定义,泛型的返回
谈谈关于Microsoft Visual Studio 2008中C#和java泛型的区别
java,学习java泛型,java培训之泛型.pptxjava培训之泛型.pptxjava培训之泛型.pptxjava培训之泛型.pptx
很好的Java泛型的总结,看完之后你一定会知道java泛型的底层机制,你一定会学会Java泛型!
关于java基础的泛型的练习
java泛型详解.pdf
思维导图之Java泛型详解
Java泛型使用详细分析.pdf