11

私は最近、 Netflix オープンソース プロジェクトの 1 つを経験していました。

そこで、最終クラスとプライベートコンストラクターの両方の使用を見つけました。私はそれを十分に認識しています

  1. final は継承を避けることです
  2. private は、インスタンス化を許可しないことです

しかし、なぜ両方が一緒に使用されているのか知りたいだけです。メソッドは静的ですが、インスタンス化せずに使用できますが、その背後にある設計原理を知りたいと思っています。

4

2 に答える 2

8

このコードを使用すると、この機能が得られます

  • extends誰にもあなたのクラスのサブクラス化 ( ) を許可しない
  • クラスのインスタンス化を許可しない
  • 変数またはクラスを final にすることでパフォーマンスが向上します (それほどではありませんが、大きなプロジェクトで一般的に使用され、違いが生じます)

この場合、インスタンスを取得するためのシングルトン パターンが見当たらないので、私見ですが、Netflix API のヘルパー/ユーティリティ クラスを探しています。そこでは、開発者チームがいくつかの標準的な手法を使用して、ユーザーが確実にクラスを使用できるようにしました。正しい方法:

StaticFinalClassExample.methodYouWantToCall();

また、リンクしたクラスを見てください:

/**
 * This class consists exclusively of static methods that help verify the compliance of OP1A-conformant....
 */

と:

//to prevent instantiation
private IMFConstraints()
{}

拡張機能:

さらに詳しい情報が必要な場合はItem 4Joshua Bloch の「Effective Java (2nd Edition)」を参照してください。

項目 4: プライベート コンストラクターで非インスタンス化を強制する

静的メソッドと静的フィールドをグループ化しただけのクラスを書きたい場合があります。このようなクラスは、オブジェクトの観点から考えるのを避けるために悪用する人がいるため、悪い評判を得ていますが、有効な用途があります。

  • java.lang.Mathこれらは、またはの方法で、プリミティブ値または配列に関連するメソッドをグループ化するために使用できますjava.util.Arrays
  • また、ファクトリ メソッド (項目 1) を含む、特定のインターフェイスを実装するオブジェクトの静的メソッドを のようにグループ化するためにも使用できますjava.util.Collections
  • final最後に、クラスを拡張する代わりに、クラスのメソッドをグループ化するために使用できます。

このようなユーティリティ クラスは、インスタンス化するようには設計されていません。インスタンスは無意味です。ただし、明示的なコンストラクターがない場合、コンパイラーは、パラメーターなしのパブリックな既定のコンストラクターを提供します。ユーザーにとって、このコンストラクターは他のコンストラクターと区別できません。公開された API で意図せずにインスタンス化可能なクラスを目にすることは珍しくありません。

クラスを抽象化して非インスタンス化を強制しようとしてもうまくいきません。クラスをサブクラス化し、サブクラスをインスタンス化できます。さらに、クラスが継承用に設計されているとユーザーを誤解させます (項目 17)。

ただし、インスタンス化できないことを保証するための簡単なイディオムがあります。既定のコンストラクターは、クラスに明示的なコンストラクターが含まれていない場合にのみ生成されるため、プライベート コンストラクターを含めることでクラスをインスタンス化できないようにすることができます。

于 2016-08-22T12:00:55.243 に答える
0

そのクラスはstaticいわゆる「ユーティリティ」メソッドで構成されているため、そのインスタンスは必要ありません。さらに、そのインスタンスを取得しようとするのは間違っています。クラスは final であるため、クライアント開発者は、元のクラスの意図に反するため、クラスを拡張するオプションがありません。

プライベート コンストラクターには基本的に 2 つの用途があります。作成を制限したいクラスの場合 (たとえば、大量のリソースが必要な場合) にインスタンス化を厳密に制御するためです。この最初のケースではstatic、クライアントのオブジェクトを作成するファクトリ メソッドを提供する必要があります。すなわち:

public static IMFConstraints getInstance()

もう 1 つのケースは、インスタンスを作成することが決して有効でない場合です。その場合、staticクラス自体で呼び出されるメソッドを提供します。すなわち:

public static void checkIMFCompliance(List<PartitionPack> partitionPacks)

上記のメソッドを次のように呼び出します。

// your cool client code here...
IMFConstraints.checkIMFCompliance(myPartitionPacks);
// more of your awesome code...

リンクしたクラスは後者のケースです。

于 2016-08-22T12:01:37.007 に答える