Why does this class behave differently when I do not propose a generic type?

I do not understand why this is confusing for the compiler. I use the generic type T to store an object that is not associated with the put and get methods. I always thought that GenericClass and GenericClass<Object> functionally identical, but I should be wrong. When compiling the DoesntWork class DoesntWork I get incompatible types - required: String - found: Object . The Works class does what I expect. What's going on here?

 public class GenericClass<T> { public <V> void put(Class<V> key, V value) { // put into map } public <V> V get(Class<V> key) { // get from map return null; } public static class DoesntWork { public DoesntWork() { GenericClass genericClass = new GenericClass(); String s = genericClass.get(String.class); } } public static class Works { public Works() { GenericClass<Object> genericClass = new GenericClass<Object>(); String s = genericClass.get(String.class); } } } 
+6
source share
2 answers

The way raw types work — the generic types you left out of the arguments — is that all generics for them and their methods are also erased. So, for raw GenericClass , the get and put methods also lose their generics.

+8
source

This is because when you work with a general class without additional type information, you work with what is sometimes called the degenerate form of a class. The degenerate form deletes ALL data of a general type.

Essentially - your class becomes something like:

 public class GenericClass { public void put(Class key, Object value) { // put into map } public Object get(Class key) { // get from map return null; } ... } 

Thus, it is expected that the expected compiler response will be expected.

It is mentioned in Java Puzzlers .

+1
source

All Articles