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

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

问题描述

我不明白未绑定通配符泛型的用途是什么.上边界 非常有意义,因为使用多态性我可以处理该类型或集合.但是拥有可以是任何类型的泛型有什么意义呢?它不会违背泛型的目的吗?编译器没有发现任何冲突,类型擦除后就像没有使用泛型一样.

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);
  }
}

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

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

并且调用者可以传入一个List或一个Set或一个Collection>.

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.

另一个重要的区别是您不能向 Collection 添加任何(非null)值,但可以添加 all 对象到原始类型 Collection:

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:

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

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天全站免登陆