开发者

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

开发者 https://www.devze.com 2023-01-14 14:48 出处:网络
(This is somewhat a followup to my previous question) I\'ve got a Foo<?> object, foo. Foo<T> is an interface.

(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 soluti开发者_如何学Con that works in all cases.

Thanks in advance :)


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.


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.


The final-final (and perhaps the best possible) solution: I refactored my code, so it doesn't need this. I moved all code which needed the type parameter into Foo, so I could provide appropriate implementation within the class. It turned out to be much less code.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消