コードで抑制警告を使用することは良い習慣ですか?


11

私は@SuppressWarnings("unchecked")@SuppressWarnings("null")ほとんどの場合上記の方法を使用して、警告なしでコードをコンパイルできるようにしていますが、疑問があります。このStackoverflowの質問が見つかりました。ジョン・スキートが興味深い答えを書いてくれました。

彼によると、

時々、Javaジェネリックスはあなたがやりたいことをさせないだけで、あなたがしていることが本当に実行時に合法であることをコンパイラに効果的に伝える必要があります。

しかし、例外がスローされる可能性がある場合はどうでしょうか?警告を抑制するのは悪い考えではありませんか?問題が表面化する可能性のある場所を意識する必要はありませんか?

また、誰かが後で私のコードを変更し、SuppressWarningsを削除せずに疑わしい機能を追加した場合はどうなりますか?それをどのように回避できますか、および/またはこれに他の代替手段はありますか?

私が使用してしなければならない@SuppressWarnings("unchecked")@SuppressWarnings("null")


アップデート#1

未チェックの型キャストに関する限り、この回答(以下のコメントで@gnatが指摘)によると、これらの警告を抑制することが必要です。

安全でない型キャストの必要性を排除するために、多くの不可欠なJavaライブラリが更新されたことはありません。これらの警告を抑制することは、他のより重要な警告に気づき修正するために必要です。

他の警告を抑制する場合は、まだ少し灰色の領域にあります。


アップデート#2

あたりとして、Oracleのドキュメント(以下もいくつかの回答で述べました):

スタイルの問題として、プログラマーは常に、このアノテーションが最も効果的な場所で最も深くネストされた要素に使用する必要があります。特定のメソッドで警告を抑制したい場合は、クラスではなくそのメソッドに注釈を付ける必要があります。



彼らはオフ型casts‽について話していない@gnat
Bileshガングリー

1
彼らはありません:「多くの不可欠なJavaライブラリが危険な型キャストの必要性を排除するために更新されていなかったこと、他の多くの重要な警告が気づいて修正されるように、これらの警告を抑制する必要があります。」
gnat

2
その重複の問題はC#に関するものだと思います-コンパイラの警告を抑制するという一般的な考え方とは異なるJava固有の理由がいくつかあります。

回答:


26

私にとって、警告を抑制する目的は、プロジェクトの「健全な法案」を維持することです。コードベース全体が正常にコンパイルされていることがわかっている場合は、誰かが何か問題を起こしたときに、最初の警告が問題リストに表示されるのはすぐにわかります。次に、エラーを修正するか、それが偽であることが証明できる場合はそれを抑制できます。

しかし、そもそも21の警告がある場合、誰かがそれを引き起こしたときに22の警告を見落とす可能性がはるかに高く、無害であることを確認しません。つまり、問題がコードベースに侵入し、気付くことはありません。

警告は有用な情報アイテムです。真実を話す人に注意し、そうでない人を除外してください。あなたがあなたの早期警告システムを失うように、人々が2種類を混合させないでください。

編集する

メリットのある警告抑制することはばかげたことです。あなたが不正行為によって得たきれいな健康法案は明らかに何の価値もありません。選択した場合は、コンパイラーが注意を向けるだけでなく、コンパイラーが気づいた問題を常に修正する必要があります。ただし、問題があるかどうかをコンパイラーが確信できない領域があり(Javaのジェネリックはそのような領域の1つです)、そのような各インスタンスを確認してから、この特定の場所で警告を抑制する方が適切です。このクラスの警告を完全にオフにし、本物の警告を見逃す可能性よりも。


1
「クリーン」なスレートから開始すると、後の警告をキャッチするのに役立つことに部分的に同意します。実際、クリーンにコンパイルされるコードはクリーンに実行されない可能性があります。
user949300

私が仕事で抱えている問題は、他の誰かがそれが何を言っているのか理解していないために抑制した警告にしばしば遭遇することです。したがって、警告にメリットがあるかどうかは主観的な問題だと思います。:/
トレカズ2018年

16

警告の抑制は、細心の注意を払って行う必要があるものです。

警告の意味:コンパイラは、怪しげに見える何かを見つけました。それはそれ危険なものであるという意味ではありません、それコンパイラにとってそれのように見えるだけです。完全に問題がなく、警告を出すコードがある場合があります。場合によっては、コードを少し変更して修正します。コンパイラーには、その目的のために特別な機能がある場合があります。たとえばどこ

if (x = someFunction ()) { ... }

警告を出しますが

if ((x = someFunction ())) { ... }

しません。最初のケースでは、おそらく==ではなく==を意味すると想定した警告。2番目のケースでは、追加の括弧がコンパイラに「私は何をしているのかわかっている」と伝えるため、警告はありません。もちろん良いでしょう

if ((x = someFunction ()) != 0) { ... }

または2行を使用します。

そして、ごくまれに、コードに問題がない場合でも、警告なしに受け入れられる方法でコードを書くことができない場合があります。その非常にまれなケースでは、そのステートメントの警告を無効にし、直後にオンにします。それが最後の手段です。また、その特定の警告のみを無効にし、他の警告は無効にしません。

ただし、一部の人々は、警告を無効にするために警告を無効にするだけです。これは、正当な警告の理由を最初に見つけて修正するのが面倒であるためです。または、警告のないコードを記述しようとはしません。それは非常に不健全なことです。


2
2番目と3番目の例では、閉じ括弧が抜けている可能性があります。
8ビットツリー

1
完全に最後の文章で合意
USR-ローカルΕΨΗΕΛΩΝ

7

メソッド全体の警告を抑制することは疑わしいです。コメントを付けて、特定の行の警告を抑制したほうがよい。例えば

@SuppressWarnings("unchecked") Foo foo = (Foo)object; // Using old library requires this cast

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.