带钻石操作员的通配符 [英] Wildcards with diamond operator

查看:141
本文介绍了带钻石操作员的通配符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我正在尝试这样做:

  List<?> unknownList = new ArrayList<>(); 

然后代码编译并运行正常,但的类型 ArrayList 已创建?



并且在此行之后,如果我这样做:

  unknownList.add(str); //编译错误

它给编译错误:

 错误:找不到适用于add(String)的方法
unList.add(str);

方法List.add(int,CAP#1)不适用
(实际和正式参数列表长度不同)
方法List.add(CAP#1)不适用
(实际参数String不能通过方法调用转换转换为CAP#1)
方法Collection.add(CAP#1)不适用
(实参无法转换通过方法调用转换到CAP#1)
其中CAP#1是新鲜的类型变量:
CAP#1从捕获?

这个错误是什么,使用菱形运算符和通配符是否好?如果是,那么WHERE ???

解决方案


创建?


类型参数只是在编译时应用的约束,但 type erasure 通过擦除来替换所有出现的类型参数(在你的情况下,对象)。因此,如果您询问运行时类型,它将是一个简单的 ArrayList (您可以认为它是 ArrayList< Object> code>)。


使用菱形运算符和通配符是否合适?如果是,那么
WHERE ???


没有。当您使用菱形运算符创建泛型类的新对象时,这意味着您不希望在类型参数上是多余的。它不应与通配符声明的变量相结合,该变量没有具体的类型参数。总而言之,你绝不应该写:

 列表<?> unknownList = new ArrayList<>(); 

您应该只使用通配符<?> 类型真的没关系。特别是,如果您想将项目添加到列表中,请勿使用通配符,因为添加项目意味着您知道要添加的类型



它很可能被用作方法的参数,例如,当您不访问该值并仅传递该列表,或者您只是以普通对象的形式访问列表项时。

If I am trying to do something like this :

List<?> unknownList = new ArrayList<>();

then the code compiles and runs fine, but of which type the ArrayList has created?

and after this line, If I have done like this :

        unknownList.add("str"); //compilation error

It gives compilation error :

error: no suitable method found for add(String)
        unList.add("str");
              ^
method List.add(int,CAP#1) is not applicable
  (actual and formal argument lists differ in length)
method List.add(CAP#1) is not applicable
  (actual argument String cannot be converted to CAP#1 by method invocation conversion)
method Collection.add(CAP#1) is not applicable
  (actual argument String cannot be converted to CAP#1 by method invocation conversion)
where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ?

What is this error, and is it good to use the diamond-operator with wildcards? If YES then WHERE???

解决方案

but of which type was the ArrayList created?

Type parameters are just constraints applied at compile time, but type erasure replaces all occurrences of the type parameter by its erasure (in your case, Object). So, if you're asking about the runtime type, it will be a plain ArrayList (which you can think of as ArrayList<Object>).

is it good to use the diamond-operator with wildcards? If YES then WHERE???

No. When you use a diamond operator to create a new object of a generic class, it means you don't want to be redundant on the type parameter. It should not be combined with a wildcard-declared variable, which does not have a concrete type parameter.

To summarize, you should never write:

List<?> unknownList = new ArrayList<>();

You should only use the wild card <?> when the type really does not matter. In particular, don't use the wild card if you want to add items to the list, because adding items means you know what type to add.

It is likely to be used as a parameter of a method for instance, when you don't access the value and just pass the list on, or where you just access the list items as plain Objects.

这篇关于带钻石操作员的通配符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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