7

给定这个类:

data class CSVRecord(private val columns: SortedSet<CSVColumn>) : Iterable<String> {

    override fun iterator(): Iterator<String> {
        return columns.map { it.value }.iterator()
    }
}

spotbugs 引发错误:

[错误] 在 com.example.CSVRecord.iterator() [com.example.CSVRecord] 在 CSVRecord.kt:[第 15 行] BC_BAD_CAST_TO_ABSTRACT_COLLECTION 中从 Collection 到抽象类 java.util.List 的可疑转换

这仅仅是因为 spotbugs 不支持 Kotlin,还是我的实现可能无效?

4

1 回答 1

12

FindBugs 处理字节码,然后反向查找文件和行信息。似乎 Kotlin 编译器发出了一条CHECKCAST指令,从 Kotlin 的角度来看,很明显转换会通过,但 Java 方法的返回类型声明或声明的局部变量/参数类型更广泛。

这是我从 IDEA 获得的反编译的 Kotlin 字节码,用于您的函数:

@NotNull
public Iterator iterator() {
    Iterable $receiver$iv = (Iterable)this.columns;
    Collection destination$iv$iv = (Collection)
            (new ArrayList(collectionSizeOrDefault($receiver$iv, 10)));
    Iterator var4 = $receiver$iv.iterator();

    while(var4.hasNext()) {
        Object item$iv$iv = var4.next();
        CSVColumn it = (CSVColumn)item$iv$iv;
        String var11 = it.getValue();
        destination$iv$iv.add(var11);
    }

    return ((List)destination$iv$iv).iterator();
}

您可以看到该声明inline fun map在此级别上的含义:它的整个代码成为您方法实现的一部分。发出的字节码恰好使用一个Collection-typed 变量destination$iv$iv来保存对ArrayList. 该return语句将其转换为List,这是完全允许的,并且显然是安全的。

于 2018-05-21T16:27:34.737 回答