我正在尝试创建返回特定类型的处理程序的“注册表”
public class HandlerRegistry {
Map<Class<?>, Handler<?>> handlers;
<T> void setHandler(Class<T> type, Handler<? extends T> handler) {
handlers.put(type, handler);
}
<T> T handle(Class<T> type, HandlerArgument arg) {
Handler<? extends T> handler = getHandler(type);
return handler.handle(arg);
}
<T> Handler<? extends T> getHandler(Class<T> type) {
// warning produced here "uses unchecked or unsafe operations."
return (Handler<? extends T>)handlers.get(type);
}
}
我知道这个特定的强制转换在运行时永远不会失败,但是除了使用 @SuppressWarnings("unchecked")
之外,有没有办法告诉编译器这确实是安全的?
我专门使用 Java 8,如果有更优雅的方式来做我想在 8 中做的事情的话。
最佳答案
通常,在这种情况下,未经检查的操作是不可避免的。您可以做的最好的事情是隔离未经检查的操作并通过安全测试来保护它。一个经过验证的解决方案是将实例包装在一个 holder 实例中,该实例封装了未经检查的操作并强制执行预检查:
class HandlerRegistry {
private static class Holder<T> {
private final Class<T> type;
private final Handler<? extends T> handler;
Holder(Class<T> c, Handler<? extends T> h) {
type=Objects.requireNonNull(c);
handler=h;
}
<U> Holder<U> as(Class<U> expected) {
if(type!=expected)
throw new ClassCastException();
@SuppressWarnings("unchecked") Holder<U> h=(Holder)this;
return h;
}
public Handler<? extends T> getHandler() {
return handler;
}
}
Map<Class<?>, Holder<?>> handlers;
<T> void setHandler(Class<T> type, Handler<? extends T> handler) {
handlers.put(type, new Holder<>(type, handler));
}
<T> T handle(Class<T> type, HandlerArgument arg) {
return getHandler(type).handle(arg);
}
<T> Handler<? extends T> getHandler(Class<T> type) {
return handlers.get(type).as(type).getHandler();
}
}
关于java - 泛型友好的类型处理程序映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29837124/