简体   繁体   English

是否有可能克服Java中的类型擦除?

[英]Is it possible to somehow overcome type erasure in Java?

Here's the thing. 就是这个 We use a lot of Wicket Panels in our application, and for testing purposes they should ideally be generated generically. 我们在应用程序中使用了许多Wicket面板,并且出于测试目的,理想情况下应以通用方式生成它们。 Part of this works, in theory: For every parameter type in a constructor I have only one possible argument to offer, so it is a matter of finding what these parameter types are - Reflection. 从理论上讲,部分工作原理是:对于构造函数中的每个参数类型,我只能提供一个可能的参数,因此查找这些参数类型是什么是一个问题-反射。 Problem being: Type Erasure. 问题是:类型擦除。 Many of the constructors use multiple versions of the Model< > class as parameters with various different type parameters to it. 许多构造函数使用Model <>类的多个版本作为参数,并带有各种不同的类型参数。 Type Erasure means that as far as I can find I have no way to differentiate between these at runtime. Type Erasure表示,据我所知,我无法在运行时区分这些类型。 So, in this situation, is there any way to overcome or circumvent type erasure? 因此,在这种情况下,是否有任何方法可以克服或规避类型擦除?

You have a problem long before you use reflection and if you fix this, you not longer need to worry. 您在使用反射之前就已经有问题了,如果您解决了这个问题,就不再需要担心。

As there is no way to tell the difference between Model<A> and Model<B> you cannot overload two methods or constructors with these types. 由于无法区分Model<A>Model<B>之间的区别,因此您无法重载具有这些类型的两个方法或构造函数。 Instead you need to create one method which takes a Model<C> where C is the super class/interface of A and B. 相反,您需要创建一个采用Model<C>方法,其中C是A和B的超类/接口。

You can't do this 你做不到

interface A extends C { }
interface B extends C { }

class MyClass {
    MyClass<Model<A> modelA) { }
    MyClass<Model<B> modelB) { }

This won't compile as they have the same signature after erasure so instead you can do 由于它们在擦除后具有相同的签名,因此无法编译,因此您可以这样做

class MyClass {
    MyClass<Model<? extends C> model) { }

Not only does this compile but there is no ambiguity at runtime. 这不仅可以编译,而且在运行时没有歧义。

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

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