Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the <?> value for a Foo<?> object?

(This is somewhat a followup to my previous question)

I've got a Foo<?> object, foo. Foo<T> is an interface.

How to get the type value hidden behind the <?>?

Note that this is not trivial, as foo can be for example an object of class Bar<String>, where Bar<T> implements Foo<T>, or some anonyomus class implementing interface FloatFoo, where FloatFoo extends Foo<Float>. I need a solution that works in all cases.

Thanks in advance :)

like image 596
mik01aj Avatar asked Sep 01 '10 07:09

mik01aj


People also ask

What is the value of * foo?

Question: What is the value of foo. x? The answer is undefined .

How to get the class of an object?

Java Object getClass() Method This method returns the runtime class of this object. The class object which is returned is the object that is locked by static synchronized method of the represented class.


3 Answers

This is not possible using reflection because Java Generics has the problem of Type Erasure. At runtime the types that have been defined for the generic class Foo have been removed, so using reflection on that class will not yield its generic type. This type information is used only in compilation for type safety.

C# does not have this issue and it is possible to access the templatized type of a Class.

This is a overview of the differences.

like image 126
linuxuser27 Avatar answered Oct 08 '22 04:10

linuxuser27


Well, for short, you can't.

However, what you can do is get the value of <?> when using FloatFoo.

Indeed, from what I remember, generics are not kept in class information.

however, when you create a subtype (be it class or interface) of a generics type, the generics information has to be memorized as it may define some of the subtype's methods signature.

As an example, if your Foo interfaceis declared as it :

public interface Foo<T> {
    public T doIt();
}

Having a

public interface FloatFoo extends Foo<Float>

implies this interface has a

public Float doIt();

method declared.

For that, the compiler has to have the type information. And this information will be reflected in the reflection API by the fact that FloatFoo's super class will have some Type parameters associated to it. Or it least it is what I remember from the few cases I encountered such cases (or elaborated them, as it may sometimes be mandatory)

But you'll have far more complete informations at Angelika's generics FAQ.

like image 32
Riduidel Avatar answered Oct 08 '22 04:10

Riduidel


I ended up with creating a getType() method in the interface:

Class<T> getType();

Maybe it's not the most elegant solution, but definitely the simplest one.

like image 26
mik01aj Avatar answered Oct 08 '22 05:10

mik01aj