What's the difference between `null == last` and `null eq last`, in Scala?
equals, scala
Solution
When either side of the `==` is `null` or if the first operand of `==` evaluates to null, then Scala will not invoke `equals`. So, in this case, yes, `x == null` is the same as `x eq null`; the `equals` method is not invoked. Pay attention to the cases below.
Consider this:
class X {
// this is just for testing
// any equals that returns true when the other object is null
// is arguably broken. thus even though it may be invoked
// the end semantics should remain the same
override def equals(x: Any) = true
}
var x = new X()
x == null // false -- compiler optimization?
null == x // false
var y = null
y == x // false -- see documentation below, y is null, x is not
x == y // true -- x does not evaluate to null, equals invokes
x eq y // false
And note that:
(new X()) == null
Results in a warning saying a "a fresh object" will never be equal (to null).
I suspect there may be slightly more/different code emitted for `x == y` than `x == null` (in case the equals must be invoked), but have not checked.
Happy coding.
Section 6.3 (The Null Value) of the Scala Language Specification has this to say:
The null value is of type scala.Null, and is thus compatible with every reference type. It denotes a reference value which refers to a special “null” object. This object implements methods in class scala.AnyRef as follows:
- [null] eq( x ) and [null] ==( x ) return true iff the argument x is also the “null” object.
- ne( x ) and !=( x ) return true iff the argument x is not also the “null” object.
- isInstanceOf[T ] always returns false.
- asInstanceOf[T ] returns the “null” object itself if T conforms to scala.AnyRef, and throws a NullPointerException otherwise.
A reference to any other member of the “null” object causes a NullPointerException to be thrown.
Problem
I see in the built-in class `MessageQueue.scala` of scala 2.7.7, around line 164, it's: ``` def extractFirst(p: Any => Boolean): MessageQueueElement = { changeSize(-1) // assume size decreases by 1 val msg = if (null eq last) null else { ... } } ``` I don't understand `val msg = if (null eq last) null` well, why it uses `eq`, but not `null`. If I write `if (last==null) null`, is it correct? Is there any difference?