使用泛型返回列表的接口会导致警告
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>
.
这些更改使警告消失似乎很奇怪:
在 buildMessage
的参数中使用 Bag<Integer> badBag
而不是 Bag badBag
:
private static String buildMessage(Bag<Integer> badBag) {
在界面中使用Bag
代替Bag<T>
:
public interface Bag {
我期望方法 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。
为什么当我尝试编译以下代码时会出现警告?
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>
.
这些更改使警告消失似乎很奇怪:
在
buildMessage
的参数中使用Bag<Integer> badBag
而不是Bag badBag
:private static String buildMessage(Bag<Integer> badBag) {
在界面中使用
Bag
代替Bag<T>
:public interface Bag {
我期望方法 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。