When i try to use Collections.addAll method like this:
val articleList1: MutableList<Article> = mutableListOf()
articleList1.addAll(articleList2) // articleList2's type is List<Article> define in java
Compiler complain that ’ type inference failed, please try to specify type arguments explicitly’, which means it use the method public fun <T> kotlin.collections.MutableCollection<in T>.addAll(elements: kotlin.collections.Iterable<T>): kotlin.Boolean
in CollectionsKt.class.
But when i try to specify type for the function:
articleList1.addAll<Article>(articleList2)
Wrong message is ‘No type arguments expected’, which means it use the method public abstract fun addAll(elements: kotlin.collections.Collection<E>): kotlin.Boolean
of MutableList class .
So, what can i do?
Could you clarify, how do you declare the variable articleList2
?
Just List<Article> articleList2
This is an property in java bean.
I wasn’t able to reproduce it with Kotlin 1.0.0. Here is what I’ve tried.
Articles.kt file:
class Article
fun useArticles(bean: ArticleBean) {
val articleList1: MutableList<Article> = mutableListOf()
articleList1.addAll(bean.articleList)
articleList1.addAll<Article>(bean.articleList)
}
ArticleBean.java file:
import java.util.Collections;
import java.util.List;
public class ArticleBean {
public List<Article> getArticleList() {
return Collections.emptyList();
}
}
Both the member addAll
and the extension addAll
are being resolved correctly.
Is there something different in your case?
Yes, the only diffrent thing i guess is that my instance of ArticleBean is nullable.
And when i try use non-nullable references it works.
So, can you reproduce this problem now?
Is there any good suggestion?
So, you’re invoking its articleList
property with a safe-call, like this?
articleList1.addAll(bean?.articleList)
articleList1.addAll<Article>(bean?.articleList)
In this case I do see a type mismatch error in both cases (it is reported on arguments), and errors you have mentioned in the first post on addAll
.
The observed behavior is as it should be: addAll
expects a List<T>
as an argument, and you’re passing List<T>?
, which is a result of a safe-call.
When you have a nullable variable of type List<T>?
you can eliminate null
either with the !!
operator, or with the elvis-operator ?:
or with the special extension function orEmpty
defined for lists:
bean!!.articleList // throws NPE if bean is null
bean?.articleList!! // throws NPE if bean is null or returned list is null
bean?.articleList.orEmpty() // results in emptyList instead of null
bean?.articleList ?: emptyList() // basically same as above
You can read more about null-safety in the docs:
https://kotlinlang.org/docs/reference/null-safety.html
https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types
and on StackOverflow:
In Kotlin, what is the idiomatic way to deal with nullable values, referencing or converting them
Thanks for your replies.
As your description i should provide a non-nullable argument for addAll
, and i know how to do it.
But which mislead me is the compiler give me wrong information, which you & kotlin team should care for.