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