Котлин повторяемый
Учитывая этот класс:
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
Это вполне разрешено, и, очевидно, безопасно.