[英]Java Generics and unchecked cast
我正在努力解决Java中泛型的这个方面。 希望有人可以帮我看看方法。
我有一个包含对象列表的类。 这段代码有效,但我想摆脱演员表。 我怎样才能使这更通用?
public class Executor {
List<BaseRequest<BaseObj>> mRequests = new ArrayList<BaseRequest<BaseObj>>();
public Executor() {
}
@SuppressWarnings("unchecked")
public <T extends BaseObj> void add(final BaseRequest<T> request) {
mRequests.add((BaseRequest<BaseObj>) request);
}
public void execute() {
for (BaseRequest<BaseObj> r : mRequests) {
// DO SOMETHING WITH r
}
}
}
在发布的代码片段中,您需要进行BaseRequest<? extends BaseObj>
因为BaseRequest<? extends BaseObj>
BaseRequest<? extends BaseObj>
不是BaseRequest<BaseObj>
的子类型,并且由于类型擦除而无法在运行时检查BaseRequest<BaseObj>
,这就是编译器警告您的原因。 但是如果你改变了mRequests
的声明:
public class Executor {
List<BaseRequest<? extends BaseObj>> mRequests = new ArrayList<>();
public Executor() {
}
public <T extends BaseObj> void add(final BaseRequest<T> request) {
mRequests.add(request);
}
public void execute() {
for (BaseRequest<? extends BaseObj> r : mRequests) {
// DO SOMETHING WITH r
}
}
}
class BaseRequest<T> {}
class BaseObj {}
让我们一步一步解决问题。 你希望能够打电话
req.add(new BaseRequest<ExtObj1>());
req.add(new BaseRequest<ExtObj2>());
req.add(new BaseRequest<ExtObj3>());
其中ExtObj[1|2|3] extends BaseObj
。 给定List接口:
List<T> {
void add(T el);
}
我们需要为BaseRequest<ExtObj1>
, BaseRequest<ExtObj2>
和BaseRequest<ExtObj3>
找到一个公共超类型。 一个超类型是BaseRequest<?>
,另一个是BaseRequest<? extends BaseObj>
BaseRequest<? extends BaseObj>
。 我选择了第二个,因为它是最可能限制的。 你应该知道,在Java中BaseRequest<ExtObj1>
不是一个亚型BaseRequest<BaseObj>
因为泛型是不变的。
现在我们有了mRequests的正确声明,找到Executor.add()
的API非常简单。 顺便说一句,如果你需要的方法体非常简单,你甚至不需要type参数:
public void add(BaseRequest<? extends BaseObj> request) {
mRequests.add(request);
}
警告不是错误。 有警告,所以你检查是否有错误,因为它可能不会被自动检查。 您应该检查它,然后使用注释注意已经检查过警告。
在你的情况下,它警告BaseRequest<T>
不等于BaseRequest<BaseObj>
。
例:
public class NumberWrapper<N extends Number> {
private N value;
public void setValue(N value) {
this.value = value;
}
}
public class MainClazz {
private NumberWrapper<Integer> wrappedNumber = new NumberWrapper<Integer>();
public void run() {
Number n = externalSource.getNumber();
wrappedNumber.setValue(n); // <-- Error. What if getNumber returns a double?
}
}
您可以出现此错误,而不是取决于您完成/集成所显示代码的方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.