Java泛型,对象和通配符的区别&澄清 [英] Java generics, objects and wildcards differences & clarifications

查看:179
本文介绍了Java泛型,对象和通配符的区别&澄清的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望了解这个概念:


  1. T object - generic,将被擦除成实际的类型。

  2. object - 将被擦除成什么? > Object object;


  3. T 对象



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

      Object var; 
    ? VAR;

    两者有什么区别?我已经读过,我不能明确地使用,比如 T 或其他任何变量,与对象有关,而不是类型。

    但是实际的原因是什么?为什么我不能写一个 List 对象( List< Object> )而不是通配符的列表 List <?>< / code>)?因为我不知道这两种情况下的对象类型。

    另外,我想知道

    解决方案

    我将列出 T 和<$ c $之间的主要区别基本: T

    $ b
      c>是一个类型参数,是通配符。 >定义泛型类时使用> T 作为类型参数。当您实例化泛型类时, T 将被具体类型替换。
      另一方面,当我们想引用未知类型的参数时,我们使用

      >
    • 定义位置:您需要在类的顶部声明 T ,或者如果定义泛型方法,则需要声明方法。您可以在任何地方使用

    • 映射:每次使用 T 映射到相同的类型(在同一个类中)。每一次使用都可以映射到不同的类型。

    • 对象实例化:可以使用泛型参数 T new ArrayList< T>()。您不能通过来实例化对象,而只是指针

    • 集合更新:您可以添加对象到 T 类型的集合。您不能将对象添加到类型为的集合中(因为您不知道它的类型)。

    • p>类型擦除:使用泛型时,类型擦除适用于泛型的 use 。当使用泛型时,它们被转换为编译时检查和执行时间转换。所以如果你有这样的代码,例如: List< String> myList = new ArrayList< String>(); 然后你想添加到你的列表中,所以你可以做 myList.add(Hello World); 然后你想通过执行 String myString = myList.get(0); 获得获得 >然后编译器会将你的代码编译为 List myList = new ArrayList(); String myString =(String)myList.get(0); ( add 由于显而易见的原因保持不变)。

      所以基本上,在执行时,有 no找到 T 本质上就是 String (列表对象(信息消失))的方式


      现在通配符的故事是不同的。通配符()被替换为 Object (因为它是无界的)。这不是很有用。在编译时,编译器会检查你是否只调用 Object 的行为。如果你有类似于的东西?扩展Foo ,然后将替换为其绑定的 Foo (在构建时编译器会检查你是否只传递了 Foo 或其任何子类型(继承自 Foo )的类型作为参数)


    Object & T 对象您可以阅读 here here


    I wish to understand this concept:

    1. T object - generic, will be erased into actual type.
    2. ? object - will be erased into what?
    3. Object object;

    What are the differences between T, ? and Object?

    I can easily understand #1, but what about:

    Object var;
    ? var;
    

    What is the difference between the two? I have read that I can't use ? explicitly, like T or any other variable, and that ? is related to objects, not types.
    But what is the practical reason? Why can't I just write a List of objects (List<Object>) instead of a List of wildcards (List<?>)? As I don't know the types of objects on both cases.
    In addition, I would like to know what is the erasure for ? ?

    解决方案

    I will list the main differences between T and ?:

    • Basic: T is a type parameter and ? is a wildcard.

    • Meaning: T is used as a type parameter when defining a generic class. T will be replaced by a concrete type when you instantiate the generic class. On the other hand, we use ? when we want to refer to an unknown type argument.

    • Place of definition: You need to declare T on the top of the class, or method if you define a generic method. You can use ? everywhere.
    • Mapping: Every use of T is mapped to the same type (in the same class). Every use of ? can be mapped to a different type.
    • Object instantiation: You can create objects with the generic parameter T like new ArrayList<T>(). You cannot instantiate objects but only pointers with ?.
    • Collections updating: You can add objects to a collection of type T. You cannot add object to a collection of type ? (since you don't know its type).

    • Type erasures: With generics, type erasure applies to the use of generics. when generics are used, they are converted into compile-time checks and execution-time casts. So if you have this code for example: List<String> myList = new ArrayList<String>(); and then you wish to add to your list so you do myList.add("Hello World"); and then you want to get the item you just added by performing String myString = myList.get(0); then the compiler will compile your code to List myList = new ArrayList(); and String myString = (String) myList.get(0); (the add stays the same for obvious reasons).
      So basically, at execution time there is no way of finding out that T is essentially String for the list object (that information is gone).

      Now for wildcards the story is different. A wildcard (?) is replaced by an Object (since it's unbounded). This is not very useful. At build-time the compiler will check you are only calling Object's behaviours. If you have something like ? extends Foo, then the ? is replaced with its bound Foo (at build-time the compiler will check you are only passing Foo or any of its subtypes (types that inherit from Foo) as an argument).

    For differences between ? and Object & T and Object you may read here and here respectively.

    这篇关于Java泛型,对象和通配符的区别&amp;澄清的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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