带有泛型的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
。