Котлин повторяемый

Учитывая этот класс:

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

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

Spotbugs вызывает ошибку:

[ОШИБКА] Сомнительное приведение из коллекции в абстрактный класс java.util.List в com.example.CSVRecord.iterator() [com.example.CSVRecord] В CSVRecord.kt:[строка 15] BC_BAD_CAST_TO_ABSTRACT_COLLECTION

Это только потому, что плагины не поддерживают Kotlin, или моя реализация потенциально недействительна?

1 ответ

Решение

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переменная destination$iv$iv держать ссылку на ArrayList, return заявление бросает это ListЭто вполне разрешено, и, очевидно, безопасно.

Другие вопросы по тегам