Rad*_*dim 3 java reflection collections dwr type-erasure
我想请求一个项目类的集合(一种特定的反射).但关于类型擦除似乎是不可能的,也是关于我在堆栈上阅读的一些主题.有一些解决方法(这里),但我很好奇是否有人知道如何通过DWR完成它:
http://directwebremoting.org/dwr/documentation/server/configuration/dwrxml/signatures.html
或者如果有一些更好的解决方法,它会很棒.
假设我们有类似的东西:
public String foo(List<String> possibleFoos) {
Run Code Online (Sandbox Code Playgroud)
我需要的是找出参数possibleFoos是字符串列表,而不仅仅是List
虽然Java确实会在运行时擦除类型(因此List<String>变为公正List),但在许多情况下,它实际上会在运行时存储泛型类型,从而允许您恢复丢失的信息以进行擦除.您可以检索这些的实际泛型类型:
这意味着如果你只是一个List类型的对象,那么你无法做任何事情来获得它的泛型类型(object.getClass()会得到你List而且就是这样) - 它已经永久丢失了.但是,如果您试图找出方法参数或上述任何一种的泛型类型,通常可以使用反射.由于您的案例不涉及类型变量或其他复杂情况,因此获取实际类型非常简单:
ParameterizedType listArgument = (ParameterizedType) ClassDeclaringFoo.class.getMethod("foo", List.class).getGenericParameterTypes()[0];
Type listType = listArgument.getActualTypeArguments()[0]; //This will be a Class representing String, the type of the List
Run Code Online (Sandbox Code Playgroud)
如果您有更多参数和地图:
public String foo(Object bar, Map<String, Number> possibleFoos) { ... }
Run Code Online (Sandbox Code Playgroud)
代码类似:
ParameterizedType mapArgument = (ParameterizedType) ClassDeclaringFoo.class.getMethod("foo", Object.class, Map.class).getGenericParameterTypes()[1]; //1 is the index of the map argument
Type keyType = mapArgument.getActualTypeArguments()[0]; //This will be a Class representing String, the type of the Map key
Type valType = mapArgument.getActualTypeArguments()[1]; //This will be a Class representing Number, the type of the Map value
Run Code Online (Sandbox Code Playgroud)
可以安全地假设这也是DWR正在使用的,因为类型是方法参数.
其他列出的案例也有类似的方法:
Class.getMethod(...).getGenericReturnType() 会得到真正的回报类型Class.getField(fieldName).getGenericType() 将为您提供该领域的真实类型Class.getGenericSuperClass() 会给你真正的超级类型Class.getGenericInterfaces() 将为您提供真正的界面类型存在允许访问AnnotatedTypeJava 8中引入的(类型用法的泛型类型和注释)的等效方法:
Class.getMethod(...).getAnnotatedParameterTypes()Class.getMethod(...).getAnnotatedReturnType()Class.getField(fieldName).getAnnotatedType()Class.getAnnotatedSuperClass()Class.getAnnotatedInterfaces()现在,当您的案例如示例中那样简单时,这就是花花公子.但是,想象一下如果您的示例看起来像这样:
public T foo(List<T> possibleFoos) {...}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,getGenericParameterTypes()[0].getActualTypeArguments()[0]会给你T哪个是无用的.要解决T代表什么,你必须查看类定义,也许是超类,同时跟踪每个类中类型变量的命名方式,因为每个类中的名称可能不同.
为了更容易地使用泛型类型反射,你可以使用一个名为GenTyRef的精彩库为你做艰苦的工作,如果你需要AnnotatedTypes的支持,你可以使用我的名为GeAnTyRef的 fork (两者都在Maven Central中).它们还包括一个类型工厂,它允许您构建(Annotated)Type使用普通Java API无法轻松完成的实例.还有一个方便的超类型令牌实现,允许您获得(Annotated)Type文字.
有了这些,您可以使用Java允许的泛型类型执行所有操作,而无需我上面解释过的麻烦:
GenericTypeReflector#getExactParameterTypes( ... )GenericTypeReflector#getExactReturnType( ... )GenericTypeReflector#getExactFieldType( ... )GenericTypeReflector#getExactSuperType( ... )还有更多的操作,比如确定一个Type是另一个的超类型(类似于Class#isAssignableFrom泛型类型),解析特定的类型变量等.
| 归档时间: |
|
| 查看次数: |
186 次 |
| 最近记录: |