【发布时间】:2015-02-12 17:49:21
【问题描述】:
我正在尝试编写一个带有注释的简单验证库,该库使用 Java 8 中的新 TYPE_USE 目标。访问这些东西的方式非常复杂,并且给我留下了两个非常混乱的代码,它们的功能完全相同,但也与他们实际要做的事情非常相关。所以我决定创建一组简单的类来以非常简单和直观的方式保存这些信息。基本上有 TypedClass,它是一个类包装器,但它可以转换为 ListClass(集合或数组)或 MapClass 以作为 TypedClass 访问其组件(或键/值)。最重要的部分是应该转换的这个助手:
static TypedClass<?> create(Field f) {
final TypeResolver typeResolver = new TypeResolver();
ResolvedType type = typeResolver.resolve(f.getGenericType());
return create(f.getAnnotations(), type, f.getAnnotatedType());
}
private static TypedClass<?> create(Annotation[] annotations, ResolvedType type, AnnotatedType at) {
if (type.isArray()) {
AnnotatedType childAnnotatedType = ((AnnotatedArrayType) at).getAnnotatedGenericComponentType();
ResolvedType childType = type.getArrayElementType();
return new ListClass<>(type.getErasedType(), annotations, create(at.getAnnotations(), childType, childAnnotatedType));
} else if (type.isInstanceOf(Collection.class)) {
AnnotatedType childAnnotatedType = ((AnnotatedParameterizedType) at).getAnnotatedActualTypeArguments()[0];
ResolvedType childType = type.typeParametersFor(Collection.class).get(0);
return new ListClass<>(type.getErasedType(), annotations, createForGenerics(childType, childAnnotatedType));
} else if (type.isInstanceOf(Map.class)) {
AnnotatedType[] att = ((AnnotatedParameterizedType) at).getAnnotatedActualTypeArguments();
List<ResolvedType> types = type.typeParametersFor(Map.class);
TypedClass<?> key = createForGenerics(types.get(0), att[0]);
TypedClass<?> value = createForGenerics(types.get(1), att[1]);
return new MapClass<>(type.getErasedType(), annotations, key, value);
}
return new TypedClass<>(type.getErasedType(), annotations);
}
private static TypedClass<?> createForGenerics(ResolvedType childType, AnnotatedType childAnnotatedType) {
return create(childAnnotatedType.getAnnotations(), childType, childAnnotatedType);
}
这里我也是使用 com.fasterxml.classmate 中的 ResolvedType,它只是用来在 Java 中的 Type 和 Class 之间架起桥梁,这也是一种痛苦。我认为这与问题无关,因为生成的结构还可以,只是注释放错了位置。
它似乎工作得很好,除非 List 或 Map 中有一个数组。例如:
@First("array") List<@First("string") String> @First("list") [] arrayOfListOfString;
工作正常(注释与相应的类型匹配)。但是当我解析时
List<@First("int[]") Integer @First("int") []> listOfArrayOfInteger;
数组和整数都与@First("int") 注释相关联。
我已经调试了我的代码,但在任何地方都找不到对 @First("int[]") 注释的引用。我要么错过了一些非常简单的东西,要么没有任何意义。该代码似乎适用于其他所有场景,即使是更复杂的场景。几周以来我一直在尝试这样做,最近才找到我认为可行的解决方案。原来我之前的两种耦合方法也不适用于这种情况(没有这个特定的测试)。所以现在我很困。
怎么了?
【问题讨论】:
标签: java arrays generics annotations java-8