Hi, I am currently calling a method "foo()" that ...
# getting-started
c
Hi, I am currently calling a method "foo()" that is implemented in Java and has a JSpecify NonNull annotation. Unfortunately, it returns null anyways. Currently I am able to call this in kotlin by explicitly specifying the type as Nullable. See:
Copy code
val x: String? = foo()
x?.length
Is this supported behavior in Kotlin? If yes, is this documented somewhere? Or just an implementation detail?
k
To make it clear, does `foo()`:
returns null anyways
or return nullable String anyway? If you know the return value from the Java side won't be null, you can consider adding:
Copy code
val x = checkNotNull(foo()){"Null detected although @NonNull on the Java side"}
r
^you don’t need to add this check, kotlin will do it for you if you explicitly set a non-null type
x : String =
(maybe you don’t even need to set it explicitly because it should be inferred from the NonNull annotation)
k
THX for the heads-up.. missed that part in the doc... @Robert Williams
k
Unfortunately the documentation doesn't seem to answer this question. To be clear, given
@NonNull public static String foo() { return null; }
, this throw an NPE:
Copy code
val x = foo()
but this works without throwing, and prints "null":
Copy code
val x: String? = foo()
println(x)
I couldn't answer the OP's question given the documentation (and the Language Spec doesn't seem to say anything about this either).
👍 1
r
That matches my assumption from reading the documentation but agree that it could be clearer
So using
Nullable/ NonNull
in Java is equivalent to explicitly stating
String?/ String
in kotlin
But if you explicitly state the nullability then the annotation is effectively ignored
And if there’s no annotation and you don’t state a type you get the platform type (which may cause bugs and crashes later)
k
This means that the following two methods behave differently, when intuitively you'd expect them to be the same:
Copy code
fun bar1(): String? {
    val x = foo()
    return x
}

fun bar2(): String? {
    return foo()
}
🤯 1
c
Thanks for all your input! For my specific usecase, I found another solution. But anyways I feel like at least the spec should clarify this. Especially the sample of @Klitos Kyriacou looks scary!