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

pie*_*tou 3 java generics type-safety

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

public interface Worker<T> {
    public void start(Class<? extends T> taskClass);
}
Run Code Online (Sandbox Code Playgroud)

和单接口实现此接口:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,我可以通过这种方式得到单例实例:

Worker<Thread> listener = Listener.getInstance();
Run Code Online (Sandbox Code Playgroud)

还是类型安全吗?什么时候不能,如何在单例实例中使用泛型?

cor*_*iKa 5

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

这意味着无论通用是什么,你只会拥有一个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 ...;
    }
}
Run Code Online (Sandbox Code Playgroud)