2013-08-29 244 views
1

我使用Scala的Liftweb,並有此模型對象:NullPointerException異常

object Product extends Product with LongKeyedMetaMapper[Product] { 
    override def dbTableName = "products" 

    override def dbIndexes = UniqueIndex(slug) :: super.dbIndexes 

    def menus = sitemap 

    lazy val sitemap: List[Menu] = List(editProductMenuLoc, listProductsMenuLoc, createProductMenuLoc, indexProductsMenuLoc).flatten(a => a) 

    protected def editProductMenuLoc = 
    Full(Menu(Loc("EditProduct" + menuNameSuffix, editPath, S.?("edit.product")))) 

    protected def listProductsMenuLoc = Full(Menu(Loc("ListProduct" + menuNameSuffix, listPath, S.?("list.products")))) 

    protected def indexProductsMenuLoc = Full(Menu(Loc("ListProduct" + menuNameSuffix, indexPath, S.?("index.products")))) 

    protected def createProductMenuLoc = 
    Full(Menu(Loc("CreateProduct" + menuNameSuffix, createPath, S.?("create.product")))) 

    protected val menuNameSuffix = "" 

    protected val editSuffix = "edit" 

    protected val createSuffix = "create" 

    protected val viewSuffix = "view" 

    protected val editPath = theAdminPath(editSuffix) 

    protected val createPath = theAdminPath(createSuffix) 

    protected val viewPath = thePath(viewSuffix) 

    protected val listPath = basePath 

    protected val indexPath = adminPath 

    protected def thePath(end: String): List[String] = basePath ::: List(end) 

    protected def theAdminPath(end: String): List[String] = adminPath ::: List(end) 

    protected val basePath: List[String] = "products" :: Nil 

    protected val adminPath: List[String] = "admin" :: "products" :: Nil 
} 

當我編譯,它工作正常,當我嘗試運行它,我得到這個錯誤:

Caused by: java.lang.NullPointerException: null 
    at scala.collection.immutable.List.$colon$colon$colon(List.scala:120) ~[scala-library.jar:0.12.2] 
    at code.model.Product$.theAdminPath(Product.scala:65) ~[classes/:na] 
    at code.Product$.<init>(Product.scala:53) ~[classes/:na] 
    at code.Product$.<clinit>(Product.scala) ~[classes/:na] 
    ... 49 common frames omitted 

我在源代碼MegaProtoMetaUser中找到的代碼之後建立了這些路徑,我不知道爲什麼在這裏會出現空指針異常 - 所有值都被正確填充,對嗎?

回答

5

問題是字段初始化的順序,從上到下。這意味着editPath,createPath和viewPath在basePath和adminPath之前正在初始化。由於這些前幾個字段在初始化基路徑之前調用了方法thePath和theAdminPath,因此對這些方法的調用將使用basePath和adminPath的預初始化值 - null。嘗試將這兩個字段的定義移到調用涉及它們的方法的任何字段的定義之上。

+1

另一種方法是使用'lazy val'或'def'及其所有含義。 –

+0

在Scala對象中有初始​​化的順序嗎?我沒有意識到這一點。因此,如果我將'val'全部更改爲'def',那也不是問題嗎? – Lanbo

+0

@LambdaDusk是的,編輯editPath,createpath和viewPath方法(或om-nom-nom建議的懶惰val)也可以。在這兩種情況下,直到調用它們纔會被評估,因此推遲了它們依賴的方法調用,直到basePath和adminPath被初始化之後。請注意,如果您將它們更改爲defs,則每次使用它們時都會重新評估它們(這裏看起來有點無意義)。懶惰的vals可以工作,但我會說在這種情況下,將basePath和adminPath的字段定義進一步移動是最直接的選擇。 – Shadowlands