2016/12/11 このエントリーをはてなブックマークに追加 はてなブックマーク - Java Puzzler〜mainメソッドと変数代入〜

Java Puzzler〜mainメソッドと変数代入〜




この記事はJava Puzzlers Advent Calendar 2016の11日目の記事です。


ぼくはハイレベルなJavaプログラマーではないので、本エントリもハイレベルなJava puzzleではありません。力を抜いて眺めて下さい。







お題となるソースコードは以下のとおりです。





/**
 * Created by yy_yank on 2016/11/12.
 */
public class Puzzler {

    String a;
    static String b;
    static {
        String a = "ははははは";
        b = "ふはははは";
    }

    public void exec(){}
    public void exec(String a){}
    public static void main(String... args){
        final String a = "";
        final String b = "";
        Puzzler p = new Puzzler(){
            @Override
            public void exec(String a){
                a = "あ";
                a = "な";
                a = "た";
                a = "と";
                a = "J";
                a = "a";
                a = "v";
                a = "a";
            }
        };
        new Puzzler(){
            @Override
            public void exec(){
                a = b;
                Puzzler.main();
                p.exec(a);
                System.out.println(a);
            }
        }.exec();


    }
    public static void main() {
        System.out.println("かかったな!");
    }
}






このプログラムを実行しようとするとどうなるでしょうか?




1.あなたとJavaと出力される
2.かかったな!ふははははと出力される
3.実行時エラー
4.コンパイルエラー







越後製菓!



はい、こういうの入れてかないと文章がかけないんです、すみません。




正解は2です。







mainメソッドから順に追いかけていきます。
まず、final変数のString aとString bが宣言されていますが、これらはその後使われていません。


  • Puzzlerインスタンスを生成して匿名クラスをつくって
  • exec(String a)メソッドをオーバーライドしています
  • 引数aに対して、文字リテラルを代入していますが、これらは呼び出し元と同一参照にはならないので呼び出しても呼び出し元の実引数の値は変わりません
  • Puzzler.mainはmainメソッド自身を呼び出してStackオーバーフローでコールスタックを食いつぶすかと思いきや食いつぶしません
  • これはmainメソッドがオーバーロードされているからで、引数なしのmainメソッドが呼び出されます
  • ここで”かかったな!”と出力されます
  • そして、最後にaの出力をしていますが、このPuzzler.aにはPuzzler.bが代入されています。
  • この代入されたPuzzler.bのあたいはstaticイニシャライザ内で宣言されているとおり”ふはははは”です




簡単でしたね!
明日はコレの続編です!




0 件のコメント:

コメントを投稿