java - 如何在 java 中参数化泛型单例

标签 java generics type-safety

我有下一个问题。我有一个界面:

public interface Worker<T> {
    public void start(Class<? extends T> taskClass);
}

和这个接口(interface)的单例实现:

public final class Listener<T extends Runnable> implements Worker<T> {
    private Listener() {}

    @Override
    public void start(Class<? extends T> taskClass) { ... }

    public static Listener getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder {
        public static final Listener INSTANCE = new Listener();
    }
}

我的问题是,我可以通过这种方式获取单例实例吗:

Worker<Thread> listener = Listener.getInstance();

仍然是类型安全的吗?如果不是,我如何在类型安全的单例实例中使用泛型?

最佳答案

所有泛型都在运行时被剥离。

这意味着您将只有一个 static class SingletonHolder 和一个 INSTANCE,无论泛型是什么。

要解决这个问题,如果有意义的话,您可以拥有“多个单例”。您将不得不添加某种注册,因此如果您试图获得一个尚不存在的注册,请在返回之前创建并存储它。请注意,这不是编译的,可能存在一些问题,但基本方法仍然相同。

public final class Listener<T extends Runnable> implements Worker<T> {
    private Listener() {}

    @Override
    public void start(Class<? extends T> taskClass) { ... }

    public static Listener getInstance(Class<T> clazz) {
        return SingletonHolder.INSTANCE.get(clazz);
    }

    private static class SingletonHolder {
        private static final Map<Class<? extends Runnable>,Listener<? extends Runnable> INSTANCE = new ...;
    }
}

关于java - 如何在 java 中参数化泛型单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7286762/

相关文章:

java - 使用泛型作为返回类型

java - 安全地加强类型之间的关系

java ->>> 和 >> 运算符之间的区别

java - 如何与其他线程的事件派发线程或 swing 组件进行通信?

java - 退出方法时堆栈会发生什么?

Java 通用问题

java + google web 工具包(google apps 引擎)

java - 当涉及java泛型时,如何使Align.vim\adec正常工作?

java - 对返回 HashMap 的方法使用泛型键

MIDP 2 移动应用程序中的 Java 枚举