Java菜鸟诚心请教一个关于泛型的问题
首先定义了Dog类和Cat类,再实例化,Dog dog=new Dog();Cat cat=new Cat();
然后 ,写了这句:Set set=new HashSet<Dog>();
问题来了,这时候如果写set.add(cat);不会报错,而且执行System.out.print(set);后会输出Cat类的哈希码(百度后看到有人说是哈希码,这个不影响此问题)。
这个该怎么理解呢?按照我个人的想法:在这个程序中,通过new创建的HashSet类的对象,它只能存放Dog类型的对象,但是能调用add方法增加Cat类的对象cat。我感觉说不通。
诚心请教。
------解决方案--------------------其实,这也算一个历史遗留问题,java最开始设计的时候没有支持泛型,是在后来的版本里加上的,为了兼容以前的代码,在运行的时候,这些泛型信息就被丢掉了。你贴出的代码实际上是很危险的,试想如果你执行下面的代码
Set set = new HashSet<Dog>();
set.add(new cat());
for (Object dog : set) {
Dog d = (Dog)dog;
...
}
就会报一个
ClassCastException。所以你应该这么写
Set<Dog> set = new HashSet<Dog>();
这样你再添加cat时就会报编译错误,从而快速发现解决问题。
最后顺便说一句,java的泛型实际上并不是彻底的泛型,也算是java设计的一个小败笔吧。
------解决方案--------------------java 的泛型 不是真正的泛型 只是根据祖先类Object 来实现的 也就是说 List<String> 实质上就是List<Object>
[转]JAVA的泛型只是一个语法糖,实际上在运行时还是有类型转换的过程,从JVM生成的代码来看,和传递一个Object(或者extends的类型)没什么区别。当然泛型的最大好处是编绎期的类型错误检查。
明白JAVA泛型的大致实现原理之后,看很多泛型代码都比较清晰了:)
和C++的泛型比较,C++的泛型是在编绎期实现的,为每一个类型都生成一份代码,所以C++的泛型容易让编绎后的代码出现膨胀。