Java 2 SDK 開発ガイド (Solaris 編)

設計 FAQ - アサーションの有効化および無効化

  1. オブジェクトファイルからアサーションを完全に削除するコンパイラフラグを提供しないのはなぜでしょうか。

    「フィールドでアサーションを有効にできるようにする」という強い要求があります。開発者がコンパイル時にオブジェクトファイルからアサーションを削除できるようにするという可能性もありました。しかし、アサーションには本来はあってはいけない副作用が生じることもあるため、このようなフラグはプログラムの動作を大幅に変えてしまう可能性があります。有効な Java プログラムごとにセマンティクスが 1 つだけ関連付けられていることが理想的です。また、オブジェクトファイルにアサーションを残しておけばフィールドで有効にできるので、ユーザにはこちらの方が推奨されます。最後に、標準 Java の「条件付きコンパイル」(JLS 14.19 を参照) を使用すると、必要に応じてこの結果を実現することができます。

  2. setPackageAssertionStatus のセマンティクスが、単純なパッケージ型でなく、パッケージツリー型なのはなぜでしょうか。

    実際には、プログラマはパッケージ階層を使用して自分たちのコードを編成しているので、階層型の制御の方が便利です。たとえば、パッケージツリー型のセマンティクスを使用すると、一度にすべての Swing でアサーションを有効または無効にできます。

  3. 呼び出されたときにはすでにアサーション状態を設定するには遅すぎた場合 (つまり、名前付きクラスがすでにロードされている場合)、setClassAssertionStatus が例外をスローするのではなく、boolean 値を戻すのはなぜでしょうか。

    アサーション状態を設定するには遅すぎた場合、警告メッセージなど以外は対処の必要がないか、対処しないでください。 例外のスローは適切ではありません。

  4. setDefaultAssertionStatus と setAssertionStatus の代わりに単一メソッドをオーバーロードしないのはなぜでしょうか。

    メソッドの名前付けにおいては、わかりやすさを優先するためです。

  5. アプレットがアサーションを有効または無効にすることを防ぐための RuntimePermission が存在しないのはなぜでしょうか。

    アプレットは任意の ClassLoader メソッドを呼び出してアサーション状態を変更する必要はありませんが、これを許可するとマイナスの状況が生じる可能性があります。まだロードされていないクラスのアサーションを有効にすると、最悪の場合、アプレットは弱い DoS 攻撃を受ける可能性があります。さらに、アプレットがアサーション状態を変更できるのは、アプレットがアクセスできるクラスローダによってロードされる予定のクラスだけです。すでに、信頼できないコードがクラスローダへのアクセス権を取得できないようにするための RuntimePermission は存在します (getClassLoader)。

  6. 包含クラスのアサーション状態を照会するための構文を提供しないのはなぜでしょうか。

    このような構文を提供すると、プログラマは複雑なアサーションコードをインラインにしようとし、これは望ましくありません。


               if (assertsEnabled()) {
                   ...
               }

    さらに、必要であれば、現在の API の上のアサーションの状態を照会することは簡単です。


     boolean assertsEnabled = false;
              assert assertsEnabled = true;  // Intentional side-effect!!!
              // Now assertsEnabled is set to the correct value