2

I have converted my old java model class to kotlin data class. Some of objects are annotated with @NonNull in java. My question is if null is passed from our backend in my data class what will happen? Does making this username nullable can help in preventing crash if null is passed?

Java code:

public abstract class Comment(){
@NonNull
public abstract String username();
}

Kotlin code:(what happen in this case if null is passed?)

data class Comment(val username: String)

Kotlin code:(it can handle null)

data class Comment(val username: String?)
Praful Ranjan
  • 117
  • 1
  • 2
  • 13
  • @NonNull is the opposite of marking a variable with ? (nullable). Right now with your Kotlin code nothing will happen. In your app code you may want to provide an alternative text or action when `username` is null. – Zun Feb 11 '19 at 12:20
  • what happens if my code is like this [data class Comment(val username: String)]. If null is passed to it what will happen? @ZUNJAE – Praful Ranjan Feb 11 '19 at 12:29

2 Answers2

3

In java - everything will compile and give a warning

In kotlin - your compiler won't let you pass null to nullable or @notnull annotated type

For example:

public static boolean isUserLoggedIn(@NotNull ctx: Context) {
    return ...
}

// Kotlin Invocation
fun main(args: Array<String>) {
    isUserLoggedIn(null)
}

And compilation error:

e: C:\_projects\test.kt: (37, 37): Null can not be a value of a non-null type Context
:app:compileDebugKotlin FAILED

FAILURE: Build failed with an exception.

In Java you are able to call this java-method with no compile error but your IDE should show warning (passing null to parameter annotated as @notnull). Also, in Java you can pass null parameters to notnull kotlin methods. It'll compile and give a warning.

Kotlin supports some of annotations (like JetBrains, Android, Eclipse). The full list can be found here: https://kotlinlang.org/docs/reference/java-interop.html#nullability-annotations

Edit 1 - regarding the comment:

It depends if runtime null check is enabled or not. Kotlin, to ensure null safety in generated code adds kotlin.jvm.internal.Intrinsics.checkNotNull call.

See: https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/Intrinsics.java

If value is null NPE will be thrown. So, NPE will be thrown every time null is passed. Every time, even if your code could handle null value.

But, you can disable this check. Then, your code will be small lighter, and also won't throw exception every time null is passed. But you will lose a lot of profits from null safety, and it's also shows that something is bad in your design.

See how: Disable not null checks in Kotlin

Cililing
  • 4,303
  • 1
  • 17
  • 35
  • 1
    Correct kotlin doesn't allow to pass `null` value to `NotNull` parameter but the question is if some null data is passed to it from backend which is dynamic in nature then what will happen? – Praful Ranjan Feb 12 '19 at 06:16
  • I've added little explanation to your comment. – Cililing Feb 12 '19 at 08:52
2

Kotlin type system tells a nullable type from a not-nullable type. A declaration like x: String? means null is allowed (same as it was in Java)

The declaration x: String means you do not accept nulls. Kotlin compiler takes care of it and it will try it's best to discard any incorrect code, that tries setting null there.

Kotlin compiler understands annotations like @Nullable or @NotNull: see the documentation for more details https://kotlinlang.org/docs/reference/java-interop.html#nullability-annotations

Of course, there are ways to call a nun-nullable method with null value (e.g. via Java Reflection or just from another JVM language). To protect from that, Kotlin Compiler emits null checks automatically, and the code will fail-fast.

Eugene Petrenko
  • 4,874
  • 27
  • 36