Bober02
Bober02

Reputation: 15351

Scala - Scalaz unMkIdentity nullPointerException

I defined the following class

private sealed trait Action2[-T1, +R] extends Function1[T1, R] {
   def printResults()
}

private abstract class BaseAction[T1, R] extends Action2[T1, R]{
  protected var result: R = null

  override final def apply(values: T1) : R = {
    result = evaluate(values)
    result
  }

  override final def printResults() {
    if(result == null)
      print("The results have not been evaluated!")
    else
      printLazyResults(result)
  }

  protected[this] def printLazyResults(results: R)
  protected[this] def evaluate(values: T1) : R
}

I have an implementation of this class and whenever I try to instantiate the given implementation the method:

 implicit def unMkIdentity[A](x: Identity[A]): A = x.value

throws null pointer exception. I don't understand firstly why that is called (I import scalaz and Scalaz) and why it is getting a null value from the property result...

Upvotes: 1

Views: 81

Answers (1)

Travis Brown
Travis Brown

Reputation: 139058

Normally you'd get into trouble with a definition like class X[R] { var r: R = null }:

scala> class X[R] { var r: R = null }
<console>:7: error: type mismatch;
 found   : Null(null)
 required: A
       class X[R] { var r: R = null }

In this case something odd is happening that allows your code to compile: the compiler sees that it has an implicit Identity[R] => R in unMkIdentity, so it interprets the null as an instance of Identity[R] and tries to make the conversion, which of course doesn't work.

This isn't intended behavior—it's just a weird little consequence of having a lot of implicits lying around.

In any case you should never write var r: R = null to initialize a member variable—you should always use var r: R = _, which picks an appropriate default value. See section 4.2 ("Variable Declarations and Definitions") of the language specification for more information.

Upvotes: 2

Related Questions