コンストラクタの this() super()はなぜ先頭にしか記述出来ないか


なぜ`this()` `super()`は先頭に以外に記述することをなぜ禁止したのでしょうか？  
`this()`や`super()`を呼び出す前に何かをしないといけない時は面倒じゃないですか。  
なぜなのでしょうか。

[code]

    public class Instance{
      String name;
      public Instance(){
        //ここに処理があるとエラーが出る
        this("Sample");
      }
      public Instance(String name){
        //処理…
      }
    }
    
[/code]

`Instance instance=getInstance();`みたいにする方法もあります。

[code]

    public class Instance{
      String name;
      public static Instance getInstance(){
        //処理
        return new Instance("Sample");
      }
      private Instance(String name){
        //処理…
      }
    }
    
[/code]

それでいいのですが、少し気になったので教えて下さい。




この制約は、正しくはコンストラクタのみにあります。

> call to super() must be first statement in constructor.

のエラーメッセージの通り、まだ生成されていない不定状態のオブジェクトへアクセスされてしまうことを防ぐためです。

以下のような状況を考えるとわかりやすいです。

[code]

    class Instance {
        protected String name;
        public Instance() {
            this("BaseType");
        }
        public Instance(String name) {
            this.name = name;
        }
    }
    
    class SubInstance extends Instance {
        public SubInstance() {
            this.name = "SubType";
            super(); // Illegal Code
        }
    }
    
[/code]

`SubInstance`の`super()`呼び出しタイミングでは、まだ`Instance`のコンストラクタは実行されていません。

この不正なコードでは、`SubInstance`の冒頭で`name`フィールドを`SubType`に書き換えていますが、もしその後に`super()`呼び出しによる初期化ができたとすると、`name`フィールドは`BaseType`で上書きされてしまいます。

想定しないフィールドの値になるだけなら大したことはないと思うかもしれません。しかし、まだ初期化されていないために`null`の参照にアクセスできてしまった場合はどうでしょうか？

同じことが`this()`でも言えるのが分かると思います。




この制約は、正しくはコンストラクタのみにあります。

> call to super() must be first statement in constructor.

のエラーメッセージの通り、まだ生成されていない不定状態のオブジェクトへアクセスされてしまうことを防ぐためです。

以下のような状況を考えるとわかりやすいです。

[code]

    class Instance {
        protected String name;
        public Instance() {
            this("BaseType");
        }
        public Instance(String name) {
            this.name = name;
        }
    }
    
    class SubInstance extends Instance {
        public SubInstance() {
            this.name = "SubType";
            super(); // Illegal Code
        }
    }
    
[/code]

`SubInstance`の`super()`呼び出しタイミングでは、まだ`Instance`のコンストラクタは実行されていません。

この不正なコードでは、`SubInstance`の冒頭で`name`フィールドを`SubType`に書き換えていますが、もしその後に`super()`呼び出しによる初期化ができたとすると、`name`フィールドは`BaseType`で上書きされてしまいます。

想定しないフィールドの値になるだけなら大したことはないと思うかもしれません。しかし、まだ初期化されていないために`null`の参照にアクセスできてしまった場合はどうでしょうか？

同じことが`this()`でも言えるのが分かると思います。

