34

効果的なJava(第2版)の項目4では、非インスタンス化を強制するためのプライベートコンストラクターの使用について説明しています。この本のコードサンプルは次のとおりです。

public final class UtilityClass {
    private UtilityClass() {
        throw new AssertionError();
    }
}

しかし、AssertionError投げるのは正しいことではないようです。「アサート」されるものはありません。これは、APIがAssertionErrorの使用を定義する方法です。

Throwableこの状況で一般的に見られる違いはありますか?Exception通常、メッセージとともに将軍を投げるだけですか?それともException、このための習慣を書くのが一般的ですか?

それはかなり些細なことですが、何よりも私はスタイルと標準の観点からそれについて興味があります。

4

8 に答える 8

40

「このコンストラクターが呼び出されることはないと断言しています」というアサーションがあります。ですから、確かに、ここでAssertionErrorは正しいです。

于 2008-12-29T22:46:27.483 に答える
11

ブロックのコメントを含めるのが好きです:

// Suppress default constructor for noninstantiability

または、それをエラーに入れることをお勧めします:

private UtilityClass()
{
    throw new AssertionError("Suppress default constructor for noninstantiability");
}
于 2008-12-30T17:26:29.250 に答える
5

UnsupportedOperationExceptionが最も適しているように思えますが、コンパイル時に誤ってクラスをインスタンス化することを誰かに警告する可能性があるため、チェック済みの例外の方がさらに適しています。

于 2008-12-29T23:43:20.847 に答える
2

IllegalAcessErrorはどうですか?:)

于 2008-12-29T22:50:04.167 に答える
2

Josh Bloch に敬意を表して、アサーションによるものでない限り、決してスローしないでください。AssertionError ここで AssertionError が必要な場合は、 でスローしassert(false)ます。その後、コードを読んでいる人が後でそれを見つけることができます。

さらに良いことに、独自の例外を定義してくださいCantInstantiateUtilityClass。次に、次のようなコードがあります

try {
    // some stuff
} catch (CantInstantiateUtilityClass e) {
    // react
}

キャッチャーの読者がが起こったのかを知ることができるように。


標準では、明確に定義された有益な例外の代わりにスローされるべきだと初心者が考えるものではなく、失敗したアサーションの結果として定義していることに注意してください。残念なことに、適切な例外処理は、おそらく Java プログラミングで最も推奨されていないスキルです。AssertionError

于 2008-12-29T23:30:02.747 に答える
2

コードが Maven テスト スコープ内などの依存関係として JUnit を含める必要がある場合は、メソッド<scope>test</scope>に直接進みAssertion.fail()、明快さの大幅な改善の恩恵を受けます。

public final class UtilityClass {
    private UtilityClass() {
        fail("The UtilityClass methods should be accessed statically");
    }
}

テスト範囲外の場合、次のようなものを使用できます。これには、上記のように静的インポートを使用する必要があります。 import static pkg.Error.fail;

public class Error {
    private static final Logger LOG = LoggerFactory.getLogger(Error.class);
    public static void fail(final String message) {
        LOG.error(message);
        throw new AssertionError(message);
        // or use your preferred exception 
        // e.g InstantiationException
    }
}

次の使用法。

public class UtilityClassTwo {
    private UtilityClassTwo() {
        Error.fail("The UtilityClass methods should be accessed statically");
    }
}

最も慣用的な形式では、それらはすべて次のようになります。

public class UtilityClassThree {
    private UtilityClassThree() {
        assert false : "The UtilityClass methods should be accessed statically";
    }
}

組み込み例外の 1 つである UnsupportedOperationException をスローして、「要求された操作がサポートされていない」ことを示すことができます。

 private Constructor() {
    throw new UnsupportedOperationException(
            "Do not instantiate this class, use statically.");
}
于 2018-07-15T14:15:57.783 に答える
0

アサーションが壊れているということは、コードのコントラクト仕様が壊れていることを意味します。ですから、ここではそれが正しいことです。

ただし、インスタンスを非公開でインスタンス化すると想定しているため、別のコンストラクターがない限り、コンストラクターも呼び出されてエラーが発生します。

于 2008-12-29T22:48:00.507 に答える