java - 在方法参数中使用通配符

标签 java generics collections wildcard

我声明了一个方法,其参数是 Number 的子类型如下所示:

public static void organizeData(java.util.List<? extends Number> c) {
    //operation on the list
}

我可以将任何非参数化列表作为参数传递。那么使用通配符 <? extends Number> 有什么意义呢? ?

List newList = new LinkedList<>();
ClassName.organizeData(newList);

为什么我得到类型为 Object 的元素来自 c ?而不是 Number 类型?有没有办法只允许一个类型的子类型作为参数传递,而不是也允许非参数化参数?

最佳答案

你在这里问了三个问题,我会分别回答。顺便说一句,您会发现阅读 Java Generics FAQ - considered by many to be the canonical reference on the subject 很有值(value):

  1. 那么使用通配符 <? extends Number> 有什么意义呢? ?

参数化参数是Number的子类时需要使用通配符,比如说,Integer .例如:

import java.util.LinkedList;
import java.util.List;

public class NumberTest {
    public static void main(String... args) {
        List<Integer> newList = new LinkedList<Integer>();
        organizeData(newList); // This works!
        anotherMethod(newList); // Doesn't compile
    }

    private static void organizeData(List<? extends Number> list) {

    }

    private static void anotherMethod(List<Number> list) {

    }
}

第二个方法调用失败并出现编译错误:

NumberTest.java:9: error: method anotherMethod in class NumberTest cannot be applied to given types;
                        anotherMethod(newList); // Doesn't compile
                        ^
  required: List<Number>
  found: List<Integer>
  reason: actual argument List<Integer> cannot be converted to List<Number> by method invocation conversion
1 error

  1. 为什么我得到类型为 Object 的元素来自 c ?而不是 Number 类型?

你得到 Object 类型的原因在你的第二种情况下是因为 you are using the Raw Type.如果出于这个原因可以避免使用原始类型,则永远不要使用它 - 您将失去编译器类型检查的所有优势。


  1. 有没有办法只允许一个类型的子类型作为参数传递,而不是也允许非参数化参数?

你无法阻止 Heap Pollution按照您描述的方式,因为有人总是可以转换为 Raw 类型,然后再转换为任何需要的类型。泛型仅在编译时构造,并且 are ultimately erased after compilation.这就是为什么只能通过注释来抑制 Unchecked Type Conversion 警告。

关于java - 在方法参数中使用通配符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26258197/

相关文章:

java - MySQL 8.0.11 抛出 CLIENT_PLUGIN_AUTH is required

Java泛型,使用类层次结构时如何避免未经检查的分配警告?

C# 泛型——基于类型特征的重载

java - 从文件读取时,它会将一个项目两次添加到组合框中

java - cmd win7 上的命令 'notepad' 仅适用于 system32?

java - 为什么 Java 中不是默认启用所有密码套件?

generics - 通用特征和生命周期的问题

java - 使用indexOf,但使用列表中包含的类的成员

java - Java Collection 中的同步是什么?

java - 异步请求不适用于 Tomcat 7/Terracotta 3.6