在Java中使用Type Erasure

因此,我使用的组减少了我们为某些事情键入的代码量。 在这种情况下,Spring网页使用DisplayTag库显示列表。 它的完成方式是使用generics扩展Controller对象的类,然后是它应该处理的每个页面的子类。

此控制器显示SystemErrorReport ,并将类型定义为SystemErrorReportCommand

 public class SystemErrorReportController extends GenericSearchAndSelectController { 

问题是,作为一个类型传递的SystemErrorReportCommand需要在其构造函数中有一个自己的手动声明,如下所示:

 public SystemErrorReportCommand() { super(SystemErrorReport.class); } 

稍后将命令对象传递给需要知道其显式类型的东西。 如果没有在某处手动指定它,它会返回GenericCommand ,这是我们的另一个类,因为SystemErrorReportCommand位在编译时丢失。

我对此并不感到兴奋,因为我们可以进一步自动化以减少开发人员的错误。 有没有更优雅的方法来做到这一点,还是我因为类型擦除而坚持这个?

也许你可以使用类似Javassist的东西来做一些元编程。

它在Tapestry中用于此目的,请参阅此文章。

与广泛接受的相反,可以避免很少已知的类型擦除,这意味着被叫方确实能够知道在呼叫期间使用了哪些通用参数。

请看一下: 使用TypeTokens检索通用参数

谢谢

即使在擦除完成后,仍然可以从:Field,Method(包括方法参数)和使用reflection的类检索通用信息。

例如,可以使用从SystemErrorReportController检索SystemErrorReportCommand

 ((ParameterizedType) SystemErrorReportController.class.getGenericSuperType()).getActualTypeArguments[0]; 

不过,这只是一个开始。 你需要开始使用reflectionapi来使用那些信息,所以如果你不期待这样的事情,你的设计很可能会受到影响。

以下是您可以在运行时提取的一个小例子:

 public abstract class Test extends ArrayList implements Comparable, List{ public List field; public abstract  M method(List arg); public static void main(String... args) throws Exception { TypeVariable> t = Test.class.getTypeParameters()[0]; Class upperBound = (Class) t.getBounds()[0]; System.out.println("Test<" + t + " extends " + upperBound.getName() + ">"); System.out.println("extends " + Test.class.getGenericSuperclass()); System.out.println("implements " + Arrays.toString(Test.class.getGenericInterfaces())); System.out.println("{"); System.out.println(Test.class.getMethods()[1].toGenericString()); System.out.println(Test.class.getFields()[0].toGenericString()); System.out.println("}"); } } 

这将输出:

 Test extends java.util.ArrayList implements [java.lang.Comparable, java.util.List] { public abstract  M Test.method(java.util.List) public java.util.List Test.field } 

我正在使用toGenericString()方法。 然而,这只是一种漂亮的打印方法! 无需解析该String:reflection api提供了所有必要的信息,例如: Method.getArgumentTypes Field.getGenericType()Method.getArgumentTypes ,…