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?
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.
The operator ==
in scala is different from Java's.
In scala, ==
is equivant to equals
method in Any, eq
is equivant to ==
in Java
BTW, why doesn't null.asInstanceOf[Int], null.asInstanceOf[Double], null.asInstanceOf[Boolean], null.asInstanceOf[Char] throw NullPointerException ?