LoginSignup
question2022
@question2022 (step1engineer)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Java Silver se11 紫本 5章の問題について

解決したいこと
現在タイトルの書籍を学習中です。
以下の問題に対する解説の理解ができず、解説をさらに細かく解説して下さる方が
いらっしゃらないかと思いこちらに質問することにしました。

問題のコード
 実行結果は「5 11」となる。

1  public class Main {
2   int x = 3;
3   static int y = 2;
4  

5   public static void main(String[] args){
6    int x = 10;
7    int y = 10;
8    Main obj = new Main();
9    obj.printIt();
10   obj.printIt(y);
11  }
12 
13  Main() { x = x+1;}
14  static { y += y;}
15 
16  void printIt(){
17   System.out.print(++x);
18  }
19  void printIt(int y){
20   System.out.printIt(" "+ ++y);
21  }
22 }

書籍に記載の解説文章
8行目でMainクラスがロードされることにより14行目が実行され、
インスタンス化されることで、13行目が実行されます。
この時点でインスタンス変数xの値は4、static変数yの値は4です。
9行目の呼び出しにより16行目が実行され、
インクリメント化されてから出力なので、5です。
また、10行目では引数にy変数としていますが、これは7行目の変数yです。
10が引数として渡され、19行目が呼び出されます。
インクリメントされてから出力なので11です。

質問したいこと
上記の解説文章のなかで、
「8行目でMainクラスがロードされることにより14行目が実行され、
インスタンス化されることで、13行目が実行されます。」
の部分だけが理解できません。
それ以外の文章は処理の流れが理解できます。
補足までですが、1~4章の学習は住んでおり、練習問題を通して
練習問題内の解説で分からない箇所はない状態です。
なぜ、
「8行目でMainクラスがロードされることにより14行目が実行され、
インスタンス化されることで、13行目が実行されます。」
になるのか、解説文章よりかみ砕くことができるものかもわかりませんが、
ステップを踏んで教えていただきたいです。
また、上記2行が理解できないなら、これを復習した方がいい!というような
アドバイスがありましたらいただけますと助かります。

0

2Answer

8行目でMainクラスがロードされることにより14行目が実行され、
インスタンス化されることで、13行目が実行されます

14行目は、staticイニシャライザです。真っ先に実行されます。
13行目のmain()はこのクラスのコンストラクタ(インスタンスイニシャライザ)です。
よって、実行順は、staticイニシャライザ(最初に1回のみ実行) → コンストラクタ(newの都度) の順になります。

説明が足りなければ、再質問してください。

2

Comments

  1. @question2022

    Questioner

    @nak435

    早速ご回答をいただきありがとうございます。
    いただいた文章とリンク先で記事を読んで、解説文の意味を理解することがきでました!
    嬉しいです。
    また同じような問題にぶつかったときに正解できるよう、リンクを持っておきます。
    ありがとうございます!!

  2. 追伸;

    8行目でMainクラスがロードされることにより14行目が実行され

    この説明は間違っていると思います(「8行目で」のところ)。
    Mainクラスのインスタンス生成とは無関係に、Mainクラスのstatic イニシャライザは実行されますから。
    おそらく、5行目のmain()関数が呼ばれるより前のタイミングで、14行目が実行されると思います。
    Main obj = new Main();が無くても。

  3. @question2022

    Questioner

    追記をいただきありがとうございます。

    1 public class Main {
    へアクセスしたときに、まずどのコードよりも
    static初期化ブロックである
    14 static { y += y;}
    が実行される、
    という理解であっていますでしょうか。

  4. その理解で合っていると思います。

  5. @question2022

    Questioner

    とても助かります。
    解決まで時間のかかっていた問題でしたので
    こちらで質問してみて良かったです!
    また投稿する事があるとおもいます、機会がありましたら
    またよろしくお願いいたします。m(_ _)m

もう解決してるかもしれませんが、
変数を毎度毎度出力するよう追記してみましたので
貼っておきます。

追記したコード
public class Main {
  int x = 3; // フィールド変数のx
  static int y = 2; // static変数のy

 public static void main(String[] args){
    System.out.println(" 3:static変数のy:" + y);
    int x = 10; // ローカル変数(main(String[] args))のx
    int y = 10; // ローカル変数(main(String[] args))のy
    System.out.println(" 4:ローカル変数(main(String[] args))のx:" + x);
    System.out.println(" 5:ローカル変数(main(String[] args))のy:" + y);
    System.out.println(" 6:static変数のy:" + Main.y);
    Main obj = new Main();
    System.out.println(" 9:フィールド変数のx:" + obj.x);
    System.out.println("10:ローカル変数(main(String[] args))のx:" + x);
    System.out.println("11:ローカル変数(main(String[] args))のy:" + y);
    System.out.println("12:static変数のy:" + Main.y);
    obj.printIt();
    System.out.println("15:フィールド変数のx:" + obj.x);
    System.out.println("16:ローカル変数(main(String[] args))のx:" + x);
    obj.printIt(y);
    System.out.println("19:ローカル変数(main(String[] args))のy:" + y);
    System.out.println("20:static変数のy:" + Main.y);
  }

  Main() {
    System.out.println(" 7:フィールド変数のx:" + x);
    x = x+1;
    System.out.println(" 8:フィールド変数のx:" + x);
  }

  static {
    System.out.println(" 1:static変数のy:" + y);
    y += y;
    System.out.println(" 2:static変数のy:" + y);
  }

  void printIt(){
    System.out.println("13:フィールド変数のx:" + x);
    System.out.println("x(これはフィールド変数のx):"+ ++x);
    System.out.println("14:フィールド変数のx:" + x);
  }

  void printIt(int y){
    System.out.println("15:引数のy:" + y);
    System.out.println("16:static変数のy:" + Main.y);
    System.out.println("y(これは引数のy):"+ ++y);
    System.out.println("17:引数のy:" + y);
    System.out.println("18:static変数のy:" + Main.y);
  }
}
出力結果
 1:static変数のy:2
 2:static変数のy:4
 3:static変数のy:4
 4:ローカル変数(main(String[] args))のx:10
 5:ローカル変数(main(String[] args))のy:10
 6:static変数のy:4
 7:フィールド変数のx:3
 8:フィールド変数のx:4
 9:フィールド変数のx:4
10:ローカル変数(main(String[] args))のx:10
11:ローカル変数(main(String[] args))のy:10
12:static変数のy:4
13:フィールド変数のx:4
x(これはフィールド変数のx):5
14:フィールド変数のx:5
15:フィールド変数のx:5
16:ローカル変数(main(String[] args))のx:10
15:引数のy:10
16:static変数のy:4
y(これは引数のy):11
17:引数のy:11
18:static変数のy:4
19:ローカル変数(main(String[] args))のy:10
20:static変数のy:4
1

Comments

  1. @question2022

    Questioner

    Yamazin 様
    コメントありがとうございます!色々な方のアドバイスが聞けて嬉しいです!
    コードをこのようにして追うこと、大事ですよね。。
    いただいたコードを1行ずつ確かめながら見たいとおもいます。
    ご親切にありがとうございます (; _;)

Your answer might help someone💌