使用泛型返回列表的接口会导致警告

Interface using generics returning list causes warning

为什么当我尝试编译以下代码时会出现警告?

Bag.java:

import java.util.List;

public interface Bag<T> {
  public List<String> getOwnerNames();
}

BagException.java:

public class BagException extends Exception {

    public BagException(Bag badBag) {
        super(buildMessage(badBag));
    }

    private static String buildMessage(Bag badBag) {

        //   BagException.java:10: warning: [unchecked] unchecked conversion
        //                   List<String> owners = badBag.getOwnerNames();
        //                                                             ^
        //     required: List<String>
        //     found:    List
        List<String> owners = badBag.getOwnerNames();

        return "Something went wrong with the bag of " + String.join(", ", owners);
    }

}

List<String> owners = badBag.getOwnerNames() in buildMessage 导致警告,即使该方法声明为 return List<String>.

这些更改使警告消失似乎很奇怪:

我期望方法 getOwnerNames 独立于 Bag 的类型 T。如果您能回答以下问题之一,将会很有帮助:

What can I do about it other than suppressing it?

尝试:

public BagException(Bag<?> badBag) {
    super(buildMessage(badBag));
}

private static String buildMessage(Bag<?> badBag) {

您通过声明 Bag 而没有为 class 的类型参数声明参数,从而在您的程序中使用了所谓的 raw type。 Java 编译器 javac 将原始类型视为不包含通用类型信息。这涉及作为原始类型一部分的任何泛型类型,甚至是不包含原始类型的类型变量的类型。 (在您的情况下,List<String> 被视为原始 List。)

因此,原始引用 Bag 中的所有泛型类型都被视为擦除。您还可以观察到

String value = badBag.getOwnerNames().get(0);

不会编译为原始 Bag returns 原始 List 而不是 List<String>。您收到的警告解决了这样一个事实,即您将这样一个原始列表分配给一个通用的 List<String>,这会导致 heap pollution