我有一个递归方法,它被标记为"错误的参数类型"错误,我不明白为什么。首次进入方法时,参数为:
checkMapping(Map<String, Object> inObjectMap,
In object,
List<DataGetter<In, Out>> inObjectDataGetters)
如果需要递归,则递归为:
checkMapping(Map<String, Object> outObjectMap,
Out object,
List<DataGetter<Out, ?>> outObjectDataGetters)
但是在递归时我收到List<DataGetter<Out, ?>> objectDataGetters
的错误:
&#34;错误的第三种参数类型:找到List<DataGetter<Out, ?>> objectDataGetters
:必需List<DataGetter<Out, Out>> objectDataGetters
&#34;
从我的代码中我无法看到我做错了什么以及为什么不接受通配符:
private <In, Out> void checkMapping(Map<String, Object> objectMap,
In object,
List<DataGetter<In, Out>> objectDataGetters) {
for(DataGetter<In, Out> getter : objectDataGetters) {
String key = getter.getDataName();
Out value = getter.getData(object);
List<DataGetter<Out, ?>> valueGetters = getter.getOutGetters();
if(valueGetters.size() == 0) {
//Check mapping is correct
assertThat(objectMap.get(key), isValue(value));
} else {
//Recursion
try {
Map<String, Object> valueMap = (Map<String, Object>) objectMap.get(key);
checkMapping(valueMap, value, valueGetters); //***Error is here***//
} catch (ClassCastException e) {
fail();
}
}
}
}
我正在编写一个测试来测试对象中成员变量到Map<String, Object>
的映射(以测试一些JSON序列化)。 String是变量名,Object是值,如果成员是对象,也可以是Map。我使用上面的递归方法来检查映射是否正确。
DataGetter<In, Out>
是一种调用映射对象的getter方法来比较成员变量值与Map中存储的值的方法:
abstract class DataGetter<In, Out> {
private String mDataName;
private List<DataGetter<Out, ?>> mOutGetters;
public abstract Out getData(In item);
public DataGetter(String dataName) {
mDataName = dataName;
mOutGetters = new ArrayList<>();
}
public DataGetter(String dataName, List<DataGetter<Out, ?>> outGetters) {
mDataName = dataName;
mOutGetters = outGetters;
}
public String getDataName() {
return mDataName;
}
public List<DataGetter<Out, ?>> getOutGetters() {
return mOutGetters;
}
}
OutGetters是getData(In item)
返回的变量的getter,如果恰好是另一个对象。
我希望这是有道理的。我做错了什么?
谢谢, RIZ
修改:解决方案继续下面的ILya回答,我猜它是列表中的外卡。如果我更改签名以获取DataGetter(只是为了看看会发生什么),则没有错误并且ILya的解决方案有效。我猜通配符并不意味着所有元素都可以保证属于同一类型,这就是CheckMapping(。)不接受它的原因。使用Ilya的答案(我已经接受了)我通过将循环中的代码拆分为CheckMappingForGetter来解决这个问题,CheckMappingForGetter调用CheckMappingRecursive进行递归:
private <In> void checkMappingRecursive(Map<String, Object> objectMap,
In object,
List<DataGetter<In, ?>> objectDataGetters) {
for(DataGetter<In, ?> getter : objectDataGetters) {
checkMappingForGetter(objectMap, object, getter);
}
}
private <In, Out> void checkMapping(Map<String, Object> objectMap,
In object,
List<DataGetter<In, Out>> objectDataGetters) {
for(DataGetter<In, Out> getter : objectDataGetters) {
checkMappingForGetter(objectMap, object, getter);
}
}
答案 0 :(得分:0)
您收到此错误是因为checkMapping
方法通过了Type Erasure进程。实际上你的根问题是this。要修复它,您可以从
checkMapping(Map<String, Object> outObjectMap,
Out object,
List<DataGetter<Out, ?>> outObjectDataGetters)
到
checkMappingRecursive(Map<String, Object> outObjectMap,
Out object,
List<DataGetter<Out, ?>> outObjectDataGetters)
并使用它
private <In, Out> void checkMapping(Map<String, Object> objectMap,
In object,
List<DataGetter<In, Out>> objectDataGetters) {
for(DataGetter<In, Out> getter : objectDataGetters) {
String key = getter.getDataName();
Out value = getter.getData(object);
List<DataGetter<Out, ?>> valueGetters = getter.getOutGetters();
if(valueGetters.size() == 0) {
//Check mapping is correct
assertThat(objectMap.get(key), isValue(value));
} else {
//Recursion
try {
Map<String, Object> valueMap = (Map<String, Object>) objectMap.get(key);
checkMappingRecursive(valueMap, value, valueGetters);
} catch (ClassCastException e) {
fail();
}
}
}
}