What's the difference between `null == last` a

2019-04-27 02:46发布

问题:

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?

回答1:

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.



回答2:

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 ?



标签: scala equals