我有关于泛型的这个问题。任何人都可以解释为什么选项4和6 [我知道这个选项]是正确的吗?
请考虑以下代码:
import java.util.*;
public class TestClass
{
public static void main(String[] args)
{
// put declaration here
m.put("1", new ArrayList()); //1
m.put(1, new Object()); //2
m.put(1.0, "Hello"); //3
System.out.println(m);
}
}
如何声明'm'以便上面的代码编译运行没有错误?
Map m = new TreeMap();
Map<Object, Object> m = new TreeMap<Object, Object>();
Map<Object, ?> map = new LinkedHashMap<Object, Object>();
Map<Object, ? super ArrayList> m = new LinkedHashMap<Object, ArrayList>();
会奏效
如果行// 2和// 3被注释掉了。 Map<Object, ? super ArrayList> m = new LinkedHashMap<Object, ArrayList>();
将起作用。Map m = new HashMap();
答案 0 :(得分:2)
要了解此问题,请查看您在此处使用的Map#put
方法的通用签名。它声明:
V put(K key, V value)
这意味着您可以将可分配给Map
的密钥类型K
的泛型类型的密钥和可分配给{{1}的泛型类型的值}的值类型Map
。对于放入地图的所有键值对,必须如此。从您的代码中,您将以下键放入地图中:
V
String
"1"
字面Integer
的{{1}}。int
文字1
的{{1}}。这些对象的唯一常见超类型是Double
类型,double
是1.0
所需的类型,以便将所有这些对象用作键。
对于您拥有的值:
Object
个实例。K
实例ArrayList
Object
醇>
同样,这些对象的唯一常见超类型是String
类型,"Hello"
是Object
所需的类型,以便允许所有这些对象用作地图值。
因此,只允许使用具有通用签名V
的{{1}}个实例。您选择的Map
界面的实现取决于您,只要它对地图的变量类型assignable,即您可以使用Map<Object, Object>
,{{1或者Map
,因为它们只是存储数据的方式不同。对于变量的泛型类型,请注意,对您的变量使用通配符LinkedHashMap
或TreeMap
将导致您无法再将值放入地图中。我链接的教程解释了原因。
对于您使用的非通用签名类型,它们的行为与HashMap
s类似,具有通用签名?
。但是,这些原始类型应not longer be used after the introduction of Java 5。
有了这些信息,您可以自己回答您的(考试)问题。
答案 1 :(得分:1)
第4行对于第1行是正确的,因为“1”是具有Object超类的String,? super ArrayList
表示您可以使用ArrayList或ArrayList的任何超类。
数字6是正确的,因为您使用的是无类型(原始)地图,因此它类似于:
Map<Object, Object> m = new HashMap<Object, Object>();
要存储此类值,您可以使用Map,但这不是一个非常好的选择。你根本不应该使用无类型的集合。想一想如何改变你的设计,不要使用这样的地图。