2011-01-15 23 views
5

xem xét như sau (giản thể) ví dụ:NullPointerException khi truy cập vào val overriden trong constructor trừu tượng

abstract class Bar[T] { 
    val f: PartialFunction[T, T] 
    val default: PartialFunction[T, T] = { case x => x } 
    val chained = f orElse default 
} 

class Foo extends Bar[Int] { 
    val f: PartialFunction[Int, Int] = { case 1 => 2 } 
} 

Và xem nó sụp đổ:

scala> val foo = new Foo 
java.lang.NullPointerException 
     at Bar.<init>(<console>:8) 
     at Foo.<init>(<console>:6) 
     at .<init>(<console>:7) 
     at .<clinit>(<console>) 
     at RequestResult$.<init>(<console>:9) 
     at RequestResult$.<clinit>(<console>) 
     at RequestResult$scala_repl_result(<console>) 
     .... 

Tuy nhiên, nếu chúng ta đặt chained trong lớp bê tông:

abstract class Bar[T] { 
    val f: PartialFunction[T, T] 
    val default: PartialFunction[T, T] = { case x => x } 
} 

class Foo extends Bar[Int] { 
    val f: PartialFunction[Int, Int] = { case 1 => 2 } 
    val chained = f orElse default 
} 

Nó hoạt động như mong đợi:

scala> val foo = new Foo 
foo: Foo = [email protected] 

Tôi phải thừa nhận rằng tôi hoàn toàn không biết điều gì đang xảy ra ở đây. Lỗi? (Đây là trên Scala 2.8.1.)

+0

Xem câu hỏi này để biết giải pháp/giải pháp thay thế: http://stackoverflow.com/questions/4712468/in-scala-what-is-an-early-initializer – Raphael

Trả lời

5

"Tại sao giá trị trừu tượng hoặc quá mức của tôi không được xác định?" https://github.com/paulp/scala-faq/wiki/Initialization-Order

+0

Cảm ơn bạn. "lười biếng val xích ..." giải quyết nó. –

+0

A: Liên kết bây giờ là 404, B: một số người muốn tránh các trò chơi lười biếng – samthebest

+0

Liên kết giờ đây [ở đây] (http://docs.scala-lang.org/tutorials/FAQ/initialization-order.html) và nó kém thực hành để trả lời với các liên kết. – nedim

0

Đoán của tôi: Đây là một tối ưu hóa được thực hiện tại thời gian biên dịch. Trình biên dịch nhận ra rằng bạn ghi đè f trong Bar. Do đó, "hàm tạo" của Bar thi hành công cụ đầu tiên từ Foo - sans f! - và rồi công cụ theo định nghĩa Bar. Do đó, f không được xác định khi chained được tạo.

Tôi gọi lỗi.

Các vấn đề liên quan