Sonar报错:List<AggregateFunction>无法容纳SummarizingFunction求助
问题:Sonar检测Java代码类型不匹配报错
问题代码
private Table sliceTable(Table table, String[] columns, Map<DependencyKey, List<F>> reportFields) { TableSliceGroup tableSlices = table.splitOn(columns); ListMultimap map = ArrayListMultimap.create(); reportFields .entrySet() .stream() .filter(entry -> !entry.getKey().getDependencyType().equals(ReportingDependency.SELF) || !entry.getKey().getDependencyType().equals(ReportingDependency.SELF_WITH_CHECKPOINT)) .flatMap(entry -> entry.getValue().stream().map(it -> Pair.of(entry.getKey().getDependencyType(), it))) .flatMap(pair -> pair.getRight().getDependencyDefinitions().stream().map(depDef -> Triple.of(pair.getLeft(), pair.getRight(), depDef))) .filter(triple -> triple.getRight().getClientName().equals(triple.getLeft())) .flatMap(triple -> triple.getRight().getFields().stream().map(it -> Triple.of(triple.getMiddle(), triple.getRight(), it))) .filter(triple -> TableUtils.containsColumn(table, triple.getMiddle().getClientName(), triple.getRight())) // This filters out the unresolved columns .forEach(triple -> { List<AggregateFunction<?, ?>> aggFuncList = map.get(TableUtils.getColumnNameFromTable(table, triple.getMiddle().getClientName(), triple.getRight())); if (!aggFuncList.contains( TableUtils.getAggregationFunction( TableUtils.getColumnFromTable(table, triple.getMiddle().getClientName(), triple.getRight()).type(), triple.getRight().getAggregation()))) { map.put(TableUtils.getColumnNameFromTable(table, triple.getMiddle().getClientName(), triple.getRight()), TableUtils.getAggregationFunction( TableUtils.getColumnFromTable(table, triple.getMiddle().getClientName(), triple.getRight()).type(), triple.getRight().getAggregation())); } }); Table slicedTable = TableSummarizer.aggregate(tableSlices, map, columns); return slicedTable; }
Sonar报错信息
if (!aggFuncList.contains( TableUtils.getAggregationFunction( A "List<AggregateFunction>" cannot contain a "SummarizingFunction".
SummarizingFunction抽象类定义
public abstract class SummarizingFunction<INCOL extends Column<?>, OUT> { private final String functionName; /** Constructs a function with the given name */ public SummarizingFunction(String functionName) { this.functionName = functionName; } /** Returns this function's name */ public String functionName() { return functionName; } /** Apply this function to the column argument */ public abstract OUT summarize(INCOL column, int[] indices); public String toString() { return functionName(); } /** Returns the {@link ColumnType} to be used for the values returned by this function */ public abstract ColumnType returnType(); }
问题分析
- 类型不匹配:
aggFuncList声明为List<AggregateFunction<?, ?>>,但TableUtils.getAggregationFunction()返回的是SummarizingFunction(或其子类),两者之间没有继承/实现关系,导致contains方法无法进行类型安全的判断,Sonar检测到该类型不兼容问题。 - 原始类型隐患:代码中
ListMultimap map使用了原始类型,未指定泛型参数,后续强制转换为List<AggregateFunction<?, ?>>会引发类型安全警告,同时加剧了类型不匹配问题。
解决方案
1. 修正泛型声明,统一类型
将ListMultimap的声明改为带具体泛型的形式,确保集合元素类型与getAggregationFunction()的返回类型一致:
// 替换原始类型声明 ListMultimap<String, SummarizingFunction<?, ?>> map = ArrayListMultimap.create(); // 同步修改aggFuncList的类型 List<SummarizingFunction<?, ?>> aggFuncList = map.get(TableUtils.getColumnNameFromTable(table, triple.getMiddle().getClientName(), triple.getRight()));
2. 明确AggregateFunction与SummarizingFunction的继承关系
如果业务逻辑中AggregateFunction是SummarizingFunction的具体实现,需要补全继承关系:
public class AggregateFunction<INCOL extends Column<?>, OUT> extends SummarizingFunction<INCOL, OUT> { // 实现summarize和returnType抽象方法 @Override public OUT summarize(INCOL column, int[] indices) { // 业务逻辑实现 } @Override public ColumnType returnType() { // 返回对应类型 } }
这样AggregateFunction可以向上转型为SummarizingFunction,类型匹配问题自然解决。
3. 优化equals方法,确保contains判断准确
当前SummarizingFunction仅重写了toString(),contains()默认依赖对象引用判断是否存在,可能不符合业务预期。建议重写equals()和hashCode()方法,基于业务标识字段(如functionName和returnType)判断:
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; SummarizingFunction<?, ?> that = (SummarizingFunction<?, ?>) o; return Objects.equals(functionName, that.functionName) && Objects.equals(returnType(), that.returnType()); } @Override public int hashCode() { return Objects.hash(functionName, returnType()); }
内容的提问来源于stack exchange,提问作者Scientist
相关产品推荐
相关产品推荐

