java 如何在java中创建一个通用的单例类?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11772362/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 06:18:38  来源:igfitidea点击:

how to create a generic singleton class in java?

javagenerics

提问by saurabhking

i want to create a generic singleton class in java witch gives singleton object of class which i pass in method parameter. some thing like below code : please help

我想在 java 中创建一个通用的单例类,女巫给出了我传入方法参数的类的单例对象。一些类似下面的代码:请帮忙

public final class Listener<T extends Object>  {
    private Listener() {
    }

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

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

回答by yshavit

Make an enumwith just one value, INSTANCEor such. Instant singleton.

制作一个enum只有一个值,INSTANCE或者这样的。即时单身。

If I understand you correctly, I think you want your singleton to implement some generic interface? Something like:

如果我理解正确,我认为您希望您的单例实现一些通用接口?就像是:

interface ListenerInterface<T> {
    void handleEvent(T event);
}

In that case, you can use an unchecked cast to return your enum-as-singleton in a generified way. This is safe as long as your singleton doesn't actually use the instance (or else, only assume it's an Object).

在这种情况下,您可以使用未经检查的强制转换以通用方式返回您的 enum-as-singleton。只要您的单身人士实际上不使用该实例(否则,仅假设它是一个对象),这就是安全的。

public enum MySingleton implements ListenerInterface<Object> {
    INSTANCE;

    @SuppressWarnings("unchecked")
    public static <T> ListenerInterface<T> getListener() {
        return (ListenerInterface<T>) INSTANCE;
    }

    public void handleEvent(Object event) {
        System.out.println("I am a singleton. An event happened: " + event);
    }

}

If the interface is a producer instead of consumer -- that is, it returns a T-- then you can only return nullsafely. Otherwise, someone else will get a ClassCastException when they try to use their T, which they think is a Foo but is actually just an Object.

如果接口是生产者而不是消费者——也就是说,它返回一个T——那么你只能null安全地返回。否则,其他人在尝试使用他们的 时会得到 ClassCastException T,他们认为这是一个 Foo 但实际上只是一个对象。

回答by Sap

This was going to be comment but I think it better be an answer due to character limit,

这将是评论,但我认为由于字符限制,它最好是一个答案,

Thinking little bit deeper will it be really possible to create a generic singleton class?

再深入思考一下,真的有可能创建一个通用的单例类吗?

A singleton class can not be instantiated neither should it be cloned.

单例类不能被实例化,也不应该被克隆。

To give any class this behavior you will have to make all the constructors private and clone method will have to be overridden to throw an exception. Now if you are going to change all your classes to implement this behavior is your way of creating singleton really generic?

要为任何类提供这种行为,您必须使all the constructors private and clone method will have to be overridden to throw an exception. 现在,如果您要更改所有类以实现此行为,那么您创建单例的方式是否真的很通用?

Please excuse me if I interpreted the question wrongly

如果我错误地解释了问题,请原谅

回答by m3th0dman

You can do something like this, but is unreliable IMHO:

你可以做这样的事情,但恕我直言不可靠:

public class SimpleSingleton {
private Map<String, Object> counter = new HashMap<String, Object>();

public <T> T getInstance(Class<T> clazz) throws IllegalAccessException, InstantiationException {
    T singleton = (T) counter.get(clazz.getName());
    if (singleton == null) {
        singleton = clazz.newInstance();
        counter.put(clazz.getName(), singleton);
    }
    return singleton;
}

}

}

回答by Laurentiu Stamate

The solution for me to this problem was designing it like this:

我对这个问题的解决方案是这样设计的:

public interface IListener<T extends Object>  {
    void handle(T event);
}

public final class Listener implements IListener<Object> {
    private static Listener instance = new Listener();

    private Listener() {
    }

    public static Listener getInstance() {
        return instance;
    }

    @Override
    public void handle(Object event) {
        //TODO Do stuff
    }
}

回答by gustafc

I'm not sure if I understand your question fully, but if you want to integrate a singleton into a generic hierarchy, you have to cheat a bit (like we did in this topic):

我不确定我是否完全理解您的问题,但是如果您想将单例集成到通用层次结构中,则必须作弊(就像我们在本主题中所做的那样):

interface Listener<T>{
    // ...
}

@SuppressWarnings("unchecked")
final class SingletonListener {

    private SingletonListener(){ 
        assert false : "Uninstantiable"; 
    }

    public Listener<T> instance(){
        return SingletonListenerInstance.INSTANCE;
    }

    // Note - implements Listener without specifying type parameters!
    private enum SingletonListenerInstance implements Listener { 
        INSTANCE;
        // Insert listener methods here
    }

}

// Usage:
Listener<Pony> ponyListener = SingletonListener.instance();