1

このページからJavaの列挙例について読んでいました。

最初の例で、私が理解できなかった唯一の部分staticは、コードのこの部分でのキーワードの使用です。

private static final List<Card> protoDeck = new ArrayList<Card>();

// Initialize prototype deck
static {
    for (Suit suit : Suit.values())
        for (Rank rank : Rank.values())
            protoDeck.add(new Card(rank, suit));
}

public static ArrayList<Card> newDeck() {
    return new ArrayList<Card>(protoDeck); // Return copy of prototype deck
}

protoDeck が宣言されているのはなぜstaticですかfinal? その後、静的ループを使用して protoDeck を初期化します。オブジェクトのインスタンス間で値を保持する静的変数について知っています。ただし、これはシングルトン クラス (プライベート コンストラクター) であるため、インスタンス化できません。

では、上記のようにすることの利点は何ですか?proteDeck がそうでない場合、どのような意味がstaticありfinalますか?

4

6 に答える 6

2

技術的には、これはシングルトン クラスではありません。(シングルトンには1 つのインスタンスがありますが、このインスタンスにはありません!)

これは のファクトリ メソッドでありArrayList<Card>、このメソッドnewDeckはクラス「CardArrayList」のコンストラクタと同じように機能します。これは Java コンストラクターではなく、ファクトリ メソッドですが、それ以外は、新しいカード デッキの作成という同じ目的を果たします。

クラスCardArrayListとサブタイプを使用するArrayListことは明らかに代替手段です。演習としてこれを試してください。同じ目的を果たすようにクラスなどを記述します。static finalオブジェクトの初期セットを保持するために、定数 ( ) を使用してみてください。このアプローチには追加機能がないことを明確に示していることを除いて、これら 2 つの間にほとんど違いはないことがわかりますが、結果は「ArrayList<Card>完全なデッキを含むものにすぎません」。サブクラス化は、デッキが台無しにされないようにするなど、追加の機能があることを意味する場合があります。

このstatic final変数には、新しいオブジェクトのテンプレートとして機能するプロトタイプが含まれています。

于 2012-09-22T19:24:44.170 に答える
1

クラスの初期化 (static括弧内のコード) で、プログラムはデッキのすべてのカードを生成し、それを に格納しprotoDeckます。

newDeck呼び出されると、デッキの浅いコピーが返されます。これは、ゲーム内のすべてのカード オブジェクトが同じオブジェクトであることを意味します (「スペードのエース」カードは 1 つだけです)。ただし、それらはいくつかの異なるデッキで管理されています。

IMHOこの例では少し複雑すぎますCards。他の種類のクラス(初期化にコストがかかる/ RAMで高価なクラス、またはシステムリソースを表す他のクラス-データベース接続など-)の代わりに、より意味があります。 )。

于 2012-09-22T19:32:28.023 に答える
1

コードの static { .... } 部分は、クラスが Java 仮想マシンによってロードされる場所で実行されます。

コード セグメントでは、protoDeck ArrayList を初期化するために使用されます。

クラスが 1 回だけインスタンス化されることを示す証拠がコードにないため、これはシングルトン パターンに従っていません。

于 2012-09-22T19:29:16.577 に答える
0

Javaのfinalキーワードは、あらゆる種類のコンパイル時の魔法を可能にします。たとえば、コンパイラが変数が再割り当てされないことを知っている場合、「メモ化」最適化を実行できます。

finalもちろん、実際にそれらを再割り当てする必要がない限り、これだけでローカル変数、パラメーター、およびクラスメンバーをデフォルトでサイズ変更するのに十分な理由です。

于 2012-09-22T19:35:02.857 に答える
0

そうprotoDeckでなければstatic、それぞれに1つCardあり、それは良いことではありません。

static明らかに、あなたはコードでのみ変数を構築することができstaticます。

finalは決して置き換えられないことを意味しprotoDeckます(ただし、内部で変更することはできます)。

于 2012-09-22T19:37:38.520 に答える
0

静的でない場合、newDeck メソッドが静的であるため、コードはコンパイルされません。また、カードごとに異なるデッキが得られないため、newDeck は静的です。

それを最終的でなくても、何も変わらないでしょう。別の配列を割り当てることができないという点で最終的なものです。ただし、まだ追加できるため、不変ではありません。したがって、これは一般的な手がかりですが、行動の変化ではありません。

于 2012-09-22T19:24:33.607 に答える