泛型友好类型处理程序地图 [英] Generics friendly Type Handler map

查看:148
本文介绍了泛型友好类型处理程序地图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个返回特定类型的处理程序的注册表

I'm trying to make a "registry" of handlers that return a specific type

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)有没有办法告诉编译器这确实是安全的?

I know that this particular cast will never fail at runtime, but other than using @SuppressWarnings("unchecked") is there a way to tell the compiler that this is indeed safe?

我特意使用Java 8,如果有更优雅的方式在8中做我想做的事。

I'm using Java 8 specifically, if there is a more elegant way to do what I want in 8.

推荐答案

通常,在这种情况下,不可避免的操作是不可避免的。您可以做的最好的事情是隔离未经检查的操作并用安全测试来保护它。一个经过验证的解决方案是将实例包装在一个holder实例中,该实例封装了未经检查的操作并强制执行预检:

Generally, an unchecked operation is unavoidable in this case. The best thing you can do is to isolate the unchecked operation and guard it with a safe test. One proven solution is to wrap the instance in a holder instance which encapsulates the unchecked operation and enforces the pre-check:

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();
    }
}

这篇关于泛型友好类型处理程序地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆