2011-01-15 3 views
5

Considérese el siguiente ejemplo (simplificado):NullPointerException cuando se accede a val overriden en el constructor abstracto

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 } 
} 

y verlo accidente:

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>) 
     .... 

Sin embargo, si ponemos chained en la clase concreta:

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 
} 

Funciona como se esperaba:

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

Tengo que admitir que no tengo absolutamente ninguna idea de lo que está sucediendo aquí. ¿Error? (Esto está en Scala 2.8.1.)

+0

Ver esta pregunta para una solución/solución: http://stackoverflow.com/questions/4712468/in-scala-what-is-an-early-initializer – Raphael

Respuesta

5

"¿Por qué mi valor abstracto o invalidado es nulo?" https://github.com/paulp/scala-faq/wiki/Initialization-Order

+0

Gracias. "perezoso val encadenado ..." lo resuelve. –

+0

A: El enlace ahora es 404, B: algunas personas quieren evitar lazy vals – samthebest

+0

El enlace ahora es [aquí] (http://docs.scala-lang.org/tutorials/FAQ/initialization-order.html) y es pobre practicar para responder con enlaces. – nedim

0

Mi suposición: Esta es una optimización hecha en tiempo de compilación. El compilador reconoce que sobrescribe f en Bar. Por lo tanto, el "constructor" de Bar ejecuta primero las cosas desde Foo - sans f! - y luego las cosas en la definición de Bar. Por lo tanto, f no está definido cuando se construye chained.

Llamo a error.

Cuestiones relacionadas