4

さまざまなケースでのクラス インスタンスの初期化を理解したい..
JLS-7 セクション 12.5 では、最終的なインスタンス変数がいつどのように初期化されるかについての言及はありませんでした。final として宣言されたインスタンス変数の場合の動作を理解するために参照できる人がいますか?

   public class Test {

        public static void main(String args[]){

            Child  c1 = new Child();
        }
    }

    class Parent{
        final int a =30;
        Parent(){
            System.out.println("From super Contsrutor "+a);
            meth();
        }
        void meth(){
             System.out.println("From super");
        }
    }

    class Child extends Parent{
         final  int e=super.a;
         int b=30;
        void meth(){
            System.out.println("From Sub e=" +e+", b="+b);
        }
    }

次のような出力を与えています

From super Contsrutor 30
From Sub e=0,b=0

一方

public class Test {

    public static void main(String args[]){

        Child  c1 = new Child();
    }
}

class Parent{
    final int a =30;
    Parent(){
        System.out.println("From super Contsrutor "+a);
        meth();
    }
    void meth(){
         System.out.println("From super");
    }
}

class Child extends Parent{
     final  int e=a;
    void meth(){
        System.out.println("From Sub " +e);
    }
}

として出力を与えています

From super Contsrutor 30
From Sub 30
4

3 に答える 3

2

これ

final int e = a;

定数変数定数式です。呼び出しでは

System.out.println("From Sub e=" +e+", b="+b);

コンパイラは、の使用eをその値で置き換えることができます30

final int e = super.a;

は単純な名前ではないため、変数eは定数変数ではありません。したがって、値を置き換えることはできません。super.a

于 2014-05-14T18:15:12.183 に答える
1

コードの最初の部分は、以下のような出力を与えています

From super Contsrutor 30
From Sub e=0,b=0

これは以下の理由による。

最初に行うnew Child()と、 Child クラスのコンストラクターが実行を開始します

ただし、最初のステートメントはデフォルトでスーパーであるため、親クラスのコンストラクターを呼び出します

現在、親クラスのコンストラクターには以下のコードがあります

Parent(){ System.out.println("スーパー コンストラクターから"+a); 方法(); }

したがって、ここでは親クラスが meth() メソッドを呼び出しており、その呼び出し元は実際にはサブクラスの子のオブジェクトであるため、子クラスの meth() メソッドを呼び出します。

スーパーコンストラクターから子クラスの meth() メソッドを呼び出すと、実際には子オブジェクトはまだ作成されていないため、その変数はまだ初期化されていませんが、a と b の両方の値を出力しています。

そのため、子コンストラクターの実行が完了した後、割り当てられる前に b は 0 になります。

したがって、以下のように最初のコードを変更すると、目的の出力が得られます。つまり、親コンストラクターではなく、子コンストラクター内に meth() 呼び出しを配置し​​ます。

package com.kb.finalVariables;

public class Test {

    public static void main(String args[]){

        Child  c1 = new Child();
    }
}

class Parent{
    final int a =30;
    Parent(){
        System.out.println("From super Contsrutor "+a);
       // meth();
    }
    void meth(){
         System.out.println("From super");
    }
}

class Child extends Parent{

     final  int e=super.a;
     int b=30;
     public Child() {
        meth();
    }
    void meth(){
        System.out.println("From Sub e=" +e+", b="+b);
    }
}
于 2014-05-14T18:17:37.823 に答える