13

I am creating my Scala bean which is a configuration to be loaded from a YML config. I want a long property to be null if not specified, but I'm facing below issue. Any idea why?

startOffset: Integer = null
scala> var endOffset: Long = null
<console>:11: error: an expression of type Null is ineligible for implicit conversion
   var endOffset: Long = null
                         ^`

PS: Yes I can use Option[Long] but wanted clarity and is there anything wrong with this approach.

lospejos
  • 1,976
  • 3
  • 19
  • 35
mukh007
  • 339
  • 1
  • 6
  • 17
  • 2
    Yes, there is something wrong with this approach. `Null` is an unfortunate legacy from Java and should never be used in original Scala code. You are just begging for run-time errors. – Michael Lorton Aug 29 '16 at 18:15

3 Answers3

27

Scala Long is literal data type like long in Java. Same is true for Int. But Integer is a Wrapper class i.e java.lang.Integer

If you want nullable Long value, you can use java.lang.Long

TheKojuEffect
  • 20,103
  • 19
  • 89
  • 125
  • I gueesed so, based on the class def. This is so confusing btw! Is this intended or just an oversight? – mukh007 Aug 29 '16 at 16:37
  • It's just a collision between two policies: Types in Scala are capitalized, even primatives like Int and Long, and everything from java.lang is available by default. – Michael Lorton Aug 29 '16 at 18:12
12

Int and Long are Scala types and are derived from AnyVal, which is not a reference type (i.e. not AnyRef) and hence can't be null. Integer on the other hand is an alias for java.lang.Integer, which is a reference type.

No, it's not an oversight, Int and Long are consistent, using null in Scala is considered a bad thing and, as I understand it, null exists merely for Java compatibility (even for AnyRef) as well as Integer.

Victor Moroz
  • 9,167
  • 1
  • 19
  • 23
4

In Scala, type scala.Null is a subtype of all reference types (all types which inherit from scala.AnyRef - which is an alias of java.lang.Object). That's why you can use the null value (of type scala.Null) anywhere a reference type is expected.

It is not, however, a subtype of any value type (types which inherit from scala.AnyVal). Because types such as scala.Int, scala.Long, scala.Boolean... (corresponding to Java's primitive types) are value types, they cannot be null.

As for the Integer type you mention: I guess this is java.lang.Integer, which is a subtype of java.lang.Object (a.k.a. scala.AnyRef): it's a reference type, so you can use null.

It's probably easier to understand with this diagram of the Scala type hierarchy (lifted from the official documentation): Scala types hierarchy

Cyäegha
  • 4,191
  • 2
  • 20
  • 36