2013-06-07 9 views
1

Я пытаюсь сделать синглтон следующим, но я продолжаю получать предупреждение. Если возможно, я не хочу подавлять предупреждение. Есть ли способ сделать это?java static class Singleton с общим

На данный момент я не хочу думать о безопасности потоков. Я просто хочу передать это предупреждение.

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; 
     } 
    } 

Спасибо.

+2

Что это предупреждение может быть хорошая информация :) – clement

+0

ли 'DefaultStorage' класс верхнего уровня? Тогда это не может быть 'static'. –

+0

: «Ссылки на общий тип DefaultStorage должны быть параметризованы, но если я сделаю« defaultStorage = new DefaultStorage () », я получаю ошибку компиляции. – user826323

ответ

0

Переменная defaultStorage в DefaultStorage существует только один раз в каждом случае DefaultStorage в сочетании. Во время выполнения есть только один фактический класс и одна статическая переменная. Таким образом, переменная будет одновременно DefaultStorage<K1, V1>, DefaultStorage<K2, V2>, DefaultStorage<K3, V3> и так далее. Итак, один класс будет хранить Strings в нем, другой будет хранить BigDecimals, а другой X501Principals. Это подрывает тип безопасности.

Предупреждение состоит в том, что вы храните экземпляр необработанного типа, new DefaultStorage(), в переменной, объявленной как DefaultStorage<K, V>.

С Angelika Langer's Generics FAQ,

Может родовые типы имеют статические члены?

Да.

Общие типы могут содержать статические элементы, включая статические поля, статические методы и статические вложенные типы. Каждый из этих статических членов существует один раз для каждого типа оболочки, то есть независимо от количества объектов охватывающего типа и независимо от количества экземпляров родового типа, которые могут быть использованы где-то в программе. Имя статического члена состоит - как обычно для статических членов - области (пакеты и тип размещения) и имени участника. Если закрытый тип является общим, то тип квалификационной области должен быть необработанным, а не параметризованным.

+0

Это будет означать, если вы создали' DefaultStorage d1' и 'Default Хранение d2', вы можете сделать 'd2.put (" X ", BigDecimal.TEN)' и 'd1.get (" X ")' -ooops, здесь согревается! Думаю, предупреждение означает: вы не хотите этого делать. –

+0

Да, это также причина, по которой вы получите предупреждение о доступе к статической переменной из экземпляра объекта. Компилятор предложит вам использовать 'DefaultStorage .defaultStorage', или он может пойти прямо на предложение' DefaultStorage.defaultStorage'. В любом случае вскоре произойдет «ClassCastException». Это предполагает, что ваши методы 'get' и' set' проходят через статический 'defaultStorage', конечно. –

0

Как вы могли создать ссылку на свой параметризованный внутренний класс следующим образом?

private static DefaultStorage<K, V> defaultStorage; 

В соответствии с разъяснениями в Static method in a generic class?:

параметры типа А Класс доступен только для переменных экземпляра, а не статические поля и методы. Статические поля и методы являются общими для всех экземпляров класса и даже экземпляры различных параметров типа.»

Таким образом, вы не можете создать статическую ссылку на свой класс DefaultStorage и ограничить его только типы K, V. Это должно быть хорошо.

private static DefaultStorage<?,?> defaultStorage; 

Но, как уже упоминалось, я не в состоянии избавиться от предупреждения, не подавляя его. И создание объекта, как это

 defaultStorage= new DefaultStorage();
вызывает ошибку компиляции, очевидно.

1

Я хотел бы использовать перечисление и указать тип.

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); } 

}