Scalaの面白い問題14自分で自分を調整する時

1683 ワード

本当に珍しくありません.次の2つのprintln文のどちらがポインタを空にして、その出力は8ですか.
  val s1: String = s1
  println(s1.length)
  val s2: String = s2 + s2
  println(s2.length)

説明:
Stringタイプはデフォルトでnulllに初期化されます
nullリファレンスは、文字列の位置で言語仕様に従ってデフォルトで文字列「null」に変換されます.
Explanation
The definitions of the values s1 and s2 are valid and compile without an error. As the definitions are recursive, the type of the declared values has to be provided (SLS §4.1).
In Scala, object fields are preinitialized to their default value, and for the type String (and all other reference types) the default value is null.
This is as in Java. However, such a recursive definition of a field in a Java class body gives an illegal forward reference compiler error,
class Z {
   String s = s + s;
}
but the following compiles fine.
class Z {
   String s = this.s + this.s;
}
This demonstrates, that the checking which is done by the Java compiler is quite shallow. The Scala way to accept recursive definitions for all situations is more consistent.
What remains to explain is the result of this puzzler.
    Value s1 is initialized to null, therefore the expression s1.length ends in a NullPointerException at run-time.
    The initialization of the value s2 actually gets translated to byte code equvalent to
    s2 = (new StringBuilder()).append(s2).append(s2).toString()
    where the argument s2 has its default value null. According to the JLS, Section 15.18.1.1 the reference null is converted to the string "null", and the value which gets assigned to s2 is the string "nullnull"which has length 8.