102

定数を保持するだけのクラスを定義する必要があるとします。

public static final String SOME_CONST = "SOME_VALUE";

これを行うための好ましい方法は何ですか?

  1. インターフェース
  2. 抽象クラス
  3. 最終クラス

どちらを使用する必要があり、その理由は?


いくつかの回答の説明:

列挙型- 列挙型を使用するつもりはありません。何も列挙していません。互いにまったく関係のないいくつかの定数を収集しているだけです。

インターフェイス- インターフェイスを実装するクラスとして設定するつもりはありません。インターフェイスを使用して、次のように定数を呼び出したいだけですISomeInterface.SOME_CONST

4

11 に答える 11

109

最終クラスを使用します。簡単にするために、静的インポートを使用して別のクラスで値を再利用できます

public final class MyValues {
  public static final String VALUE1 = "foo";
  public static final String VALUE2 = "bar";
}

別のクラスで:

import static MyValues.*
//...

if(variable.equals(VALUE1)){
//...
}
于 2009-01-26T12:06:51.403 に答える
39

あなたの明確化は次のように述べています。

定数が互いにまったく関連していない場合、なぜそれらをまとめたいのですか? 各定数は、最も密接に関連するクラスに配置します。

于 2009-01-26T12:28:20.377 に答える
33

私の提案(好みの降順で):

1)しないでください。最も関連性の高い実際のクラスで定数を作成します。「定数のバッグ」クラス/インターフェースを持つことは、実際にはオブジェクト指向のベストプラクティスに従っていません。

私と他のみんなは、時々 1 を無視します。それを行う場合は、次のようにします。

2)プライベート コンストラクターを使用した最終クラスこれにより、定数に簡単にアクセスできるように拡張/実装することで、誰かが「定数のバッグ」を悪用するのを少なくとも防ぐことができます。(あなたがこれをやらないと言ったのは知っていますが、それはあなたがやらないと誰かがやってくるという意味ではありません)

3)インターフェースこれは機能しますが、私の好みではありません。

一般に、これらが定数であるからといって、通常の oo 原則をそれらに適用してはならないというわけではありません。定数を気にするクラスが 1 つしかない場合、それはプライベートでそのクラス内にある必要があります。テストのみが定数を気にする場合、それは本番コードではなく、テストクラスにある必要があります。定数が複数の場所で定義されている場合 (偶然に同じであるだけでなく) - リファクタリングして重複を排除します。など - メソッドと同じように扱います。

于 2009-04-07T17:14:49.760 に答える
14

JoshuaBlochがEffectiveJavaで述べているように:

  • インターフェイスは、タイプを定義するためにのみ使用する必要があります。
  • 抽象クラスは、不安定性を防ぐことはできません(サブクラス化することができ、サブクラス化するように設計されていることを示唆することさえあります)。

すべての定数が関連している場合(惑星名など)に列挙型を使用したり、関連するクラスに定数値を配置したり(アクセスできる場合)、インスタンス化できないユーティリティクラスを使用したり(プライベートデフォルトコンストラクターを定義)できます。 。

class SomeConstants
{
    // Prevents instanciation of myself and my subclasses
    private SomeConstants() {}

    public final static String TOTO = "toto";
    public final static Integer TEN = 10;
    //...
}

次に、すでに述べたように、静的インポートを使用して定数を使用できます。

于 2009-01-26T12:32:27.887 に答える
7

私の好みの方法は、それをまったくしないことです。Java 5 でタイプセーフな列挙型が導入されたとき、定数の時代はほとんど終わりました。そしてそれ以前にも、Josh Bloch は、Java 1.4 (およびそれ以前) で動作するバージョンの (少し冗長な) バージョンを公開しました。

レガシーコードとの相互運用性が必要でない限り、名前付き文字列/整数定数を使用する理由はもうありません。

于 2009-01-26T12:06:59.653 に答える
3

enum大丈夫です。IIRC、有効な Java (第 2 版) の 1 つの項目には、任意の値enumの [Java キーワード]interfaceを実装する標準オプションを列挙する定数があります。

interface私の好みは、final classfor 定数よりも [Java キーワード] を使用することです。を暗黙的に取得しpublic static finalます。一部の人々は、悪いプログラマーがそれを実装することを許可すると主張するでしょうinterfaceが、悪いプログラマーは、あなたが何をしてもうまくいかないコードを書くでしょう。

どっちが見栄えがいい?

public final class SomeStuff {
     private SomeStuff() {
         throw new Error();
     }
     public static final String SOME_CONST = "Some value or another, I don't know.";
}

または:

public interface SomeStuff {
     String SOME_CONST = "Some value or another, I don't know.";
}
于 2009-01-26T13:47:29.547 に答える
3

最終クラスを使用するだけです。

他の値を追加できるようにしたい場合は、抽象クラスを使用してください。

インターフェイスを使用してもあまり意味がありません。インターフェイスはコントラクトを指定することになっています。いくつかの定数値を宣言したいだけです。

于 2009-01-26T12:03:23.017 に答える
3

これらの種類のものには列挙型が最適ではないでしょうか?

于 2009-01-26T12:06:07.363 に答える
1

または 4. 定数を最もよく使用するロジックを含むクラスに配置します。

...申し訳ありませんが、抵抗できませんでした;-)

于 2009-01-26T12:07:45.177 に答える
-1
  1. プライベート コンストラクターの欠点の 1 つは、メソッドの存在をテストできないことです。

  2. 特定のドメインタイプに適用するのに適した性質の概念による列挙型、分散定数に適用するのは十分ではないようです

Enum の概念は、「列挙は密接に関連するアイテムのセットです」です。

  1. 定数インターフェイスを拡張/実装することは悪い習慣です。不変定数を直接参照する代わりに拡張する必要があることを考えるのは難しいです。

  2. SonarSource のような高品質ツールを適用する場合、開発者に定数インターフェイスの削除を強制するルールがあります。多くのプロジェクトが定数インターフェイスを楽しんでおり、定数インターフェイスで「拡張」が発生することはめったにないため、これは厄介なことです。

于 2015-09-11T06:34:42.077 に答える