Java中未绑定通配符泛型的用法和要点是什么? [英] What is the use and point of unbound wildcards generics in Java?

查看:85
本文介绍了Java中未绑定通配符泛型的用法和要点是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白什么是使用未绑定的通配符泛型。绑定的通配符泛型与上边界<? extends Animal> 非常合理,因为使用多态我可以使用该类型或集合。但是,有什么样的泛型可以是任何类型的?它是否不符合泛型的目的?编译器没有发现任何冲突,并且在类型擦除之后,它就像没有使用泛型一样。

解决方案

未绑定类型可以



<$>一个简单的例子就是这样:



<$ (对象项目:东西){
System.out.println(item);} $ {
> public void printStuff(Iterable<?> stuff)




$ b $ PrintStream.println( )可以处理所有的引用类型(通过调用 toString()),我们不关心实际内容 Iterable 是。



调用者可以传入 List< Number> 或者 Set< String> 或者集合<?扩展MySpecificObject< SomeType>>



另外请注意,不使用泛型(使用原始类型调用)不同的效果:它使编译器处理整个对象,就好像泛型完全不存在一样。换句话说:不仅仅是该类的类型参数被忽略,而且还包括方法中的所有泛型类型参数。



另一个重要的区别是你不能添加任何(非 null )值添加到 Collection <?>< / code>,但可以添加所有对象到原始类型集合



这不会编译,因为 c 是一个未知类型(=通配符),所以我们不能提供一个保证可赋值的值(除了 null ,可分配给所有参考类型)。

 收集和LT;?> c = new ArrayList< String>(); 
c.add(foo); //编译错误

如果您将type参数取出(即使用原始类型)可以添加任何东西到集合中:

  Collection c = new ArrayList< String>(); 
c.add(foo);
c.add(new Integer(300));
c.add(new Object());

请注意,编译器会警告您不要使用原始类型,特别是出于这个原因:它删除了与泛型相关的任何类型检查。


I don't understand what is the use of unbound wildcards generics. Bound wildcards generics with upper boundary <? extends Animal> makes perfect sense, because using polymorphism I can work with that type or collection. But what is the point of having generics that can be of any type? Doesn't it defeat the purpose of generics? Compiler doesn't find any conflict and after type erasure it would be like no generics was used.

解决方案

An unbound type can be useful when your method doesn't really care about the actual type.

A primitive example would be this:

public void printStuff(Iterable<?> stuff) {
  for (Object item : stuff) {
    System.out.println(item);
  }
}

Since PrintStream.println() can handle all reference types (by calling toString()), we don't care what the actual content of that Iterable is.

And the caller can pass in a List<Number> or a Set<String> or a Collection<? extends MySpecificObject<SomeType>>.

Also note that not using generics (which is called using a raw type) at all has a quite different effect: it makes the compiler handle the entire object as if generics don't exist at all. In other words: not just the type parameter of the class is ignored, but also all generic type parameters on methods.

Another important distinctions is that you can't add any (non-null) value to a Collection<?>, but can add all objects to the raw type Collection:

This won't compile, because the type parameter of c is an unknown type (= the wildcard ?), so we can't provide a value that is guaranteed to be assignable to that (except for null, which is assignable to all reference types).

Collection<?> c = new ArrayList<String>();
c.add("foo");    // compilation error

If you leave the type parameter out (i.e. use a raw type), then you can add anything to the collection:

Collection c = new ArrayList<String>();
c.add("foo");
c.add(new Integer(300));
c.add(new Object());

Note that the compiler will warn you not to use a raw type, specifically for this reason: it removes any type checks related to generics.

这篇关于Java中未绑定通配符泛型的用法和要点是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆