Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A generics confusion: deceiving the compiler

Tags:

java

generics

Consider a code:

public class GenericsConfusion {
    public static <T> Class<T> get(Class<T> clazz) {
        Map<Class, Class> map = new HashMap<Class, Class>();
        map.put(Integer.class, String.class);
        return map.get(clazz);
    }

    public static void main(String[] args) {
        Class<Integer> clazz = get(Integer.class);
        System.out.println(clazz);
    }
}

It compiles and runs perfectly. The idea was to return in get method the class which has the same type parameter as input class. But it is broken due to the presence of map. Yes, I know that in runtime the type parameter information is erased, so without the type parameters this code is perfectly valid. Also I know I can fix it by specifying Map<Class<T>, Class<T>> But the fact is that in method signature I have type parameters, and they dont help me in compile time.

Is this a misuse of some concept?

Or it is a disadvantage of Java generics?

Or its perfectly ok and I misunderstand the idea of type parameters?

like image 864
MiamiBeach Avatar asked Sep 30 '14 20:09

MiamiBeach


1 Answers

A raw type, such as Class or Map (as opposed to Class<...> or Map<..., ...>), circumvents the type-checking of generics. You can even write something like this:

final Class<Integer> whoops = (Class) String.class;

This is an unfortunate weakness in the type system. It was originally included in Java 5 (which introduced generics) for compatibility with code written under previous versions.

For the most part, you can avoid this weakness by avoiding the use of raw types. Your compiler should warn you about them.

Unfortunately, there are various circumstances where raw types are essentially unavoidable (due to the special typing of .getClass(); due to the fact that we can only write (for example) Map.class and not Map<String, String>.class (or Map.<String, String>class); due to erasure and reflection, etc.); but happily, as you've noted, your circumstance does not appear to be one of these.

like image 53
ruakh Avatar answered Oct 17 '22 03:10

ruakh