2
public class SuperClass{
    public SuperClass(){
        System.out.println("Super class");
    }
}

public class SubClass extends SuperClass{
    int i;
    {
        i=10;
    }
    public SubClass(){
        System.out.println("Subclass");
    }
    public static void main(String[] args){
        SubClass sc = new SubClass();
    }
}

考えられるすべての場所でデバッグを行ったところ、最初にインスタンスが作成されたときに、最初に SuperClass コンストラクターに移動して Super Class を出力し、次にインスタンス変数、次に初期化ブロック、最後に SubClass コンストラクターと出力に到達することがわかりましたサブクラス。

しかし、私はどこかで、サブクラスのコンストラクター内で super() がデフォルトで呼び出される場所であり、それがスーパークラスのコンストラクターに行くときであることをどこかで読みました!!!

4

3 に答える 3

9

SubClass()コンストラクターは暗黙的に次のようになります。

 public SubClass(){
    super();
    {
      i=10;
    }
    System.our.println("Subclass");
 }

JLSセクション12.5に従って:

新しく作成されたオブジェクトへの参照が結果として返される直前に、指定されたコンストラクターが処理され、次の手順を使用して新しいオブジェクトが初期化されます。

  1. コンストラクターの引数を、このコンストラクター呼び出し用に新しく作成されたパラメーター変数に割り当てます。

  2. このコンストラクターが、(this を使用して) 同じクラス内の別のコンストラクターの明示的なコンストラクター呼び出し (§8.8.7.1) で始まる場合、引数を評価し、これらの同じ 5 つの手順を使用してそのコンストラクター呼び出しを再帰的に処理します。そのコンストラクターの呼び出しが突然完了すると、このプロシージャは同じ理由で突然完了します。それ以外の場合は、ステップ 5 に進みます。

  3. このコンストラクターは、(this を使用して) 同じクラス内の別のコンストラクターの明示的なコンストラクター呼び出しで開始されません。このコンストラクターが Object 以外のクラス用である場合、このコンストラクターは、(super を使用して) スーパークラス コンストラクターの明示的または暗黙的な呼び出しから開始します。これらの同じ 5 つの手順を使用して、引数を評価し、そのスーパークラス コンストラクター呼び出しを再帰的に処理します。そのコンストラクターの呼び出しが突然完了すると、このプロシージャは同じ理由で突然完了します。それ以外の場合は、ステップ 4 に進みます。

  4. このクラスのインスタンス初期化子とインスタンス変数初期化子を実行し、インスタンス変数初期化子の値を対応するインスタンス変数に割り当てます。この順序は、クラスのソース コードにテキストで表示される左から右の順序です。これらの初期化子のいずれかを実行すると例外が発生した場合、それ以上の初期化子は処理されず、このプロシージャは同じ例外で突然終了します。それ以外の場合は、ステップ 5 に進みます。

  5. このコンストラクターの残りの本体を実行します。その実行が突然完了した場合、このプロシージャは同じ理由で突然完了します。それ以外の場合、この手順は正常に完了します。

于 2013-06-10T11:07:42.497 に答える
5

それは、SubClassコンストラクターが実際には次のようになっているためです。

public SubClass() {
    super();
    {
       i=10;
    }
    System.out.println("Subclass");
}

super();を呼び出さない場合 明示的に、コンパイラは暗黙的にそれを行います。つまり、SuperClassコンストラクターが最初に呼び出され、次に `System.out.println("Subclass");が呼び出されます。

また、super()コンストラクターの最初のステートメントである必要があります。

SuperClass プライベートのコンストラクターを作成することで、これらすべてを確認できます(別のファイルでも)。SubClassコンパイラは、コンストラクタにデフォルトのコンストラクタがないことを示すエラーを表示しますSuperClass

于 2013-06-10T11:06:40.167 に答える
1

コンストラクタは常に を呼び出しますsuper()。それは暗黙的です。

ドキュメントを読んでください。

コンストラクターがスーパークラス コンストラクターを明示的に呼び出さない場合、Java コンパイラーはスーパークラスの引数なしコンストラクターへの呼び出しを自動的に挿入します。スーパー クラスに引数のないコンストラクタがない場合、コンパイル時エラーが発生します。Object にはそのようなコンストラクターがあるため、Object が唯一のスーパークラスであれば問題はありません。

于 2013-06-10T11:08:31.643 に答える