2513

別のコンストラクターを呼び出すことは可能ですか (サブクラスからではなく、同じクラス内で)? はいの場合、どのように?そして、別のコンストラクターを呼び出す最良の方法は何ですか (それを行う方法がいくつかある場合)?

4

23 に答える 23

3249

はい、可能です:

public class Foo {
    private int x;

    public Foo() {
        this(1);
    }

    public Foo(int x) {
        this.x = x;
    }
}

同じクラスのコンストラクターではなく、特定のスーパークラス コンストラクターにチェーンするには、super代わりにthis. チェーンできるのは 1 つのコンストラクターのみであり、それはコンストラクター本体の最初のステートメントでなければならないことに注意してください。

この関連する質問も参照してください。これは C# に関するものですが、同じ原則が適用されます。

于 2008-11-12T20:12:14.610 に答える
278

を使用してthis(args)います。推奨されるパターンは、最小のコンストラクターから最大のコンストラクターまで動作することです。

public class Cons {

    public Cons() {
        // A no arguments constructor that sends default values to the largest
        this(madeUpArg1Value,madeUpArg2Value,madeUpArg3Value);
    }

    public Cons(int arg1, int arg2) {
       // An example of a partial constructor that uses the passed in arguments
        // and sends a hidden default value to the largest
        this(arg1,arg2, madeUpArg3Value);
    }

    // Largest constructor that does the work
    public Cons(int arg1, int arg2, int arg3) {
        this.arg1 = arg1;
        this.arg2 = arg2;
        this.arg3 = arg3;
    }
}

最近提唱されている valueOf または単に「of」のアプローチを使用することもできます。

public class Cons {
    public static Cons newCons(int arg1,...) {
        // This function is commonly called valueOf, like Integer.valueOf(..)
        // More recently called "of", like EnumSet.of(..)
        Cons c = new Cons(...);
        c.setArg1(....);
        return c;
    }
} 

スーパー クラスを呼び出すには、 を使用しますsuper(someValue)。super の呼び出しは、コンストラクターでの最初の呼び出しでなければなりません。そうしないと、コンパイラ エラーが発生します。

于 2008-11-12T20:13:22.893 に答える
232

[注: 他の回答では見られなかった 1 つの側面を追加したいだけです: this() が最初の行になければならないという要件の制限を克服する方法)。]

Java では、同じクラスの別のコンストラクターを、コンストラクターから を介して呼び出すことができますthis()。ただしthis、最初の行にある必要があることに注意してください。

public class MyClass {

  public MyClass(double argument1, double argument2) {
    this(argument1, argument2, 0.0);
  }

  public MyClass(double argument1, double argument2, double argument3) {
    this.argument1 = argument1;
    this.argument2 = argument2;
    this.argument3 = argument3;
  }
}

最初の行に表示する必要があることthisは大きな制限のように見えますが、静的メソッドを介して他のコンストラクターの引数を構築できます。例えば:

public class MyClass {

  public MyClass(double argument1, double argument2) {
    this(argument1, argument2, getDefaultArg3(argument1, argument2));
  }

  public MyClass(double argument1, double argument2, double argument3) {
    this.argument1 = argument1;
    this.argument2 = argument2;
    this.argument3 = argument3;
  }

  private static double getDefaultArg3(double argument1, double argument2) {
    double argument3 = 0;

    // Calculate argument3 here if you like.

    return argument3;

  }

}
于 2013-03-11T20:33:12.427 に答える
41

コード内 (最初の行ではなく) から別のコンストラクターを呼び出す必要がある場合は、通常、次のようなヘルパー メソッドを使用します。

class MyClass {
   int field;


   MyClass() {
      init(0);
   } 
   MyClass(int value) {
      if (value<0) {
          init(0);
      } 
      else { 
          init(value);
      }
   }
   void init(int x) {
      field = x;
   }
}

しかし、ほとんどの場合、可能な限り、最初の行の単純なコンストラクターからより複雑なコンストラクターを呼び出すことによって、逆の方法で実行しようとします。上記の例では

class MyClass {
   int field;

   MyClass(int value) {
      if (value<0)
         field = 0;
      else
         field = value;
   }
   MyClass() {
      this(0);
   }
}
于 2013-04-23T23:12:24.103 に答える
18

誰もがすでに言ったように、明示的なコンストラクター呼び出しthis(…)と呼ばれる を使用します。

ただし、そのような明示的なコンストラクター呼び出しステートメント内では、参照できないことに注意してください。

  • インスタンス変数または
  • インスタンスメソッドまたは
  • このクラスまたはスーパークラスで宣言された内部クラス、または
  • thisまた
  • super.

JLS (§8.8.7.1) に記載されているとおり。

于 2015-05-07T22:52:03.147 に答える
14

はい、任意の数のコンストラクターをクラスに存在させることができ、[コンストラクター呼び出しとキーワードをthis()混同しないでください]を使用して別のコンストラクターから呼び出すことができます。または、コンストラクターの最初の行にする必要があります。this()thisthis()this(args)

例:

Class Test {
    Test() {
        this(10); // calls the constructor with integer args, Test(int a)
    }
    Test(int a) {
        this(10.5); // call the constructor with double arg, Test(double a)
    }
    Test(double a) {
        System.out.println("I am a double arg constructor");
    }
}

これは、コンストラクターのオーバーロードとして知られています。
コンストラクターの場合、オーバーロードの概念のみが適用され、継承やオーバーライドは適用されないことに注意してください。

于 2016-11-16T16:14:17.193 に答える
8

「this」キーワードを使用して、同じクラスの別のコンストラクターからコンストラクターを作成できます。例 -

class This1
{
    This1()
    {
        this("Hello");
        System.out.println("Default constructor..");
    }
    This1(int a)
    {
        this();
        System.out.println("int as arg constructor.."); 
    }
    This1(String s)
    {
        System.out.println("string as arg constructor..");  
    }

    public static void main(String args[])
    {
        new This1(100);
    }
}

出力 - arg コンストラクターとしての文字列.. デフォルトのコンストラクター.. arg コンストラクターとしての int..

于 2015-11-27T19:01:24.790 に答える
7

はい、あるコンストラクターを別のコンストラクターから呼び出すことができますthis()

class Example{
   private int a = 1;
   Example(){
        this(5); //here another constructor called based on constructor argument
        System.out.println("number a is "+a);   
   }
   Example(int b){
        System.out.println("number b is "+b);
   }
于 2016-09-13T05:48:26.047 に答える
6

thisキーワードは、コンストラクターからコンストラクターを呼び出すために使用できます。クラスの複数のコンストラクターを記述する場合、コードの重複を避けるために、あるコンストラクターを別のコンストラクターから呼び出したい場合があります。

ベローは、コンストラクターと getters() および setters() に関する他のトピックを説明するリンクであり、2 つのコンストラクターを持つクラスを使用しました。説明と例が役立つことを願っています。

セッター メソッドまたはコンストラクター

于 2017-03-14T23:53:16.330 に答える
1

私はこの方法を好みます:

    class User {
        private long id;
        private String username;
        private int imageRes;

    public User() {
        init(defaultID,defaultUsername,defaultRes);
    }
    public User(String username) {
        init(defaultID,username, defaultRes());
    }

    public User(String username, int imageRes) {
        init(defaultID,username, imageRes);
    }

    public User(long id, String username, int imageRes) {
        init(id,username, imageRes);

    }

    private void init(long id, String username, int imageRes) {
        this.id=id;
        this.username = username;
        this.imageRes = imageRes;
    }
}
于 2019-06-19T08:38:36.010 に答える