因此,我使用的组减少了我们为某些事情键入的代码量。在这种情况下,Spring网页使用DisplayTag库显示列表。它的完成方式是使用泛型扩展Controller
对象的类,然后是它应该处理的每个页面的子类。
此控制器显示SystemErrorReport
,并将类型定义为SystemErrorReportCommand
。
public class SystemErrorReportController extends
GenericSearchAndSelectController<SystemErrorReportCommand> {
问题是SystemErrorReportCommand
作为一个类型传递,需要在其构造函数中有一个自己的手动声明,如下所示:
public SystemErrorReportCommand()
{
super(SystemErrorReport.class);
}
稍后将命令对象传递给需要知道其显式类型的东西。如果没有在某处手动指定它,它会返回GenericCommand
,这是我们的另一个类,因为SystemErrorReportCommand
位在编译时丢失了。
我对此并不感到兴奋,因为看起来我们可以进一步自动化以减少开发人员错误。有没有更优雅的方法来做到这一点,还是我因为类型擦除而坚持这个?
答案 0 :(得分:4)
与广泛接受的内容相反,可以避免很少知道的类型擦除,这意味着被叫方确实能够知道在呼叫期间使用了哪些通用参数。
请看看: Using TypeTokens to retrieve generic parameters
由于
答案 1 :(得分:3)
即使在擦除完成后,仍然可以从:Field,Method(包括方法参数)和使用反射的类中检索通用信息。
例如,可以使用
从SystemErrorReportController检索SystemErrorReportCommand。((ParameterizedType) SystemErrorReportController.class.getGenericSuperType()).getActualTypeArguments[0];
尽管如此,这只是一个开始。你需要开始使用反射api来利用这些信息,所以如果你不期待这样的事情,你的设计很可能会受到影响。
以下是您可以在运行时提取的一个小例子:
public abstract class Test<T extends Number> extends ArrayList<Long> implements Comparable<String>, List<Long>{
public List<String> field;
public abstract <M> M method(List<T> arg);
public static void main(String... args) throws Exception {
TypeVariable<Class<Test>> 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<T extends java.lang.Number>
extends java.util.ArrayList<java.lang.Long>
implements [java.lang.Comparable<java.lang.String>, java.util.List<java.lang.Long>]
{
public abstract <M> M Test.method(java.util.List<T>)
public java.util.List<java.lang.String> Test.field
}
我正在使用toGenericString()
方法。然而,这只是一种漂亮的打印方法!无需解析该String:reflection api提供了所有必要的信息,例如:Field.getGenericType()
,Method.getArgumentTypes
,...
答案 2 :(得分:1)