简体   繁体   English

如何获得 <?> Foo的价值 <?> 宾语?

[英]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<?>对象, foo Foo<T> is an interface. Foo<T>是一个界面。

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> . 请注意,这不是一件容易的事,因为foo可以是类Bar<String>的对象,其中Bar<T> implements Foo<T> ,或实现接口FloatFoo一些anonyomus类,其中FloatFoo extends Foo<Float> I need a solution that works in all cases. 我需要一个适用于所有情况的解决方案。

Thanks in advance :) 提前致谢 :)

This is not possible using reflection because Java Generics has the problem of Type Erasure . 使用反射是不可能的,因为Java Generics存在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. 在运行时,已经删除了为泛型类Foo定义的类型,因此在该类上使用反射将不会产生其泛型类型。 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. C#没有这个问题,可以访问类的模板化类型。

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 . 但是,您可以做的是在使用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 : 例如,如果您的Foo接口声明为:

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. 并且这些信息将反映在反射API中,因为FloatFoo的超类将具有与之关联的一些Type参数。 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 . 但是你会在Angelika的仿制药常见问题解答中获得更完整的信息。

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. 我将所有需要type参数的代码移动到Foo ,因此我可以在类中提供适当的实现。 It turned out to be much less code. 结果证明代码要少得多。

I ended up with creating a getType() method in the interface: 我最终在界面中创建了一个getType()方法:

Class<T> getType();

Maybe it's not the most elegant solution, but definitely the simplest one. 也许它不是最优雅的解决方案,但绝对是最简单的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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