我有关于泛型的问题:
Map<? super String, ? super String> mappa1 = new HashMap<Object,Object>();
使用super可以为HashMap<Object,Object>
实例化<? super String>
。
但是,您只能添加扩展String的对象(在本例中只是String本身)。
他们为什么不禁止编译错误以及extends
通配符。
我的意思是,如果一旦创建Map <Object, Object>
,就有可能只添加字符串..为什么不强制首先创建Map<String, String>
? (就像它发生在extends
通配符)
我再次了解super
和extends
之间关于泛型的区别。我想知道我上面提到的细节。
提前致谢。
答案 0 :(得分:5)
为简洁起见,我们使用List
代替Map
。
基本上,extends
和super
的实际含义可以定义如下:
List<? extends T>
表示“List
你可以T
来自”List<? super T>
表示“List
您可以将T
加入”现在您可以看到extends
没有什么特别之处 - extends
和super
的行为是完全对称的:
List<? extends Object> a = new ArrayList<String>(); // Valid, you can get an Object from List<String>
List<? extends String> b = new ArrayList<Object>(); // Invalid, there is no guarantee that List<Object> contains only Strings
List<? super String> a = new ArrayList<Object>(); // Valid, you can put a String into List<Object>
List<? super Object> b = new ArrayList<String>(); // Invalid, you cannot put arbitrary Object into List<String>
答案 1 :(得分:3)
我认为你因为选择了一个集合类型而被抛弃了。集合很少用作使用者,因此下限(? super X
)不会放在其元素类型上。一个更恰当的例子是谓词。
考虑<E> List<E> filter(List<? extends E> p, Predicate<? super E> p)
等方法。它将采用列表l
和谓词p
,并返回一个新列表,其中包含l
满足p
的所有元素。
您可以传递List<Integer>
和Predicate<Number>
,其满足2.5
的所有倍数。 Predicate<Number>
将成为Predicate<? super Integer>
。如果没有,则无法按如下方式调用过滤器。
List<Integer> x = filter(Arrays.asList(1,5,8,10), Predicates.multipleOf(2.5));
答案 2 :(得分:2)
Map<? super String, ? super String> mappa1 = new HashMap<Object,Object>();
由于Java Generics基于类型擦除,因此使用此行不会创建MashMap<Object,Object>
。您刚刚创建了HashMap
类的实例;在此代码行之后,类型参数会立即丢失,而所有保留的类型都是mappa1
变量的类型,甚至没有提到Object
。 new
表达式的类型与mappa1
的类型赋值兼容,因此编译器允许赋值。
通常,与new
一起使用的类型参数无关紧要,为解决此问题,Java 7引入了菱形运算符 <>
。真正重要的是mappa1
的类型,即Map<? super String, ? super String>
;就其他代码而言,这是实例化地图的类型。
答案 3 :(得分:0)
您所描述的问题不存在。
这是因为您的引用被声明为Map<? super String, ? super String>
。但是你的实际对象可以保存任何对象,因为它是HashMap<Object,Object>
Map<? super String, ? super String> mappa1 = new HashMap<Object,Object>();
map1.put("", "");
//you can put only string to map1
//but you can do this
Map map2 = map1;
map2.put(23, 234);
同样可以通过一个更好的例子来描述:
String a = "a".
a.length(); // legal.
Object b = a;
b.length() // compilation error