読者です 読者をやめる 読者になる 読者になる

09

Java Puzzlers 2013

http://www.slideshare.net/tyoshio2002/java-puzzlers-2013-at-javafesta-japan

一問目が全く理解できなくて衝撃的だった。他はほぼ正解できた(出題者の意図が透けて見えるものもあったので完全に理解していたかどうかは微妙)

同じ名前のプロパティを持つ親子クラスにおいて直接プロパティを参照した場合にどうなるか。「フィールドはコンパイル時に親クラスの情報を引き継ぐ」・・・?いまいち何を言ってるのか釈然としない。そもそもプロパティに対して持っていた理解と違いすぎる。

フィールド定義時にリテラルを代入しているが意味的にはスタティックイニシャライザなんだろうか?であるなら特に問題になるはずがない(という理解だった)。もしかして「フィールド定義時にリテラルを代入する」ということに特殊性があるのかと思って、コードを書いて試してみたが、コンストラクタで代入するようにしても結果は変わらないようだ。 しかし

Ancestor person = new Descendant();

Descendant person = new Descendant();

に書き換えると結果は

子孫:子孫

になる。解決策ではキャストすればOKとか書いているから、バインドする型によって参照先が変わるという事のようにみえる。Object型にバインドしてリフレクションでアクセスしてみると

子孫:子孫

つまり静的にバインドされた型のフィールドにバインドされているように見える。バイトコードを見ていないので分からないが、この参照先の決定がコンパイル時に行われているという事なのかな。「フィールドはコンパイル時に親クラスの情報を引き継ぐ」と書かれるとちょっとなにいってるのか分からない感があるが、そういう事なんだろう。 しかしメソッドは動的に継承関係の子供から親へ辿って子側が優先されるのに?なんでこんな事に。