带有泛型的java静态类单例

带有泛型的java静态类单例,java,Java,我试着做一个像下面这样的单身汉,但我一直得到一个警告。如果可能的话,我不想取消警告。有办法吗 现在,我不想考虑线程安全性。我只是想通过这个警告 public interface Storage<K, V> { public void put(K key, V value); public V get(K key); } public static class DefaultStorage<K, V> implem

我试着做一个像下面这样的单身汉,但我一直得到一个警告。如果可能的话,我不想取消警告。有办法吗

现在,我不想考虑线程安全性。我只是想通过这个警告

    public interface Storage<K, V> {
        public void put(K key, V value);
        public V get(K key);
    }


    public static class DefaultStorage<K, V> implements Storage<K, V> {

        private Map<Object, Object> map = new ConcurrentHashMap<Object, Object>();

        private static DefaultStorage<K, V> defaultStorage;

        private DefaultStorage() {
            //
        }

        public static DefaultStorage<?, ?> getInstance() {
            if (defaultStorage== null) {
                defaultStorage= new DefaultStorage();
            }
            return defaultStorage;
        }
     }
公共接口存储{
公开作废认沽权(K键,V值);
公共V-get(K键);
}
公共静态类DefaultStorage实现存储{
私有映射映射=新的ConcurrentHashMap();
私有静态默认存储默认存储;
专用默认存储(){
//
}
公共静态DefaultStorage getInstance(){
if(defaultStorage==null){
defaultStorage=新的defaultStorage();
}
返回默认存储;
}
}

谢谢。

defaultStorage
中的变量
defaultStorage
仅在
defaultStorage
组合的每个实例中存在一次。在运行时,只有一个实际类和一个静态变量。因此,变量将同时是
DefaultStorage
DefaultStorage
DefaultStorage
,依此类推。因此,一个类将存储
字符串
,另一个类将存储
大小数
,另一个类将存储
X501Principals
。这破坏了类型安全性

警告是您正在声明为
DefaultStorage
的变量中存储原始类型的实例
new DefaultStorage()

泛型类型可以有静态成员吗

泛型类型可以有静态成员,包括静态字段、静态方法和静态嵌套类型。每个静态成员在每个封闭类型中都存在一次,也就是说,与封闭类型的对象数量无关,也与程序中可能使用的泛型类型的实例化数量无关。静态成员的名称由作用域(包和封闭类型)和成员的名称组成,这对于静态成员来说是常见的。如果封闭类型是泛型的,则范围限定中的类型必须是原始类型,而不是参数化类型


您如何能够像这样创建对参数化内部类的引用

private static DefaultStorage<K, V> defaultStorage;
私有静态DefaultStorage DefaultStorage;
根据中给出的解释:

类的类型参数只能用于其实例变量,而不能用于静态字段和方法。静态字段和方法在类的所有实例之间共享,甚至共享到各种类型参数的实例。”

因此,您不能创建对类DefaultStorage的静态引用并将其限制为仅K,V类型。这应该可以

private static DefaultStorage<?,?> defaultStorage;
私有静态DefaultStorage DefaultStorage;

但是,正如您所提到的,如果不抑制警告,我无法消除它。并且创建像这样的对象defaultStorage=new defaultStorage();显然会引发编译错误。

我将使用枚举并指定类型

defaultStorage= new DefaultStorage();
public interface Storage<K, V> {
    public void put(K key, V value);
    public V get(K key);
}

public enum DefaultStorage implements Storage<String, Object> {
    INSTANCE;

    private final Map<Object, Object> map = new ConcurrentHashMap<>();

    public Object get(String key) { return map.get(key); }
    public void put(String key, Object value) { map.put(key, value); }
公共接口存储{
公开作废认沽权(K键,V值);
公共V-get(K键);
}
公共枚举DefaultStorage实现存储{
实例;
私有最终映射=新的ConcurrentHashMap();
公共对象get(字符串键){return map.get(键);}
公共void put(字符串键,对象值){map.put(键,值);}

}

警告是什么?可能是一个很好的信息:)是
DefaultStorage
顶级类吗?那么它不能是
static
。它说“对泛型类型DefaultStorage的引用应该参数化。但是如果我执行“defaultStorage=new defaultStorage()”,我会得到一个编译错误。它是父类中的内部类。@user826323什么是SampleCache?这没有显示在您的代码中。这意味着如果您创建了一个
DefaultStorage d1
和一个
DefaultStorage d2
,您可以执行
d2.put(“X”,BigDecimal.TEN)
d1.get(“X”)
-oops,这里正在变暖!我猜警告的意思是:你不想这样做。是的,这也是为什么你会收到关于从对象实例访问静态变量的警告。编译器会建议您使用
DefaultStorage.DefaultStorage
,或者直接建议
DefaultStorage.DefaultStorage
。在任何一种情况下,都会很快出现
ClassCastException
。当然,这假设您的
get
set
方法通过静态
defaultStorage