Search code examples
javaandroidkotlincallnullable

How can i know when calling a java method from Kotlin if a nullable argument should be checked at call site?


As a junior programmer who needs to pass from java to Kotlin, I'm asking a lot of questions about the Integration between Kotlin and Java. I have read the following link: Calling Java From Kotlin

but it seems that I still have difficulty when calling a java method. For example if I have a TextView in my Kotlin code:

 val secondaryTextColor : Int? = weakReferenceContext.get()?.resources?.getColor(R.color.secondary_text_color)
 secondaryTextColor?.let {
     holder.someTextView.setTextColor(it)
 }

The code above won't be compiled without the let block. If I tried to compile without the let, It will cause a compilation error saying the setTextColor expected an Int but get an Int? I'm looking in the java source code, and there is any place that is written the int parameter can't be null. So the only way that I have to know that may be a problem is by the editor or by compiling and getting the error. I'm asking if the is a way that from the java source code I will be able to know if the method will accept a nullable argument or not. I hope the way I wrote the post is clear what I'm asking and if not please tell me and I will try to elaborate it, cause I really need to understand once and forever


Solution

  • What is the return type of weakReferenceContext.get()?.resources?.getColor(R.color.secondary_text_color)?

    It is an Int? (a nullable Int).

    So secondaryTextColor has a type of Int?, if you want to use it as a parameter in a function that expects type Int (like your someTextView.setTextColor) you have to find a way around it.

    Why does TextView#setTextColor require a non-null parameter? If you look at the docs you can see it has the following signature:

    public void setTextColor(@ColorInt int color)
    

    In the signature, int is a primitive type in Java. There is no opportunity for this to be null. Hence, Kotlin interprets this as:

    fun setTextColor(@ColorInt color: Int)
    

    There are different ways to get around nullability here. One way is using the let block. Please have a look at the official docs on null safety to learn more

    Addendum: @ColorInt is an annotation. Ints representing colors can be references to resources @ColorRes or a color that represents a packed ARGB. See the docs here