scala中侦听器模式的NullPointerException

时间:2013-04-25 12:14:52

标签: list class scala nullpointerexception

我正在尝试创建一个类似的侦听器设计模式:

abstract class Listener(g: Engine) {
  g.addListener(this)
}
class Listener1(g: Engine) extends Listener(g)
class Listener2(g: Engine) extends Listener(g)

class Engine {
  val listener1 = new Listener1(this)
  val listener2 = new Listener2(this)  

  var listeners: List[Listener] = Nil
  def addListener(g: Listener) = {
    listeners = g::listeners
  }
}

但是,如果NullPointerException失败,因为listeners在创建nulllistener1时最初等于listener2

我如何克服这个问题?

编辑:我尝试了以下内容:

  def addListener(g: Listener) = {
    if(listeners == null) {
      listeners = List(g)
    } else {
      listeners = g::listeners
    }
  }

但问题是在初始化类之后,listeners = Nil。 我需要一个更好的设计模式来实现我的目标。

解决方案:不使用延迟val或可变集合:

var listeners: List[Listener] = _
def addListener(g: Listener) = {
  if(listeners == null) 
    listeners = List(g)
  else
    listeners = g::listeners
}

使用_进行初始化而不是'null'或'Nil'会使编译器在创建listenerslistener1后不会覆盖listener2

1 个答案:

答案 0 :(得分:2)

lazy valuemutable collection的帮助下:

class Engine {
  val listener1 = new Listener1(this)
  val listener2 = new Listener2(this)  

  lazy val listeners = collection.mutable.ListBuffer.empty[Listener]
  def addListener(g: Listener) {
    listeners += g
  }
}

如果你在某个地方非常需要不可变列表,只需在呼叫中使用.toList方法将缓冲区转换为它。