18

いつコンストラクターを使用し、いつ静的メソッドを使用する必要がありますか?

上記を短いスニペットで説明できますか? いくつかのスレッドをざっと読みましたが、これについてはまだ明確ではありません。

4

9 に答える 9

21

Joshua Blochは、コンストラクターではなく静的ファクトリメソッドを使用することをお勧めします(これは良い習慣だと思います)。いくつかの長所と短所:

静的ファクトリメソッドの利点:

  • コンストラクターとは異なり、名前があります
  • コンストラクターとは異なり、コンストラクターは呼び出されるたびに新しいオブジェクトを作成する必要はありません(インスタンスをキャッシュできます:例:Boolean.valueOf(..)
  • コンストラクターとは異なり、リターンタイプの任意のサブタイプのオブジェクトを返すことができます(柔軟性が高い)

静的ファクトリメソッドのデメリット:

  • それらは他の静的メソッドと実際には区別できません(APIに精通していない場合、オブジェクトを初期化する方法を見つけるのは困難です)
  • 主な欠点(静的ファクトリメソッドのみを使用し、コンストラクターをプライベートにする場合)は、そのクラスをサブクラス化できないことです。
于 2012-12-10T14:49:06.250 に答える
19

その型の新しいオブジェクトのみを返す必要があり、単純さが必要な場合は、パブリック コンストラクターを使用します。

良い例は StringBuilder です。これは変更可能であり、毎回新しいオブジェクトが必要になる可能性が高いためです。

public String toString() {
    StringBuilder sb = new StringBuilder();
    // append fields to the sb
    return sb.toString();
}

オブジェクトを再利用したい場合 (特に不変の場合)、サブクラスを返したい場合、または記述の構築が必要な場合は、静的因子メソッドを使用します。良い例は EnumSet で、同じ引数を持っているものもありますが、異なることを行う多数の静的ファクトリがあります。

EnumSet.noneOf(RetentionPolicy.class);
// has the same arguments, but is not the same as
EnumSet.allOf(RetentionPolicy.class);

この場合、静的ファクトリを使用すると、セットを構築するこれら 2 つの方法の違いが明確になります。

また、EnumSet は 2 つの異なる実装を返すことができます。1 つは少数の値 (<= 64) を持つ列挙型用に最適化され、もう 1 つはRegularEnumSet呼び出される多くの値用に最適化されています。JumboEnumSet

于 2012-12-10T14:37:41.940 に答える
8

クラスに状態がある場合は、常にコンストラクターを使用します(単一のインスタンスの場合でも、シングルトンパターン)。

java.lang.Mathのようなユーティリティメソッドにのみstaticを使用します

例:

public static int max(int a, int b) {
    return (a >= b) ? a : b;
}

オブジェクトの状態(インスタンス変数)を変更しないため、静的と宣言できます。

于 2012-12-10T14:41:23.317 に答える
4
  1. オブジェクトや、オブジェクトごとに1つのコピーを持つ関数や変数などの他のものが必要な場合は、コンストラクターを使用します。
  2. オブジェクトを作成せずに何かをしたい場合は、静的メソッドを使用します。

    Example:
    public class Test {
    public int value;
    public static int staticValue;
    public int getValue() {
    return ++value;
    }
    
    public static int getStaticValue() {
    return ++staticValue;
    }
    }
    
    public class TestClass {
    public static void main(String[] args) {
    Test obj = new Test();
    Test obj1 = new Test();
    S.o.p(obj.getValue());
    S.o.p(obj1.getValue));
    S.o.p(Test.getStaticValue());
    S.o.p(Test.getStaticValue());
    }
    }
    
于 2012-12-10T14:41:23.807 に答える
3

静的ファクトリ メソッドには名前がありますが、コンストラクタにはありません。したがって、ファクトリー・メソッドは、コンストラクターではできないことについての自然なドキュメントを運ぶことができます。たとえば、Guava Libraries のファクトリ メソッドを参照してくださいImmutableMap.copyOf(otherMap)。これは構築の動作にはほとんど影響しないかもしれませんが、コードの可読性に大きな影響を与えます。API を公開する場合は、これを必ず考慮してください。

また、作成しているオブジェクトのより複雑な構成を行う必要がある場合、特に他のスレッドに公開する必要がある場合 (プールへの登録、MBean としての公開、その他すべての方法... )際どい出版を避けるため。(たとえば、Java Concurrency In Practice セクション 3.2 を参照)

何かを行う静的メソッド(例: Math.min) は、実際には静的ファクトリと同じではありません。静的ファクトリは、柔軟性、進化性、および (多くの場合) 明快さが追加された、コンストラクターの直接の代替と見なすことができます。

于 2012-12-10T14:39:41.813 に答える
2

オブジェクトのインスタンスを作成する必要があるときはいつでも、コンストラクターを使用する必要があります。

したがって、Car オブジェクトを作成する場合は、そのためのコンストラクターが必要になります。

キーワード static は、インスタンスを作成せずにメソッドを呼び出すことができることを意味します。

于 2012-12-10T14:40:18.027 に答える
2
class Car
{
   private int num_of_seats;

   public Car(int number_of_seats)
   {
      this.num_of_seats = number_of_seats;
   }

   // You want to get the name of the class that has to do with
   // this class, but it's not bounded with any data of the class
   // itself. So you don't need any instance of the class, and 
   // you can declare it as static.
   static String getClassName()
   {
      return "[Car]";
   }
}

一般に、オブジェクトのインスタンスと関連付けられていないデータで静的クラスを使用します。

別の例は次のとおりです。

class Ring
{
   private List nodes;

   public Ring(List nodes) 
   {
      this.nodes = nodes;
   }

   // You want to calculate the distance of two ids on the ring, but
   // you don't care about the ring. You care only about the ids.
   // However, this functionality logical falls into the notion of
   // the ring, that's why you put it here and you can declare it
   // as static. That way you don't have to manage the instance of 
   // ring.
   static double calculateDistance(int id_1, int id_2)
   {
      return (id_1 - id_2)/383; // The divisor is just random just like the calculation.
   }
}

上記の投稿が言うように、それはあなたが何をしたいのか、どのようにそれをしたいかの問題です. また、すぐにすべてを理解しようとするのではなく、いくつかのコードを書いてから、そのコードのさまざまなアプローチを試し、コードが何をするかを理解しようとします。例は良いのですが、書いてから何をしたかを理解する必要があります。それが、なぜスタッフをそのようにしなければならないのかを理解する唯一の方法だと思います。

于 2012-12-11T19:02:19.130 に答える
1

つまり、シングルトンを使用する場合、つまり、他のユーザーと共有される可能性のあるオブジェクトのインスタンスが1つしかない場合は、内部でコンストラクターを呼び出す静的メソッドが必要です。したがって、誰かがそのオブジェクトのインスタンスを必要とするたびに、常に同じものが返されます。したがって、メモリを消費するのは1つだけです。すべてのオブジェクト指向言語で、オブジェクト指向プログラミングのコンストラクターが常に必要です。Javaでは、他の多くの言語では、オブジェクトのデフォルトコンストラクターが暗黙的に示され、自動的に構築されます。ただし、独自に作成する必要のあるカスタム機能が必要です。

上に、使用法のいくつかの良い例があります。ただし、具体的なことをお考えの場合はお知らせください。つまり、静的メソッドとコンストラクターのどちらを使用すべきかわからない特定のケースがある場合です。とにかく、コンストラクターが必要になることは間違いありませんが、静的メソッドについてはよくわかりません。

于 2012-12-10T14:54:22.593 に答える
1

静的メソッドは、毎回新しいオブジェクトをインスタンス化する必要はありません。オブジェクトのインスタンス化はコストがかかるため、インスタンスをオブジェクト内にキャッシュできます。したがって、パフォーマンスを向上させることができます。

これは、Effective Javaからの説明です。

これにより、不変クラス (項目 15) は、事前に構築されたインスタンスを使用したり、構築時にインスタンスをキャッシュしたり、インスタンスを繰り返し分配して不要な重複オブジェクトの作成を回避したりできます。Boolean.valueOf(boolean) メソッドはこの手法を示しています。オブジェクトを作成することはありません。このテクニックは Flyweight パターン [Gamma95, p. 195]。同等のオブジェクトが頻繁に要求される場合、特にそれらの作成にコストがかかる場合は、パフォーマンスを大幅に向上させることができます。

于 2012-12-10T14:46:11.900 に答える