Java泛型,对象和通配符差异&澄清

时间:2016-01-25 13:17:43

标签: java object generics wildcard type-erasure

我希望理解这个概念:

  1. T object - generic,将被删除为实际类型。
  2. ?对象 - 将被删除为什么?
  3. Object object;
  4. T?Object之间有什么区别?

    我很容易理解#1,但是:

    Object var;
    ? var;
    

    两者有什么区别?我已经读过,我无法明确使用?,例如T或任何其他变量,?与对象有关,而不是类型。
    但实际原因是什么?为什么我不能只写List个对象(List<Object>)而不是List个通配符(List<?>)?因为我不知道两种情况下的物体类型 另外,我想知道?的删除是什么?

1 个答案:

答案 0 :(得分:9)

我将列出T?之间的主要区别:

  • 基本:T是一个类型参数,?是通配符。

  • 含义:T在定义泛型类时用作类型参数。在实例化泛型类时,T将被具体类型替换。 另一方面,当我们想要引用 unknown 类型参数时,我们使用?

  • 定义的位置:如果定义了泛型方法,则需要在类的顶部声明T或方法。您可以在任何地方使用?
  • 映射:T的每次使用都映射到相同的类型(在同一个类中)。 ?的每次使用都可以映射到不同的类型。
  • 对象实例化:您可以使用通用参数T创建对象,如new ArrayList<T>()。您无法使用?实例化对象,只能实现指针
  • 集合更新:您可以将对象添加到T类型的集合中。您无法将对象添加到类型?的集合中(因为您不知道其类型)。

  • 类型删除:使用泛型,类型擦除适用于泛型的 use 。使用泛型时,它们将转换为编译时检查和执行时转换。因此,如果您有以下代码:List<String> myList = new ArrayList<String>();然后您希望添加到列表中,那么您需要执行myList.add("Hello World");,然后您希望通过执行{get添加刚刚添加的项目String myString = myList.get(0); 1}}然后编译器会将您的代码编译为List myList = new ArrayList();String myString = (String) myList.get(0);(由于显而易见的原因,add保持不变)。
    所以基本上,在执行时,无法发现列表对象T本质上是String(该信息已消失)。

    现在,对于通配符来说,故事是不同的。通配符(?)由Object替换(因为它是无界)。这不是很有用。在构建时,编译器将检查您调用Object的行为。如果您有类似? extends Foo的内容,那么?将被其绑定Foo替换(在构建时,编译器将检查您是否只传递Foo或其任何一个子类型(从Foo继承的类型)作为参数)。

?Object之间的差异&amp; TObject您可以分别阅读herehere