单例引用的Java映射

单例引用的Java映射,java,Java,我想创建一个单例类的映射,我可以通过交叉引用来访问它,以便响应特定的请求。我实现了以下内容,但在获取可以调用getInstance()的实际引用时遇到了困难 我不知道如何从“t”到“某物”,或者根据我的编码方式,这是可能的。我尝试调用.cast(Thing.class).getInstance(),但遇到了一个cast异常。还尝试了反射来获取getInstance()方法,但也没有成功 也许我走错了路。给定1..n个可能的函数,解决方案的任何给定实例可能只需要其中的一个子集。此外,我希望通过配置

我想创建一个单例类的映射,我可以通过交叉引用来访问它,以便响应特定的请求。我实现了以下内容,但在获取可以调用getInstance()的实际引用时遇到了困难

我不知道如何从“t”到“某物”,或者根据我的编码方式,这是可能的。我尝试调用.cast(Thing.class).getInstance(),但遇到了一个cast异常。还尝试了反射来获取getInstance()方法,但也没有成功

也许我走错了路。给定1..n个可能的函数,解决方案的任何给定实例可能只需要其中的一个子集。此外,我希望通过配置轻松添加/删除类并管理接口,而不是在启动时通过一系列对象实例化


谢谢

我不太明白您创建此地图的目的。从您所写的内容来看,似乎可以简单地将返回单例的静态
getInstance()
方法放在每个相关类上。或者更简单:将每个共享实例作为其类的静态最终字段

如果必须使用映射,请不要将整数用作键。类是键,其实例是值。比如:

private static final Map<Class<?>,Object> singletons = new HashMap<>();

public static synchronized <T> T getSingleton(Class<T> klass) {
    Object obj = singletons.get(klass);
    if (obj == null) {
        try {
            obj = klass.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        singletons.put(klass, obj);
    }
    return klass.cast(obj);
}
我不确定这是否是你想要的,但它可能包含一些想法


编辑:我刚刚意识到使用类本身作为键的问题:它导致类被加载,即使在特定程序运行期间不需要它。使用字符串键可以避免加载不需要的类,但会增加脆弱性。这是另一个反对使用映射的论点。

为什么要类映射而不是对象映射?你为什么不用Guice,Spring,或者别的什么?我来看看Guice,谢谢。我的想法是建立一个基于某种索引的单件表。特定函数在被请求之前不会实例化,在某些实例中可能永远不会实例化。我也可以很容易地把它做成一个服务对象表,但在大多数安装中,只需要少数几个,直到运行时才真正知道这一点。如果你有这么多单身汉,你需要一张地图来保持他们的正直,那么你就是在严重滥用这个概念。@HotLicks…你可能是对的。我主要是在想一些最有效的方法,让控制器将请求映射到服务。我可以很容易地实例化每个服务对象并相应地路由。但在大多数安装中,只会使用一小部分可能的服务,这在编译时是未知的。更好的主意当然是受欢迎的。地图的关键是由请求决定的…即/request/thing/1将查找“thing服务表”的索引1,以获取处理请求的类。本质上,我试图实现一个服务表,而不必实例化每个处理程序。@coolhouse啊。你是说。。网络事物?我不知道我是否明白,但没关系。
something.perform(arg1, arg2);
private static final Map<Class<?>,Object> singletons = new HashMap<>();

public static synchronized <T> T getSingleton(Class<T> klass) {
    Object obj = singletons.get(klass);
    if (obj == null) {
        try {
            obj = klass.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        singletons.put(klass, obj);
    }
    return klass.cast(obj);
}
private static final Map<Class<?>,Object> singletons = new HashMap<>();

public static synchronized <T> T getSingleton(Class<T> klass) {
    Object obj = singletons.get(klass);
    if (obj instanceof Supplier) {
        obj = ((Supplier<?>)obj).get();
        singletons.put(klass, obj);
    }
    return klass.cast(obj);
}

public static synchronized <T> void declareSingleton(Class<T> klass, Supplier<T> supplier) {
    if (Supplier.class.isAssignableFrom(klass)) {
        // prevent Supplier<Supplier<?>> weirdness;
        // could use separate maps if those are really needed
        throw new UnsupportedOperationException();
    }
    singletons.put(klass, supplier);
}

static {
    // add creation expressions for several classes;
    // instances will not be created until needed
    declareSingleton(ThingOne.class, () -> new ThingOne());
    declareSingleton(ThingTwo.class, () -> new ThingTwo(123));
}