为什么Java中的HashMap<K, V>的get函数是get(Object key),而不是get(K key)?

帮别人的代码改bug,发现有一大堆bug是由get或者remove传递进去的参数类型不匹配而造成的。

比如:

		Map<Short, String> m = new HashMap();

		m.put(new Short((short) 2), "2222");
		System.out.println(m.get(2));

上面的代码输出是null。

一般人很难发现传递进去的int和Short类型不匹配,而且IDE,编译器也没有提示。当然通过一些分析工具可以检查出来。

真的感到很困惑,Java中的容器的一些函数,参数都是Object类型,如HashMap中的get,remove函数,Set中的contains函数。

为什么不明确它们的类型?这样编译器可以检查出类型不匹配的错误。

Google之,google的一个工程师给出了答案:http://smallwig.blogspot.com/2007/12/why-does-setcontains-take-object-not-e.html

为了简单起见,以Set容器为例:

定义一个简单的S,只有一个简单的contains函数:

	class S<K>{
		public void contains(K k){
			System.out.println("S<K>,contains(K k)");
		}
	}

假如我们有个函数,想要处理Foo类的集合:

	public void doSomeReading(S<Foo> foos) { 

	}

要是我们想能同时处理Foo类的子类(如SubFoo)的集合,那应该这样定义:

	public void doSomeReading(S<? extends Foo> foos) { 

	}

一切看起来很好,但是如果我们把代码都合起来,就会发现悲剧了:

	class S<K>{
		public void contains(K k){
			System.out.println("S<K>,contains(K k)");
		}
	}
	class Foo{
	}

	class SubFoo extends Foo{
	}

	public void doSomeReading(S<? extends Foo> foos) {
		Foo f = new Foo();
		SubFoo subFoo = new SubFoo();
		foos.contains(f); //这里eclipse会提示出错,这里只有填null时才不会报错
		foos.contains(subFoo); //同样错误
		foos.contains(null);
	}

这时编译器不干了,它表示不能工作了。

原来在S<K>类的定义中,我们明确contains(K  k)函数只能接受一个明确类型的参数。

但是在doSomeReading函数中,编译器无法确定到底是什么类型,它是Foo类型,还是SubFoo类型,还是SubSubFoo类型?

编译器无从得知,所以它只允许null类型的参数。

===========================================================

对于这个解析,话说还是有点郁闷。

也有另外的解析,认为和equals函数有关系。不过感觉不大靠谱,这个只能说是一些另类的应用。

http://stackoverflow.com/questions/857420/what-are-the-reasons-why-map-getobject-key-is-not-fully-generic

时间: 2024-11-01 20:17:06

为什么Java中的HashMap&lt;K, V&gt;的get函数是get(Object key),而不是get(K key)?的相关文章

Java中的HashMap浅析

在Java的集合框架中,HashSet,HashMap是用的比较多的一种,顺序结构的ArrayList.LinkedList这种也比较多,而像那几个线程同步的容器就用的比较少,像Vector和HashTable,因为这两个线程同步的容器已经不被JDK推荐使用了,这是个比较老式的线程安全的容器,JDK比较推荐的是采用Collections里面的关于线程同步的方法. 问题来源: 1.为什么要有HashMap? <Thinking In Java>里面有一个自己采用二维数组实现的保存key-valu

深入理解Java中的HashMap的实现机制_java

如果任何人让我描述一下HashMap的工作机制的话,我就简单的回答:"基于Hash的规则".这句话非常简单,但是要理解这句话之前,首先我们得了解什么是哈希,不是么? 什么是哈希 哈希简单的说就是对变量/对象的属性应用某种算法后得到的一个唯一的串,用这个串来确定变量/对象的唯一性.一个正确的哈希函数必须遵守这个准则. 当哈希函数应用在相同的对象或者equal的对象的时候,每次执行都应该返回相同的值.换句话说,两个相等的对象应该有相同的hashcode. 注:所有Java对象都从Objec

Java中对HashMap的深度分析

在Java的世界里,无论类还是各种数据,其结构的处理是整个程序的逻辑以及性能的关键.由于本人接触了一个有关性能与逻辑同时并存的问题,于是就开始研究这方面的问题.找遍了大大小小的论坛,也把<Java 虚拟机规范>,<apress,.java.collections.(2001),.bm.ocr.6.0.shareconnector>,和<Thinking in Java>翻了也找不到很好的答案,于是一气之下把JDK的 src 解压出来研究,扩然开朗,遂写此文,跟大家分享感

Java中对HashMap的深度分析与比较

比较 在Java的世界里,无论类还是各种数据,其结构的处理是整个程序的逻辑以及性能的关键.由于本人接触了一个有关性能与逻辑同时并存的问题,于是就开始研究这方面的问题.找遍了大大小小的论坛,也把<Java 虚拟机规范>,<apress,.java.collections.(2001),.bm.ocr.6.0.shareconnector>,和<Thinking in Java>翻了也找不到很好的答案,于是一气之下把JDK的 src 解压出来研究,扩然开朗,遂写此文,跟大家

Java中对HashMap的深度分析_JSP编程

在Java的世界里,无论类还是各种数据,其结构的处理是整个程序的逻辑以及性能的关键.由于本人接触了一个有关性能与逻辑同时并存的问题,于是就开始研究这方面的问题.找遍了大大小小的论坛,也把<Java 虚拟机规范>,<apress,.java.collections.(2001),.bm.ocr.6.0.shareconnector>,和<Thinking in Java>翻了也找不到很好的答案,于是一气之下把JDK的 src 解压出来研究,扩然开朗,遂写此文,跟大家分享感

对象-java中如何理解这个数据类型 List&amp;amp;lt;Map&amp;amp;lt;String, Object&amp;amp;gt;&amp;amp;gt;

问题描述 java中如何理解这个数据类型 List<Map<String, Object>> 话说我现在只能理解int void string long 等等基本数据类型呢 List> 是一个引用数据类型吗 应该如何理解呢 解决方案 这个变量本质是一个List类型,指定了List中的元素类型是Map ,这个是泛型,但是编译后会泛型擦除还原成List. 解决方案二: 1) 第一层,一个列表,可以用 类似于 list[i] 的方式来访问. 2) 第二层,这个列表中的每个元素都是一

Java中的HashMap和ConcurrentHashMap的并发性能测试

先看看代码吧,模拟1000个并发,每个测试1000次操作,循环测试10轮.分别测试Put和Get操作import java.util.Collections; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 测试HashMap和ConcurrentHashMap的并发性能差别. * * @

java中对象多态时成员变量,普通成员函数及静态成员函数的调用情况

/* 样例1:   class Parent{      int num = 3;   }     class Child extends Parent{      int num = 4;   } */   /* 样例2: class Parent{   }   class Child extends Parent{     int num = 4; } */   /* 样例3: class Parent{     void show(){         System.out.println

hashmap-&amp;amp;lt;K,V&amp;amp;gt;HashMap&amp;amp;lt;K,V&amp;amp;gt;,后面的(k,v)是泛型,前面的是什么?跪求!

问题描述 <K,V>HashMap<K,V>,后面的(k,v)是泛型,前面的是什么?跪求! 这是源代码: public static < K,V >HashMap < K,V> newInstance(){ return new HashMap < K, V > (); } < K,V >HashMap< K,V>是一个返回类型,那么如题,前面的< K,V>是什么意思? 解决方案 返回这个类型 函数的返回值类型