[英]Java Generics - Unchecked cast from “capture#1 of ?” to “A”
我有2條警告:
unchecked cast, required: A found: capture#1 of ?
unchecked cast, required: A found: Congress
我知道該課程實際上是一個事件。
在“事件”是接口的情況下,展覽和國會均實現“事件”接口。
public static <A extends Event> A copy(A event) {
Class<?> eventType = event.getClass(); // --> Warning 1
return (A) eventType.getConstructor(eventType).newInstance(event);
return event;
}
第二個警告:
public static <A extends Event> A create(EventType type) {
if(type == EventType.CONGRESS){
return (A) new Congress() // --> Warning 2
}else(){
return (A) new Exhibition() // --> Same as warning 2 but for Exibition
}
}
現在的問題是:如何不使用以下命令解決這兩個警告:
@SuppressWarning("unchecked")
似乎您在濫用泛型。 如果方法決定返回哪種類型,則不應使用泛型。 當調用者決定返回哪種類型時,將使用泛型。
所以create
應該是這樣的:
public static Event create(EventType type) {
if(type == EventType.CONGRESS){
return new Congress();
}else {
return new Exhibition();
}
}
對於第一個警告,您可以執行以下操作。
public static <A extends Event> A copy(A event) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
return (A) event.getClass().getConstructor(event.getClass()).newInstance(event);
}
您可以通過將 eventType
聲明為Class<? extends A>
來解決第一個警告Class<? extends A>
Class<? extends A>
。這使得強制轉換為 A
多余的。
如果您無法更改第一種方法的返回類型,則無法選擇不使用強制轉換來解決此編譯問題。 可以通過將方法的返回類型更改為Event
來解決編譯問題。 如果將返回類型更改為Event
,則可以完全刪除通用參數:
public static Event copy(Event e)
throws NoSuchMethodException,
IllegalAccessException,
InstantiationException,
InvocationTargetException {
Class<? extends Event> cls = e.getClass();
return cls.getConstructor(cls).newInstance();
}
對於第二個警告,您也可以完全刪除該方法的通用類型:
public Event create(EventType type) {
if (type == EventType.CONGRESS) {
return new Congress();
} else {
return new Exhibition();
}
}
這假定Congress extends Event
, Exhibition extends Event
。
為什么要將此方法設為靜態方法?
public static <A extends Event> A copy(A event) {
Class<?> eventType = event.getClass(); // --> Warning 1
return (A) eventType.getConstructor(eventType).newInstance(event);
return event;
}
您具有Event的實例,讓Event
類能夠創建其自身的副本。
abstract class Event<E extends Event<E>> {
public E createCopy(E toCopy);
}
同
class Exhibition extends Event<Exhibition> {
// ...
public Exhibition createCopy() {
return new Exhibition(this);
}
}
您可以擺脫的第二個警告是將EventType
調整為
public enum EventType {
CONGRESS { public Event createEvent() { return new Congress(); }},
EXHIBITION { public Event createEvent() { return new Exhibition(); }};
public abstract Event createEvent();
}
這將導致
public static Event create(EventType type) {
return type.createEvent();
}
如果確實有必要知道返回的事件的確切類型,那么此時您應該重新考慮設計。
我建議使用TypeTags aka ClassTags。 就像是:
public static <A extends Event> Optional<A> create(Class<A> classTag) {
try {
return Optional.of(classTag.newInstance());
} catch (InstantiationException | IllegalAccessException e) {
return Optional.empty();
}
}
這樣稱呼它:
public static void main(String[] args) {
Optional<Exhibition> e = create(Exhibition.class);
e.ifPresent(System.out::println);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.