20

まず第一に、それが本当にばかげた質問である場合はご容赦ください。私はこの言語をその核心まで学ぼうとしているだけです。私はEffective Javaを読んでいて、最初の章では静的ファクトリメソッドとコンストラクターについて話しています。それらの長所と短所。私を混乱させるいくつかのことは次のとおりです。

  1. 静的ファクトリ メソッドによって返されるオブジェクトのクラスは非公開です- 正確にはどういう意味ですか?
  2. コンストラクタとは異なり、静的ファクトリ メソッドは、呼び出されるたびに新しいオブジェクトを作成する必要はありません。これはどのように行われるのでしょうか? 新しいオブジェクトを取得するためだけにファクトリ メソッドを呼び出しています。オブジェクトが既に存在するかどうかを確認するために、ファクトリ メソッドにチェックを入れますか?

ありがとう。

4

5 に答える 5

11

静的ファクトリメソッドによって返されるオブジェクトのクラスは非公開です-それは正確にはどういう意味ですか?

これは、静的ファクトリメソッドによって返されるオブジェクトの実際のクラスが宣言された型のサブクラスである可能性があり、このサブクラスがパブリックである必要がないことを意味します。これは、クライアントコードが気にしないもう1つの実装の詳細です。

コンストラクターとは異なり、静的ファクトリメソッドは、呼び出されるたびに新しいオブジェクトを作成する必要はありません-これはどのように発生しますか?新しいオブジェクトを取得するためだけにファクトリメソッドを呼び出していますが、オブジェクトがすでに存在するかどうかをチェックするためにファクトリメソッドにチェックインしますか?

はい、それはこれを行うことができる1つの方法です。しかし、実際には、何でも可能です。

于 2010-11-02T15:57:32.047 に答える
5

まず最初に、あなたが Java-lit を選んだことを称賛します。Bloch の本は優れた入門書です。

2 番目の質問に答えるには (「コンストラクターとは異なり、呼び出されるたびに静的ファクトリー メソッドは新しいオブジェクトを作成する必要はありません」)、ブロッホがここで言っていることは、静的ファクトリーではどちらかのオプションがあることを認識することが重要です。 : 新しいオブジェクトを返すか、既存のオブジェクトを返します。それはすべて、あなたが何をしたいかによって異なります。

たとえば、Money 型の非常に単純な値クラスがあるとします。スタティック ファクトリ メソッドは、おそらく新しいインスタンス、つまり Money の特定の値を持つ新しいオブジェクトを返す必要があります。したがって、次のようになります。

public class Money { 

    private Money(String amount) { ... } /* Note the 'private'-constructor */

    public static Money newInstance(String amount) {
        return new Money(amount);
    }

}

しかし、リソースを管理するオブジェクトがあり、ResourceManager クラスを介してそのリソースへのアクセスを同期したいとします。その場合、静的ファクトリ メソッドがそれ自体の同じインスタンスをすべての人に返すようにする必要があります。その 1 つのインスタンスがプロセスを制御できるように、全員が同じインスタンスを通過するように強制します。これはシングルトンパターンに従います。このようなもの:

public ResourceManager {

    private final static ResourceManager me = new ResourceManager();

    private ResourceManager() { ... } /* Note the 'private'-constructor */

    public static ResourceManager getSingleton() {
        return ResourceManager.me;
    }
}

上記の方法により、ユーザーは単一のインスタンスのみを使用できるようになり、管理しているものに誰が (いつ) アクセスできるかを正確に制御できます。


最初の質問に答えるには、次のことを考慮してください (確かに最良の例ではありません。かなりアドホックです)。

public class Money {

    private Money(String amount) { ... }


    public static Money getLocalizedMoney( MoneyType localizedMoneyType, String amount ) { 
        switch( localizedMoneyType ) {
            case MoneyType.US:
                return new Money_US( amount );
            case MoneyType.BR:
                return new Money_BR( amount );
            default:
                return new Money_US( amount );
        }
    }
}

public class Money_US extends Money { ... }

public class Money_BR extends Money { ... }

これを行う方法に注意してください。

Money money = Money.getLocalizedMoney( user_selected_money_type );
saveLocalizedMoney( money );

繰り返しますが、非常に不自然な例ですが、ブロッホがその時点で得ていたものを多かれ少なかれ理解するのに役立つことを願っています.

他の回答は良かったです。初心者として、実際のコードを見ると役立つ場合があると思います。

于 2010-11-02T16:17:50.113 に答える
2

キーワードを使用するnewと、開発者として、JDK がそのオブジェクトの新しいインスタンスを作成することがわかります。著者が言っていることは、静的メソッドを使用すると、開発者はそのメソッドが新しいインスタンスを作成しているのか、それとも何か他のことをしているのかわからなくなるということです。他にも、キャッシュされたデータの再利用、オブジェクトのプーリング、プライベート実装の作成、クラスのサブクラスの返しなどがあります。

于 2010-11-02T15:59:13.840 に答える
1

静的ファクトリ メソッドによって返されるオブジェクトのクラスは非パブリックです

多くの場合、静的ファクトリ メソッドは、インターフェイスとして型指定されたオブジェクト (最も一般的) を返すか、場合によっては何らかの基本クラス (あまり一般的ではありません) を返します。どちらの場合も、返されたオブジェクトの正確なクラスはわかりません。

これの利点は、インスタンス化するクラスの面倒な詳細を気にせずに、動作がわかっているオブジェクトを取得できることです。

コンストラクタとは異なり、静的ファクトリ メソッドは、呼び出されるたびに新しいオブジェクトを作成する必要はありません。

これを理解するために、シングルトンを扱う場合を考えてみましょう。一部のファクトリ クラスで .getInstance() を呼び出して、特定のオブジェクトのシングルトン インスタンスを取得できます。通常、これはオブジェクトのインスタンスが存在しない場合は作成し、存在する場合は既存のインスタンスを提供します。どちらの場合でも、オブジェクトのコピーが返されます。ただし、このシングルトンを作成する必要があるかどうか、または以前に作成されているかどうかはわかりません (また、作成することもありません)。

これの利点は、オブジェクトのライフサイクルと作成時期が管理されることです。

于 2010-11-02T16:03:53.850 に答える
0

両方の質問は、静的ファクトリ メソッドのこれらのプロパティの両方を利用するコードを見ることで答えることができます。Guava のImmutableListを見ることをお勧めします。

引数なしのファクトリ メソッドof()が常に同じインスタンスを返すことに注意してください (毎回新しいインスタンスを作成するわけではありません)。注意深く見ると、copyOf(Iterable)ファクトリ メソッドは、渡されたオブジェクト自体がImmutableList. これらはどちらも、 anImmutableListが決して変わらないことが保証されているという事実を利用しています。

EmptyImmutableListその中のさまざまなファクトリ メソッドが、SingletonImmutableList、、 などのさまざまなサブクラスを返すことにも注意してくださいRegularImmutableList。これらのオブジェクトの型を公開することはありません。メソッド シグネチャは、それらが を返すことを示しているだけImmutableListであり、 のすべてのサブクラスImmutableListはパッケージ プライベート (既定) の可視性を持っているため、ライブラリ ユーザーには見えません。ImmutableListこれにより、複数の実装クラスは単一のタイプとしてのみ表示できるため、ユーザーの観点から複雑さを加えることなく、複数の実装クラスのすべての利点が得られます。

に加えて、 GuavaImmutableListのほとんどのインスタンス化可能なクラスは静的ファクトリ メソッドを利用します。Guava は、Effective Java で規定されている多くの原則の例でもあります (これらの原則と Josh Bloch 自身のガイダンスに基づいて設計されていることを考えると、驚くべきことではありません)。本を通して取り組んでいます。

于 2010-11-02T16:05:25.863 に答える