简体   繁体   English

动态初始化Java单例的通用版本时出错(单行)

[英]Error initializating a generic version of Java singleton on the fly (single line)

Scenario: Exactly I am translating a my own Objective-C library to enable the same functionality to Android development using Java which is, a Singleton contains a Hashtable<String, V> (NSMutableDictionary in Objective-C) to facilitate programmer to inject and pop values based on key-value coding . 场景:确实,我正在翻译自己的Objective-C库,以使用Java实现与Android开发相同的功能,即Singleton包含Hashtable<String, V> (NSMutableDictionary in Objective-C)以方便程序员进行injectpop基于key-value coding The code is as follows... 代码如下...

Singleton.java Singleton.java

import java.util.Hashtable;

public class Singleton<V> {

    private static volatile Singleton sharedInstance = null;

    private Hashtable<String, V> sharedHashtable;

    private Singleton() {

        sharedHashtable = new Hashtable<String, V>();
    }

    public static Singleton getSharedInstance() {

        if (sharedInstance == null) {

            sharedInstance = new Singleton();
        }

        return sharedInstance;
    }

    public void inject(String key, V value) {

        sharedHashtable.put(key, value);
    }

    public V popValue(String key) {

        return sharedHashtable.get(key);
    }
}

Main.java Main.java

public class Main {

    public static void main(String[] args) {

        // Part 1

        Singleton<String> stringVersion = Singleton.getSharedInstance();

        stringVersion.inject("RAMStringKey", "Hello I am Using SO");

        String string = stringVersion.popValue("RAMStringKey");

        // Part 2

        Singleton<Integer> integerVersion = Singleton.getSharedInstance();

        integerVersion.inject("RAMIntegerKey", 5);

        Integer integer = integerVersion.popValue("RAMIntegerKey");

        System.out.println(string);
        System.out.println(integer);

        // Part 3

        String anotherString = Singleton.getSharedInstance().popValue("RAMStringKey"); // Error:(27, 70) java: incompatible types: java.lang.Object cannot be converted to java.lang.String

    }
}

Problem: I have succeeded to achieve strong typing therefore I can inject any object (String or Integer) and pop any object. 问题:我已经成功实现了强类型化,因此可以注入任何对象(字符串或整数)并弹出任何对象。 But in the Part 3 I am trying to do the same on the fly (in single line) but it is giving an error 但是在第3部分中,我试图动态地(单行)执行相同操作,但它给出了错误

Error:(27, 70) java: incompatible types: java.lang.Object cannot be converted to java.lang.String 

I am really trying to do something like: 我真的在尝试做类似的事情:

String anotherString = Singleton<String>.getSharedInstance().popValue("RAMKey"); 

but it is not allowed. 但这是不允许的。

How can I create a singleton in a single line exactly like in part 3? 如何像第3部分中一样在单行中创建一个单例? Can anyone help me to achieve that? 谁能帮助我实现这一目标? Where should I make the change? 我应该在哪里进行更改?

Tip: Part 3 is the single line version of Part 1 提示:第3部分是第1部分的单行版本

The type parameter is used at compile time for type checking. type参数在编译时用于类型检查。 The Singleton class does not know about the type parameter, instances may know about type parameters. Singleton类不知道类型参数,实例可能知道类型参数。 The first call to Singleton.getSharedInstance() creates a HashMap<String,Object> in part 1. Its legal to store String or Integer values in this map. Singleton.getSharedInstance()的首次调用在第1部分中创建了HashMap<String,Object> 。在此映射中存储StringInteger值是合法的。 In part 3 getSharedInstance() accesses a map HashMap<String,Object> , thus popValue() returns an Object which cannot be cast to a String as the error says. 在第3部分中, getSharedInstance()访问映射HashMap<String,Object> ,因此popValue()返回一个Object ,该Object不能如错误所述那样转换为String

Please note there is only one static instance sharedInstance , not one per used type parameter! 请注意,只有一个静态实例sharedInstance ,而不是每个使用的type参数一个!

And since you mentioned Android: Be careful with singletons in android: If the application is exited and restarted it is not guaranteed that the VM has been restarted for your application. 而且,由于您提到了Android:请注意android中的单例:如果应用程序已退出并重新启动,则无法保证已为您的应用程序重新启动了VM。 This means a singleton instance from a previous run might survive and its state might or might not be useful for the new run. 这意味着来自先前运行的单例实例可能会生存,并且其状态可能对新运行有用或可能不有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM