[英]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.