Joker
Joker

Reputation: 11146

Collections.synchronizedMap( ) returns class cast exception where as normal map works fine

When i cast Collections.synchronizedMap( ) to hash map it returns class cast exception but when i cast Map to hash map it works fine.

As per my understanding Collections.synchronizedMap( ) also returns map .

Then Why i am getting this exception .

How to over come it.

Example code

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

Ok if its synchronizedMap and throws class cast exception can i convert this SynchronizedMap to HashMap.

Upvotes: 1

Views: 1344

Answers (6)

Developer
Developer

Reputation: 544

Collections.synchronizedMap(Map) returns an instance of SynchronizedMap which is an inner class of Collections class. Following piece of code will get the actual class name being returned.

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

SynchronizedMap implements the Map interface but it is not a subclass of HashMap. So casting SynchronizedMap to HashMap will cause ClassCastException.

Upvotes: 0

Eran
Eran

Reputation: 393781

Collections.synchronizedMap(m) doesn't return a HashMap, so you can't cast it to HashMap. It returns a SynchronizedMap instance.

You can assign it to a Map :

Map smap = Collections.synchronizedMap(m);

In your "normal Map" example :

HashMap hm = (HashMap)(m);

is not a "normal Map". There is no such thing as "normal Map".

You assign a HashMap instance to it here :

Map m = new HashMap();

which is the only reason you can later cast it to HashMap.

Upvotes: 3

Salah
Salah

Reputation: 8657

SynchronizedMap returns a different implementation than HashMap implementation, so you can't cast it to HashMap.

But you can do this:

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

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

Upvotes: 0

karim mohsen
karim mohsen

Reputation: 2254

Hashmap is not synchronized so it can't be cast to Synchronized Map while Map is an interface so what ever type of synchronized Map returned it implements Map so can be caseted to Map

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691685

It returns an instance of Map, i.e. an instance of a class (that you don't need to know) that implements the Map interface. You don't need to cast it to HashMap, which is another class implementing the same Map interface.

HashMap hm = (HashMap)(m)

works only because the actual concrete class of m is HashMap. It wouldn't work if you initialized m with

Map m = new TreeMap();

for example.

You should program to interfaces rather than programming to concrete types. Your variable should be of type Map. You should also avoid using raw types, and specify the generic parameters of the map:

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

Upvotes: 1

BobTheBuilder
BobTheBuilder

Reputation: 19284

Map is interface. HashMap is one implementation, SynchronizedMap is another implementation.

SynchronizedMap is not a HashMap, so you cannot cast it to it.

HashMap is a HashMap, so you can cast it.

In your example it is better to cast to Map if you need, as it would allow you to work with any implementation.

Upvotes: 0

Related Questions