使用java classmate解析泛型类型
在尝试使用TypeTools失败之后,我正尝试使用它 有人能帮我修复这个代码吗使用java classmate解析泛型类型,java,generics,classmate,Java,Generics,Classmate,在尝试使用TypeTools失败之后,我正尝试使用它 有人能帮我修复这个代码吗 public T fromMap(S map) { TypeResolver typeResolver = new TypeResolver(); ResolvedType type = typeResolver.resolve((new MapperImpl<T, S>() {}).getClass()); List<ResolvedType> par
public T fromMap(S map) {
TypeResolver typeResolver = new TypeResolver();
ResolvedType type = typeResolver.resolve((new MapperImpl<T, S>() {}).getClass());
List<ResolvedType> params = type.typeParametersFor(MapperImpl.class);
ResolvedType typeT = params.get(0);
ObjectMapper objectMapper = new ObjectMapper();
T obj = objectMapper.convertValue(map, (Class<T>) typeT.getErasedType());
return obj;
}
public T fromMap(S map){
TypeResolver TypeResolver=新的TypeResolver();
ResolvedType type=typeResolver.resolve((新的MapperImpl(){}).getClass());
List params=type.typeparameters(MapperImpl.class);
ResolvedType typeT=params.get(0);
ObjectMapper ObjectMapper=新的ObjectMapper();
T obj=objectMapper.convertValue(map,(Class)typeT.get橡皮擦类型());
返回obj;
}
我得到这个错误:
无法将java.util.LinkedHashMap强制转换为LoginInputMapTest$Foo
java.lang.ClassCastException位于
shouldmaptoo(LoginInputMapTest.java:83)
使用此最小测试用例:
public static class Foo {
private String a;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
}
@Test
public void shouldMapToFoo() {
Map<String, Object> map = new HashMap<>();
map.put("a", "aaa");
Mapper<Foo, Map<String, Object>> mapper = new MapperImpl<>();
Foo foo = mapper.fromMap(map);
Assert.assertEquals(foo.getA(), map.get("a"));
}
公共静态类Foo{
私人字符串a;
公共字符串getA(){
返回a;
}
公共空集a(字符串a){
这个a=a;
}
}
@试验
public void shouldMapToFoo(){
Map Map=newhashmap();
地图放置(“a”、“aaa”);
Mapper Mapper=新的MapperImpl();
Foo-Foo=mapper.fromMap(map);
Assert.assertEquals(foo.getA(),map.get(“a”);
}
在fromMap
方法中,无法获取绑定到类型变量T
的类型参数
我建议您专门为Foo
创建一个Mapper
实现
class FooMapperImpl<S> implements Mapper<Foo, S> {
public Foo fromMap(S map) {
ObjectMapper objectMapper = new ObjectMapper();
Foo obj = objectMapper
.convertValue(map, Foo.class);
return obj;
}
}
类FooMapperImpl实现映射器{
公共Foo fromMap(S地图){
ObjectMapper ObjectMapper=新的ObjectMapper();
Foo obj=对象映射器
.convertValue(映射,Foo.class);
返回obj;
}
}
(虽然我不明白为什么您需要源类型
S
,如果它始终是Map
)在我看来,您似乎不完全了解Java泛型类型在类型变量方面的工作方式(t
,S
)。了解更多信息的好地方是:
但基本上类型变量不携带任何运行时泛型类型信息。因此,当您名义上调用具有特定参数化的方法时,除非您传递实际的Class
合适的参数化实例,否则不会发生任何事情。因此,编译成字节码的方法只不过是:
public Object fromMap(Object map) { ... }
现在,如果将Map
作为Map
传递,则运行时类型将只是Map.class
,并且没有指定类型参数:Java值没有任何运行时类型参数化信息。底层类在Map
和Map
之间是相同的。参数声明只影响Java编译器,它添加了必要的强制转换,以确保值类型得到正确的强制转换
不幸的是,没有一个图书馆能找到那里的信息。因此,您建议的用法不可能按原样实现
这并不意味着你不能通过打字,但它意味着它必须从外部通过。使用basic Jackson,您可以使用TypeReference
:
new TypeReference<Map<KeyType, ValueType>>() { };
现在:
ClassMate
可以从类定义中提取类型信息。如果您有一个带有字段的类,即使用泛型类型声明的方法,则很难找到声明的参数化。但听起来这并不是你真正想要或需要的。相反,您应该能够使用Jackson的类型处理功能构建它。您的MapperImpl有什么作用吗?看起来您创建了一个匿名类而没有实际访问它。或者这只是一个缩写?匿名类是用来提供子类型的。我认为您需要它来解析泛型类型。看这个例子:你是对的,没有必要用S参数化映射器接口。为什么你说我无法得到类型T。这不是像TypeTools和classmate这样的库的目的吗?我试图做的正是他们在“4.真实世界用法”@dmz73中描述的,这看起来完全不同。他们可以从处理程序
中提取类型。但是您的fromMap
方法没有任何内容可用于提取为T
提供的类型参数。
mapper.getTypeFactory().constructMapType(Map.class, KeyType.class, ValueType.class);
// or with recursively constructing nested generic types