最後に、Stack Overflow で質問があります。:-)
主なターゲットは Java ですが、ほとんど言語にとらわれないと思います。ネイティブ アサートがない場合は、いつでもシミュレートできます。
私は Java で書かれた一連のソフトウェアを販売する会社で働いています。コードは古く、少なくとも Java 1.3 までさかのぼり、いくつかの場所でそれが示されています... これは大きなコード ベースであり、約 200 万行に及ぶため、一度にすべてをリファクタリングすることはできません。
最近、最新バージョンを Java 1.4 構文と JVM から Java 1.6 に切り替え、次のようないくつかの新機能を保守的に使用assert
しました (以前は DEBUG.ASSERT マクロを使用していました -- assert
1.4 で導入されたことは知っていますが、使用しませんでした)。以前)、ジェネリック (型指定されたコレクションのみ)、foreach ループ、列挙型など。
このトピックに関する記事をいくつか読んだことがありますが、私は assert の使用についてまだ少し緑色です。それでも、いくつかの使用法は私を困惑させ、私の常識を傷つけます... ^_^ それで、私が何かを修正したいのが正しいかどうか、またはそれが一般的な慣行に反するかどうかを確認するために、いくつか質問する必要があると思いました. 私は言葉が多いので、ざっと目を通すのが好きな人のために、質問を太字にしました。
参考までに、SO でassert javaを検索したところ、興味深いスレッドがいくつか見つかりましたが、正確な重複はないようです。
- Javaで「!= null」ステートメントを回避するには? nullチェックはどれくらいで十分ですか?変数が null かどうかを確認するだけの多くのアサートがあるため、非常に関連性があります。コードのいくつかの場所では、null オブジェクトが使用されています (例: return
new String[0]
) が、常にではありません。少なくともレガシーコードのメンテナンスのために、私たちはそれを受け入れなければなりません。 - Java assertions underusedにもいくつかの良い答えがあります。
- ああ、SO はいつ Debug.Assert() を使用する必要があるかという理由を示していますか? 質問も関連しています(重複を減らすための優れた機能です!)。
まず、今日私の質問を引き起こした主な問題:
SubDocument aSubDoc = documents.GetAt( i );
assert( aSubDoc != null );
if ( aSubDoc.GetType() == GIS_DOC )
{
continue;
}
assert( aSubDoc.GetDoc() != null );
ContentsInfo ci = (ContentsInfo) aSubDoc.GetDoc();
(はい、私たちは MS の C/C++ スタイル/コード規則を使用しています。私もそれが好きです (同じバックグラウンドから来ました)! だから私たちを訴えてください。 )
まず、フォームは呼び出しassert()
の変換に由来します。DEBUG.ASSERT()
assert は言語構造であり、(もはやここでは) 関数呼び出しではないため、余分な括弧は嫌いです。私も嫌いですreturn (foo);
:-)
次に、アサートはここで不変条件をテストしません。むしろ、悪い値に対するガードとして使用されます。しかし、私が理解しているように、ここでは役に立ちません。アサーションは、コンパニオン文字列で文書化されていなくても、アサーションが有効な場合にのみ例外をスローします。だから私たちが持っているなら-ea
オプションを使用すると、通常の NullPointerException の代わりにアサーションがスローされるだけです。とにかく最高レベルで未チェックの例外をキャッチするため、これは最大の利点のようには見えません。
それらを取り除き、それで生活できると思いますか(つまり、Javaにそのような未確認の例外を発生させます)?(または、もちろん、他の場所で行われている可能性がある場合は、null 値に対してテストします)。
補足: 上記のスニペットで主張する必要がある場合は、ゲッターに対してではなく、ci 値に対して行います。ほとんどのゲッターが最適化/インライン化されている場合でも、確信が持てないため、2 回呼び出すことは避ける必要があります。
最後に参照されたスレッドで、パブリック メソッドはパラメーターの値に対してテストを使用する必要があり (パブリック API の使用)、プライベート メソッドは代わりにアサートに依存する必要があると誰かが言いました。いいアドバイス。
現在、どちらの種類のメソッドも、別のデータ ソースである外部入力をチェックする必要があります。すなわち。たとえば、ユーザー、データベース、ファイル、またはネットワークからのデータ。
私たちのコードでは、これらの値に対するアサートが見られます。私は常にこれらを実際のテストに変更するので、アサーションが無効になっていても機能します。これらは不変条件ではなく、適切に処理する必要があります。
たとえば、リレーションで使用される定数で満たされたデータベーステーブルなど、入力が定数であると想定される例外が1つだけあります。このテーブルが変更されても、対応するコードが更新されないと、プログラムが壊れます。
他の例外はありますか?
私が見た別の比較的頻繁な使用は、問題ないようです: スイッチのデフォルトで、または else if
すべての可能な値をテストする一連の最後で (これらのケースは、列挙型を使用する前にさかのぼります!)、多くの場合、assert false : "Unexpected value for stuff: " + stuff;
正規の Lookがあります。私(これらのケースは本番環境では発生しないはずです)、どう思いますか?(ここでは関係のない「スイッチなし、OOを使用する」というアドバイスを超えて)。
最後に、ここで見逃した便利なユースケースや厄介な落とし穴は他にありますか? (おそらく!)