2015-10-20 1 views
0

Когда я выбрал Collections.synchronizedMap() для хэш-карты, он возвращает исключение класса cast, но когда я отбрасываю карту в хэш-карту, она отлично работает.Collections.synchronizedMap() возвращает класс cast exception, где, когда нормальная карта работает нормально

Согласно моему пониманию Collections.synchronizedMap() также возвращает карту.

Тогда почему я получаю это исключение.

Как это сделать.

Пример кода

public class Main_1 { 
    public static void main(String[] args) throws UnknownHostException, IOException { 
    Map m = new HashMap(); 
    m.put("sachin", "sacjdeva"); 
    // Throws exception here 
    HashMap hm = (HashMap) Collections.synchronizedMap(m); 
    //No exception 
    HashMap hm = (HashMap)(m) 
    System.out.println(hm); 
    } 
} 

Хорошо, если его synchronizedMap и бросает исключение произнесения класс может преобразовать этот SynchronizedMap в HashMap.

+0

«Карта» - это интерфейс, но «HashMap» - это тип реализации. Поэтому лучше отнести его к «Карте» – SacJn

+0

Вы не можете отнести интерфейс к классу реализации-интерфейса, вы можете вызвать конструктор hashmap, указав вместо этого карту как вход. – morels

+0

Возможный дубликат [Разница между назначениями динамического и статического типов в Java] (http://stackoverflow.com/questions/20504714/difference-between-dynamic-and-static-type-assignments-in-java) –

ответ

2

Collections.synchronizedMap(m) не возвращает HashMap, поэтому вы не можете его отличить до HashMap. Он возвращает экземпляр SynchronizedMap.

Вы можете назначить его на Map:

Map smap = Collections.synchronizedMap(m); 

В вашем примере "нормальная карта":

HashMap hm = (HashMap)(m); 

не является "нормальным Map". Нет такой вещи, как «нормальная карта».

Вы присваиваете HashMap экземпляр к нему здесь:

Map m = new HashMap(); 

, который является единственной причиной, вы можете позже привести его к HashMap.

+0

Я знаю, что я не возвращает хеш-карту, он возвращает только карту. –

+0

@ShowStopper Я не просто ссылаюсь на возвращаемый тип этого метода, который является «Map», я имею в виду фактическую реализацию «Map», возвращаемую этим методом, которая является 'SynchronizedMap', и поэтому не может быть брошенным на 'HashMap'. – Eran

0

Map есть интерфейс. HashMap - одна реализация, SynchronizedMap - другая реализация.

SynchronizedMap не является HashMap, поэтому вы не можете его отличить.

HashMap - HashMap, так что вы можете бросить его.

В вашем примере лучше всего добавить Map, если это необходимо, так как это позволит вам работать с любой реализацией.

+0

SynchronizedMap - это не реализация, а метод. Pls см. [Http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedMap(java.util.Map)](http://docs.oracle.com/javase /7/docs/api/java/util/Collections.html#synchronizedMap(java.util.Map)) – morels

+1

Это реализация. Взгляните на реализацию метода - он возвращает класс 'SynchronizedMap' – BobTheBuilder

1

Он возвращает экземпляр Map, то есть экземпляр класса (который вам не нужно знать), который реализует интерфейс Map. Вам не нужно указывать его на HashMap, то есть другой класс, реализующий тот же интерфейс Map.

HashMap hm = (HashMap)(m) 

работает только потому, что фактический конкретный класс m является HashMap. Это не будет работать, если вы инициализируетесь m с

Map m = new TreeMap(); 

, например.

Вы должны программировать интерфейсы, а не программировать конкретные типы. Ваша переменная должна быть типа Map. Вы должны также избегать использования сырья типов, а также указать общие параметры карты:

Map<String, String> map = new HashMap<>(); 
m.put("sachin", "sacjdeva"); 
Map<String, String> synchronizedMap = Collections.synchronizedMap(m); 
0

Hashmap не синхронизирован, поэтому он не может быть приведен к синхронному карте, а Map является interface так, что когда-либо типом синхронизированного Map вернулся он реализует Map так можно caseted к Map

0

SynchronizedMap возвращает другую реализацию, чем HashMap реализации, так что вы не можете бросить его HashMap.

Но вы можете сделать это:

Map<String, String> m = new HashMap<String, String>(); 
m.put("sachin", "sacjdeva"); 

Map<String, String> hm = Collections.synchronizedMap(m); 
+0

Err no, вы не можете. Это все еще синхронизирует карту с HashMap. –

0

Collections.synchronizedMap (Карта) возвращает экземпляр SynchronizedMap, который является внутренним классом класса Collections. Следующий фрагмент кода получит возвращаемое фактическое имя класса.

System.out.println(Collections.synchronizedMap(m).getClass().getName()); 

SynchronizedMap реализует интерфейс карты, но не является подклассом HashMap. Таким образом, при запуске SynchronizedMap в HashMap будет вызвано ClassCastException.

Смежные вопросы