Explicit nulls and user input

I quite like the explicit nulls feature, but I’m wondering just how far they can eliminate the need to check function arguments for null.

For example, if I opt in to -Yexplicit-nulls and write a library with an API function that accepts a String argument, do I still need to check that argument for null?

If someone used my library from a Java program, it seems very plausible that they could pass in a null. So it seems to me that I should still guard against that condition.

However, I’m not entirely sure how I should do this. If I try to check the argument for null, then the compiler tells me:

Values of types String and Null cannot be compared with == or !=

Is there a way around this? Or is -Yexplicit-nulls a feature only intended for self-contained programs?

Or perhaps there’s something in the generated bytecode that does the null check?

Many thanks!

1 Like

Yup. There’s a lengthy section on Java interop in the docs, but this only covers calling Java from Scala.

Calling Scala from Java just yields a good old NPE:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "$this" is null
	at scala.collection.StringOps$.$times$extension(StringOps.scala:658)
	at de.sangamon.expnulls.ExpNullLib$.twice(ExpNullLib.scala:9)

It’s been ages since I’ve called Scala code from Java, but I recall that there’s a strong incentive to introduce a Java specific external API layer that hides Scala specific types, enforces null checks, etc., anyway. In such a layer, you could resort to unsafeNulls, e.g.

def twiceJ(s: String): String =
  import scala.language.unsafeNulls
  Option(s).map(PureScalaAPI.twice).getOrElse(null)
2 Likes