如何在Java中参数化通用单例

如何在Java中参数化通用单例

本文介绍了如何在Java中参数化通用单例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有下一个问题。我有一个接口:

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

以及此接口的单一实现:

  public final class Listener< T extends Runnable>实现Worker< T> {
private Listener(){}
$ b $ @Override
public void start(Class< ;? extends T> taskClass){...}

public static Listener getInstance(){
返回SingletonHolder.INSTANCE;


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


$ / code $ / pre

我的问题是,我可以通过单例实例这样:

 工人<线程> listener = Listener.getInstance(); 

仍然是类型安全的?如果没有,我怎么能在单例实例中使用泛型来保证类型安全? 解决方案

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

这意味着你只有一个静态类SingletonHolder ,并且只有一个 INSTANCE 不管泛型是什么。



为了解决这个问题,如果有意义的话,你可以有'多个单身人士'。您将不得不添加某种注册,因此如果您尝试获取尚未存在的注册,请在返回之前创建并存储它。请注意,这不是编译好的,可能会有一些问题,但基本方法仍然是一样。

  public final class Listener< T extends Runnable>实现Worker< T> {
private Listener(){}
$ b $ @Override
public void start(Class< ;? extends T> taskClass){...}

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

私有静态类SingletonHolder {
私有静态最终地图< Class< ;?扩展可运行>,监听器<?扩展Runnable> INSTANCE = new ...;
}
}


I have next problem. I have an interface:

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

and singleton implementation of this 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();
    }
}

My question is, can I get the singleton instance by this way:

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

is still type-safe? when not, how can I use generic in singleton instance to by type-safe?

解决方案

All generics are stripped at runtime.

This means you're only going to have one static class SingletonHolder and only one INSTANCE no matter what the generic is.

To get past this, you could have 'multiple singletons' if that makes sense. You would have to add some kind of registration, so if you tried to get one that didn't exist yet, create and store it before returning it. Note this isn't compiled, and there may be some issues with it, but the basic approach is still the same.

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中参数化通用单例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 07:09