简体   繁体   中英

How to get the class type of nested generic type?

Say we have a function:

void doSomething(Class<?> clazz);

If I want to call it for a class Foo, I would call it this way:

doSomething(Foo.class);

How do I call doSomething() if my type is Foo<Boo> ?

I guess the question is what is the equivalent of Foo.class for Foo<Boo> ?

Is that even possible?

-- Update ---

I'll explain more.

I have a typed bean :

class EventMessage <T> {

T payload;
String type;

}

An object of this type gets converted to a Json form (String), then put on a JMS Queue; The consumer needs to de-jasonize it back from the String to it's original form. The Json ObjectMapper needs to know the type to convert to. Say my EventMessage payload was Offer type, then I want something like that:

EventMessage <Offer> offerEvent = jsonObjectMapper.readValue(jsonMsg, EventMessage<Offer>.class)

Except that there is no such thing as EventMessage<Offer>.class .

The issue is that EventMessage is a typed class so the Json converter would have no idea how to resolve it without extra information about the payload type.

There is only one Foo class object. Foo<Boo> and Foo<Integer> are not different classes; they are the same class, and even if you could do Foo<Boo>.class it would be identical to Foo except for the compile-time type. But in the first example, you are not using the compile-time type anyway, since you are passing to a parameter of type Class<?> .

In your second example, you did not show the signature of readValue() , but I am assuming that it is something like <T> T readValue(JSONMessage, Class<T>) . This is completely different from your first example. In this case, the compile-time type helps determine the T which is the return type. You can either manipulate the type of the Class argument:

EventMessage<Offer> offerEvent =
    jsonObjectMapper.readValue(jsonMsg, (Class<EventMessage<Offer>>)
                                        (Class<?>)EventMessage.class)

or just use the raw type, get the raw type back, and let it be implicitly converted to the parameterized type:

EventMessage<Offer> offerEvent =
    jsonObjectMapper.readValue(jsonMsg, EventMessage.class)

Try this:

doSomething((Class<Foo<Boo>>)Foo.class)

Or this:

EventMessage<Offer> offerEvent = jsonObjectMapper.readValue(jsonMsg, 
                           (Class<EventMessage<Offer>>) EventMessage.class);

.class is a language literal, not a field. Maybe you like to report a feature-request to java

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM