2016-08-21 11 views
1

なぜthis()がコンストラクタチェーンの最初のステートメントに含まれる必要がありますか?異なる引数を持つ `this()`が親コンストラクタで動作しないのはなぜですか?

this()複数の引数を持つ複数のコンストラクタが最終コンストラクタで機能しないのはなぜですか?私は、コンストラクタA(int x,int y,int c)で複数のthis()を使用できない理由

package thislatest; 

public class ThisLatest { 

    public static void main(String[] args) { 
      A a1= new A(10,20,30); 
      a1.display(); 
    } 

} 

class A 
{ 
    int x,b; 
    static int c; 
    A(){ System.out.println("constructor chaining1");} 

    A(int y) 
    { //this(); 
     System.out.println("constructor chaining2"); 
     b=y; 
    } 

    A(int x,int y) 
    { 
     // this(x); 
     System.out.println("constructor chaining3"); 
     x=x; 
     x=y; 
    } 

     A(int x,int y,int c) 
    { this(); 
     this(y); 
     this(x,y); 
     x=x;    //self reference initialised by previous constructor 
     b=y;    //no need of this keyword since name is different 
     this.c=c;   //current instance variable or A.c=c will also work 
    } 

    void display() 

    { 
     System.out.println(x+b);   //wrong result due to self reference 
     System.out.println(c+b);   //correct reference 
    } 

} 

なぜこれが最初のステートメントである必要がありますか?

言語の流れを維持するだけですか?

私は初心者が簡単な言葉を使用してください:)

+2

よく読んでくださいhttp://stackoverflow.com/questions/1168345/why-does-this-and-super-have-to-be-the-first-statement-in-a-constructor?rq=1 –

+0

私は同じタイプの質問をする前にstackoverflow答えを読んでいます。私はそれらの答えを理解していない – ekaf

+0

あなたは副作用なしにプライベートイニシャライザメソッドで行うことができます。しかしコンストラクタを尋ねる場合は、最後のフィールドでは、多くのコンストラクタでこの最終フィールドを初期化すると、最終フィールドを何度か初期化でき、これが問題になると考えるべきです。 –

答えて

1

同じコンストラクタで複数のコンストラクタを呼び出すことはできませんが、別のコンストラクタを呼び出すようにチェーン化することはできます。これは、クラス内のコンストラクターがなくなるまで実行できます。以下のクラスを考えてみましょう:

public class MyClass() { 
    public MyClass() { 
     this(1); 
     System.out.printf("Calling MyClass()%n"); 
    } 

    public MyClass(int a) { 
     this(a, 2); 
     System.out.printf("Calling MyClass(%d)%n", a); 
    } 

    public MyClass(int a, int b) { 
     System.out.printf("Calling MyClass(%d, %d)%n", a, b); 
    } 
} 

そして、次のクライアントコード:

public class Client() { 
    public static void main(String[] args) { 
     new MyClass(); 
    } 
} 

出力あなたは上記のコードを実行した場合、次のようになります。

Calling MyClass(1, 2) 
Calling MyClass(1) 
Calling MyClass() 

出力の順序は、上記表示されますprintf()の呼び出しはコンストラクターが呼び出した後に行われるため、間違った順序になります。下の矢印に従うことで、あなたは、コンストラクタ呼び出しが始まる場所を確認することができ、それが最終的に終わるところ:

あなたは最後の矢印が何を意味するのか不思議に思う場合

Object  MyClass    Client 
------  -------    ------ 
       MyClass() <---------- main(String[]) 
       | 
       V 
       MyClass(int) 
       | 
       V 
Object() <--- MyClass(int, int) 
MyClassを含むすべてのJavaクラスは、密かに Objectを拡張します - クラス。 MyClass 実際の最後のコンストラクタは次のようになります。

public MyClass(int a, int b) { 
     super(); 
     System.out.printf("Calling MyClass(%d, %d)%n", a, b); 
    } 

あなたのクラスには、それ以外の場合は、コンストラクタのチェーンがループで立ち往生されるだろう、暗黙的または明示的にsuper()を呼び出して、少なくとも1つのコンストラクタを必要とします。その場合、コンパイラはエラーを返します。

0

を各コンストラクタは、クラスの単一のインスタンスを初期化しています。したがって、コンストラクタでは、他のコンストラクタを1つだけ呼び出すことができます。コンストラクタ呼び出しが最初のものでなければならない理由は、インスタンスの作成を別のコンストラクタに委譲するということです。そうでない場合、コンストラクタの最初の行が別のコンストラクタの呼び出しでない場合、インスタンスは最初の行が実行される前にインスタンス化されます(つまり、super()が暗黙的に呼び出されます)。したがって、コンストラクタを呼び出した後は、コンストラクタ内でコンストラクタを2回呼び出すようなものです。コンストラクタが1つのインスタンスのみをインスタンス化するため、明らかに不正です。

0

なぜthis()がコンストラクタチェーンの最初のステートメントに含まれている必要がありますか?:Java仕様で必要とされるため!たとえば、Pythonを使用すると、プログラマはどこでもスーパークラス初期化メソッドを呼び出すことができます。しかし、Javaはそれを許さない。完全停止。

なぜ、複数のthis()が異なる引数でも、最終コンストラクタで機能しないのですか?上記と同じ回答です。 なぜを聞いても無用です。はどうすればいいですか?言語仕様を変更しないためです。

このように考えてみましょう。コンストラクタの最初の命令としてではなく、初期化メソッドを呼び出す理由があるかもしれません。その場合には、単に非コンストラクタの初期化メソッドを使用して、コンストラクタからこれらのメソッドを呼び出す:Java言語で

class A { 
    private void init1(int x) { 
     // do something with x 
    } 

    private void init2(int x, int y) { 
     // do something with x and y 
     ... 
     init1(x); // eventually call init1 in the middle of init2 
     ... 
    } 

    A(int x) { 
     y = 2 *x + 1; 
     init2(x, y); // call initialization method in the middle of ctor 
    } 
    A(int x,int y) { 
     // eventually some instructions 
     init2(x, y); 
     // eventually other instructions 
    } 
} 

を、コンストラクタは特殊なです。あなたがそれを受け入れることができない場合は、別の言語を使用する必要があります。

関連する問題