Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a Type object corresponding to a generic type

Tags:

java

generics

In Java, how can I construct a Type object for Map<String, String>?

System.out.println(Map<String, String>.class);

doesn't compile. One workaround I can think of is

Map<String, String> dummy() { throw new Error(); }
Type mapStringString = Class.forName("ThisClass").getMethod("dummy", null).getGenericReturnType();

Is this the correct way?

like image 807
Alexey Romanov Avatar asked Jun 07 '10 11:06

Alexey Romanov


People also ask

Can you create instances of generic type parameters?

A generic type is like a template. You cannot create instances of it unless you specify real types for its generic type parameters. To do this at run time, using reflection, requires the MakeGenericType method.

How do you make a generic type?

To construct a generic type from the generic type definition for a nested type, call the MakeGenericType method with the array formed by concatenating the type argument arrays of all the enclosing types, beginning with the outermost generic type, and ending with the type argument array of the nested type itself, if it ...

What is a generic object?

Generic objects are structures for storing and interacting with data in an app. They are the primary type of entity through which the engine provides access to the components of an app.

Can you create an array using a generic type parameter?

Array of generic typesNo, we cannot create an array of generic type objects if you try to do so, a compile time error is generated.


2 Answers

public class Test {
    public Map<String, String> dummy;
    public static void main(String... args) throws SecurityException, 
                                                   NoSuchFieldException {
        Type mapStringString = Test.class.getField("dummy").getGenericType();
        // ...

Is a slightly less ugly hack..


As Tom Hawtin suggests, you could implement the methods yourself:

Type mapStrStr2 = new ParameterizedType() {
    public Type getRawType() {
        return Map.class;
    }
    public Type getOwnerType() {
        return null;
    }
    public Type[] getActualTypeArguments() {
        return new Type[] { String.class, String.class };
    }
};

returns the same values as the other approach for the methods declared in ParameterizedType. The result of the first approach even .equals this type. (However, this approach does not override toString, equals and so on, so depending on your needs, the first approach might still be better.)

like image 84
aioobe Avatar answered Sep 30 '22 13:09

aioobe


It's all done with interfaces, so you can construct your own implementation.

However, the easiest way is to use reflection on a dummy class created for the purpose.

like image 38
Tom Hawtin - tackline Avatar answered Sep 30 '22 12:09

Tom Hawtin - tackline