FindBugs Bug DescriptionsThis document lists the standard bug patterns reported by FindBugs version 3.0.1. SummaryDescriptionsBC: equals メソッドは引数の型を仮定するべきではない (BC_EQUALS_METHOD_SHOULD_WORK_FOR_ALL_OBJECTS)
BIT: ビット演算の符号をチェックする (BIT_SIGNED_CHECK)
このメソッドは、 Boris Bokowski CN: Cloneable を実装したクラスが clone メソッドを定義していないか、使用していない (CN_IDIOM)
このクラスは、 CN: clone メソッドが super.clone() を呼び出していない (CN_IDIOM_NO_SUPER_CALL)
この非 final クラスは、
すべての CN: Cloneable を実装していないクラスが clone メソッドを定義している (CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE)
このクラスは、 CNT: 既知の定数の雑な値を見つける (CNT_ROUGH_CONSTANT_VALUE)コードの明確さともっと良い正確さのために定義済みライブラリ定数を使用することを推奨します。 Co: 抽象クラスは共変な compareTo メソッドを定義している (CO_ABSTRACT_SELF)
このクラスは、共変な Co: compareTo()/compare() は間違って float または double 値を処理する (CO_COMPARETO_INCORRECT_FLOATING)このメソッドはこのようなパターンを使用して double または float 値を比較しています : val1 > val2 ? 1 : val1 < val2 ? -1 : 0。 このパターンは 正しくないソート結果や壊れたコレクションの原因になるかもしれない -0.0 や NaN 値のために間違って働きます (もし比較された値がキーとして使われるなら)。 すべての特殊なケースを正確に処理するために Double.compare または Float.compare メソッドの使用を検討してください。 Co: compareTo()/compare() は Integer.MIN_VALUE を返す (CO_COMPARETO_RESULTS_MIN_VALUE)
いくつかの状況下では、この Co: 共変な compareTo メソッドの定義 (CO_SELF_NO_OBJECT)
このクラスは、共変な DE: 例外を捨てているかもしれないメソッド (DE_MIGHT_DROP)このメソッドは、例外を捨てているかもしれません。 一般的にキャッチした例外は何らかの方法で処理、または報告するべきです、またはメソッドからスローするべきです。 DE: 例外を無視しているかもしれないメソッド (DE_MIGHT_IGNORE)このメソッドは例外を無視しているかもしれません。 一般的に例外は何らかの方法で処理、または報告するべきです、またはメソッドからスローするべきです。 DMI: エントリセットの要素を加えることは、Entry オブジェクトの再利用のために失敗するかもしれない (DMI_ENTRY_SETS_MAY_REUSE_ENTRY_OBJECTS)entrySet メソッドは、一つの Entry オブジェクトを再利用し、反復中に返される基底 Map のビューを返すことが許可されています。 Java 1.6 の時点で、IdentityHashMap と EnumMap の両方がそうしました。 そのような Map を通して繰り返すとき、エントリ値は次の繰り返しへ進むまでが有効です。 たとえば、addAll メソッドにそのような entrySet を渡そうと試みるのは、ひどく間違っているでしょう。 DMI: Random オブジェクトが作成され1度しか使われない (DMI_RANDOM_USED_ONLY_ONCE)
このコードは、
生成された乱数が推測可能でないことが重要なら、乱数ごとに新しい DMI: コレクションを消去するために removeAll メソッドを使用しない (DMI_USING_REMOVEALL_TO_CLEAR_COLLECTION)
コレクション Dm: System.exit(...) を呼び出しているメソッド (DM_EXIT)
Dm: 危険なメソッド runFinalizersOnExit を呼び出しているメソッド (DM_RUN_FINALIZERS_ON_EXIT)
どんな理由があるにせよ決して ES: String パラメータを == や != を使用して比較している (ES_COMPARING_PARAMETER_STRING_WITH_EQ)
このコードは、参照等価性のために == や != を使用して ES: String オブジェクトを == や != を使用して比較している (ES_COMPARING_STRINGS_WITH_EQ)
このコードは、参照等価性のために == や != を使用して Eq: 抽象クラスは共変な equals メソッドを宣言している (EQ_ABSTRACT_SELF)
このクラスは、共変な Eq: equals メソッドは互換性のないオペランドをチェックしている (EQ_CHECK_FOR_OPERAND_NOT_COMPATIBLE_WITH_THIS)
この public boolean equals(Object o) { if (o instanceof Foo) return name.equals(((Foo)o).name); else if (o instanceof String) return name.equals(o); else return false; }
これは対称的で推移的である Eq: compareTo(...) メソッドを定義して Object.equals() を使用しているクラス (EQ_COMPARETO_USE_OBJECT_EQUALS)
このクラスは、 Comparable インタフェースの compareTo メソッドの JavaDoc を以下に引用します。
Eq: equals メソッドはサブタイプのために失敗する (EQ_GETCLASS_AND_CLASS_CONSTANT)
このクラスは、サブクラスによる継承によって壊れる Eq: 共変な equals メソッドの定義 (EQ_SELF_NO_OBJECT)
このクラスは、共変な FI: 空のファイナライザは削除するべき (FI_EMPTY)
空の FI: ファイナライザの明示的な呼び出し (FI_EXPLICIT_INVOCATION)
このメソッドには明示的にオブジェクトで
参照によってつながった複数のオブジェクトがファイナライズ可能になると、Java 仮想マシンはすべてのオブジェクトの FI: ファイナライザはフィールドを null にする (FI_FINALIZER_NULLS_FIELDS)このファイナライザは、フィールドを null にしています。 これは通常誤りでガベージコレクタを助けません。オブジェクトはいずれにしろガベージされます。 FI: ファイナライザはフィールドを null にするだけ (FI_FINALIZER_ONLY_NULLS_FIELDS)
このファイナライザは、フィールドを null にすること以外に何もしません。
これはまったく無意味であり、オブジェクトがガベージされ、ファイナライズされ、再びガベージされることを要求しています。
FI: ファイナライザはスーパークラスのファイナライザを呼び出していない (FI_MISSING_SUPER_CALL)
この FI: ファイナライザはスーパークラスのファイナライザを無効にしている (FI_NULLIFY_SUPER)
この空の FI: ファイナライザはスーパークラスのファイナライザを呼び出しているだけ (FI_USELESS)
この FS: 書式文字列は \n よりも %n を使用するべき (VA_FORMAT_STRING_USES_NEWLINE)この書式文字列には改行文字 (\n) が含まれています。 一般的に書式文字列には %n を使用することがより望ましいです。%n は、プラットホーム特有の行セパレータを作り出します。 GC: 検査されない型への総称呼び出し (GC_UNCHECKED_TYPE_IN_GENERIC_CALL)総称型パラメータからの特定の型が予想される Object 型をコンパイルするとき、総称型コレクションメソッドへの呼び出しは引数を渡します。 したがって、標準の Java 型システムも静的解析もパラメータとして渡されているオブジェクトが適切な型かどうかに関する有用な情報を提供できません。 HE: equals メソッドは定義していますが hashCode メソッドは定義していないクラス (HE_EQUALS_NO_HASHCODE)
このクラスは、 HE: equals メソッドを定義して Object.hashCode() を使用しているクラス (HE_EQUALS_USE_HASHCODE)
このクラスは、
このクラスのインスタンスが HashMap/HashTable に決して代入されるだろうと思わないなら推奨される public int hashCode() { assert false : "hashCodeが呼び出されることは想定されていません。"; return 42; // 適当な値 } HE: hashCode メソッドを定義していますが equals メソッドは定義していないクラス (HE_HASHCODE_NO_EQUALS)
このクラスは、 HE: hashCode メソッドを定義して Object.equals() を使用しているクラス (HE_HASHCODE_USE_OBJECT_EQUALS)
このクラスは、
このクラスのインスタンスが HashMap/HashTable に決して代入されるだろうと思わないなら推奨される public int hashCode() { assert false : "hashCodeが呼び出されることは想定されていません。"; return 42; // 適当な値 } HE: equals メソッドを継承して Object.hashCode() を使用しているクラス (HE_INHERITS_EQUALS_USE_HASHCODE)
このクラスは、抽象スーパークラスから
IC: スーパークラスは初期化中にサブクラスを使用している (IC_SUPERCLASS_USES_SUBCLASS_DURING_INITIALIZATION)
クラスは、初期化中にサブクラスを積極的に使用しています。サブクラスはこの時点ではまだ初期化されていません。 public class CircularClassInitialization { static class InnerClassSingleton extends CircularClassInitialization { static InnerClassSingleton singleton = new InnerClassSingleton(); } static CircularClassInitialization foo = InnerClassSingleton.singleton; } IMSE: 疑わしい IllegalMonitorStateException のキャッチ (IMSE_DONT_CATCH_IMSE)
ISC: static メソッドだけを提供するクラスの不必要なインスタンス化 (ISC_INSTANTIATE_STATIC_CLASS)このクラスは、static メソッドだけを提供するクラスのオブジェクトを作成しています。 このオブジェクトは作成する必要はありません。修飾子として直接クラス名を使用する static メソッドにアクセスしてください。 It: Iterator.next() が NoSuchElementException をスローできない (IT_NO_SUCH_ELEMENT)
このクラスは、 J2EE: HttpSession への非直列化可能オブジェクトの格納 (J2EE_STORE_OF_NON_SERIALIZABLE_OBJECT_INTO_SESSION)このコードは、HttpSession に非直列化可能オブジェクトを格納していると思われます。 このセッションが不活性化されるか移行したなら、エラーを招きます。 JCIP: 不変クラスのフィールドは final にすべき (JCIP_FIELD_ISNT_FINAL_IN_IMMUTABLE_CLASS)クラスは、net.jcip.annotations.Immutable または javax.annotation.concurrent.Immutable でアノテートされています。 アノテーションのルールは、すべてのフィールドが final であることを義務づけます。 ME: public 列挙型メソッドが無条件にフィールドを設定するPublic enum method unconditionally sets its field (ME_ENUM_FIELD_SETTER)無条件に列挙型フィールドを設定している public 列挙型で public メソッドを宣言しています。 したがって、フィールドは悪意のあるコードや偶然別のパッケージによって変更できます。 可変列挙型フィールドが遅延初期化で使用されるかもしれないとしても外界へ暴露するバッドプラクティスです。 このメソッドを除去するかパッケージプライベートとして宣言することを考えてください。 ME: 列挙型フィールドは public で可変である (ME_MUTABLE_ENUM_FIELD)可変 public フィールドが public 列挙型の中に定義されています。 したがって、フィールドは悪意のあるコードや偶然別のパッケージによって変更できます。 可変列挙型フィールドが遅延初期化で使用されるかもしれないとしても外界へ暴露するバッドプラクティスです。 このメソッドを final およびパッケージプライベートとして宣言することを考えてください。 NP: 戻り型が Boolean のメソッドが明示的に null を返している (NP_BOOLEAN_RETURN_NULL)Boolean.TRUE、Boolean.FALSE、null を返すメソッドはいつ事故が起きてもおかしくないです。 このメソッドは、まるで論理型の値を返すかのように呼び出されます。 コンパイラは Boolean 値のオートアンボクシングを挿入します。 null 値が返されるなら NullPointerException が発生することになります。 NP: null を返すかもしれない clone メソッド (NP_CLONE_COULD_RETURN_NULL)
この NP: equals メソッドは null の引数をチェックしていない (NP_EQUALS_SHOULD_HANDLE_NULL_ARGUMENT)
この NP: null を返すかもしれない toString メソッド (NP_TOSTRING_COULD_RETURN_NULL)
この Nm: クラス名は大文字から始めるべき (NM_CLASS_NAMING_CONVENTION)クラス名は、最初の文字とそれに続く各単語の最初の文字を大文字にした名詞にすべきです。 クラス名は単純でわかりやすいようにしてください。 頭文字や略語 (URLやHTMLなどのように略語がロング形式よりもはるかに広く使われている場合を除く) の使用は避けてください。 Nm: 例外クラスのように命名されているが、クラスは Exception から派生されていない (NM_CLASS_NOT_EXCEPTION)このクラスは、例外クラスから派生されていないのにクラス名が「Exception」で終わっています。 これはこのクラスのユーザに紛らわしいです。 Nm: 紛らわしい名前のメソッド (NM_CONFUSING)参照されたメソッドは、大文字の使い方だけによって異なる名前があります。 Nm: フィールド名は小文字から始めるべき (NM_FIELD_NAMING_CONVENTION)final でないフィールドの名前は、最初の文字は小文字にし、それに続く各単語の最初の文字を大文字にすべきです。 Nm: Java の後のバージョンのキーワードである識別子を使用している (NM_FUTURE_KEYWORD_USED_AS_IDENTIFIER)識別子は、Java の後のバージョンのキーワードとして予約されている単語です。 コードを Java の後のバージョンでコンパイルするためには変更する必要があります。 Nm: Java の後のバージョンのキーワードである識別子を使用している (NM_FUTURE_KEYWORD_USED_AS_MEMBER_IDENTIFIER)この識別子は、Java の後のバージョンのキーワードとして使われます。 このコードと API を参照するどんなコードも、Java の後のバージョンでコンパイルするためには変更する必要があります。 Nm: メソッド名は小文字から始めるべきです (NM_METHOD_NAMING_CONVENTION)メソッド名は、最初の文字は小文字にし、それに続く各単語の最初の文字を大文字にした動詞にすべきです。 Nm: クラス名は実装されたインタフェースの単純名を遮るべきではない (NM_SAME_SIMPLE_NAME_AS_INTERFACE)
このクラスまたはインタフェースは、インタフェースが異なるパッケージであるということを除いて実装された/拡張されたインタフェースと同一の単純名です (たとえば、 Nm: クラス名はスーパークラスの単純名を遮るべきではない (NM_SAME_SIMPLE_NAME_AS_SUPERCLASS)
このクラスは、スーパークラスが異なるパッケージであるということを除いて、スーパークラスと同一の単純名をです (たとえば、 Nm: 非常に紛らわしい名前のメソッド (多分意図的) (NM_VERY_CONFUSING_INTENTIONAL)参照されたメソッドは、大文字の使い方だけによって異なる名前があります。 大文字の使い方が同一ならメソッドの1つが他のメソッドをオーバーライドするので、非常に紛らわしいです。 他のメソッドの存在から、これらのメソッドの両方の存在が意図的で、確実に混乱させていると思われます。 APIの凍結によって両方とも持たざるを得ない場合を除き、それらのうちの1つを除去しようと努力するべきです。 Nm: パラメータの間違ったパッケージのためにスーパークラスのメソッドをオーバーライドしていないメソッド (NM_WRONG_PACKAGE_INTENTIONAL)
パラメータの型が正確にスーパークラスで対応するパラメータの型と合致していないので、サブクラスのメソッドはスーパークラスの類似したメソッドをオーバーライドしていません。 import alpha.Foo; public class A { public int f(Foo x) { return 17; } } ---- import beta.Foo; public class B extends A { public int f(Foo x) { return 42; } public int f(alpha.Foo x) { return 27; } }
クラス この場合、サブクラスがスーパークラスのメソッドと同一のシグネチャでメソッドを定義しているので、おそらく理解できます。 しかしながら、そのようなメソッドは非常に紛らわしいです。 類似しているが同一ではないシグネチャのメソッドを除去するか、非推奨にすることを強く検討するべきです。 ODR: データベースリソースのクローズに失敗するかもしれないメソッド (ODR_OPEN_DATABASE_RESOURCE)このメソッドは、データベースリソース (たとえば、データベースコネクションや行セット) を作成していますが、どんなフィールドにも代入していないか、他のメソッドにも渡していないか、戻り値にもしていません。 そして、メソッドからのすべての経路でオブジェクトをクローズするように見えません。 メソッドからのすべての経路でデータベースリソースのクローズが失敗すると性能低下になることがあります。 データベースとの通信で問題があるアプリケーションの原因になる可能性があります。 ODR: 例外経路でデータベースリソースのクローズに失敗するかもしれないメソッド (ODR_OPEN_DATABASE_RESOURCE_EXCEPTION_PATH)このメソッドは、データベースリソース (たとえば、データベースコネクションや行セット) を作成していますが、どんなフィールドにも代入していないか、他のメソッドにも渡していないか、戻り値にもしていません。 そして、メソッドからのすべての例外経路でオブジェクトをクローズするように見えません。 メソッドからのすべての経路でデータベースリソースのクローズが失敗すると性能低下になることがあります。 データベースとの通信で問題があるアプリケーションの原因になる可能性があります。 OS: ストリームのクローズに失敗するかもしれないメソッド (OS_OPEN_STREAM)
このメソッドは、入出力ストリームオブジェクトを作成していますが、どんなフィールドにも代入していないしクローズするかもしれない別のメソッドにも渡していなくて、戻り値にしてもいません。そして、メソッドからのすべての経路でクローズするように見えません。
これはファイルディスクリプタリークの原因になることがあります。
ストリームがクローズされることを確実にするために OS: 例外経路でストリームのクローズに失敗するかもしれないメソッド (OS_OPEN_STREAM_EXCEPTION_PATH)
このメソッドは、入出力ストリームオブジェクトを作成していますが、どんなフィールドにも代入していないしクローズするかもしれない別のメソッドにも渡していないくて、戻り値にしてもいません。そして、メソッドからのすべての可能性がある例外経路でクローズするように見えません。
これはファイルディスクリプターリークの原因になることがあります。
ストリームがクローズされることを確実にするために PZ: 繰り返しでエントリオブジェクトを再利用しない (PZ_DONT_REUSE_ENTRY_OBJECTS_IN_ITERATORS)
このクラスは、Iterator と Map.Entry で基底 Map のビューを返すことを許可された両方の entrySet メソッドがあります。
この巧妙なアイデアは、Map 実装で使用されましたが、厄介なコーディング間違いの可能性を取り込みました。
Map RC: 定数への疑わしい参照比較 (RC_REF_COMPARISON_BAD_PRACTICE)
このメソッドは、 参照値を == または != 演算子を使用して定数と比較しています。
一般的にこの型のインスタンスを比較する正しい方法は RC: Boolean 値の疑わしい参照比較 (RC_REF_COMPARISON_BAD_PRACTICE_BOOLEAN)
このメソッドは、== または != 演算子を使用して2つの Boolean 値を比較しています。
一般的には2つの Boolean 値 ( RR: InputStream.read() の戻り値を無視しているメソッド (RR_NOT_CHECKED)
このメソッドは、複数バイトを返す可能性がある RR: InputStream.skip() の戻り値を無視しているメソッド (SR_NOT_CHECKED)
このメソッドは、複数バイトをスキップする可能性がある RV: compareTo()/compare() の結果を無効にする (RV_NEGATING_RESULT_OF_COMPARETO)
このコードは、 RV: 例外的戻り値を無視しているメソッド (RV_RETURN_VALUE_IGNORED_BAD_PRACTICE)
このメソッドはチェックされていない値を返しています。
戻り値は異常か予想外の実行結果を示す可能性があるのでチェックするべきです。
たとえば、 SI: スタティックイニシャライザは、すべての static final フィールドが代入される前にインスタンスを作成する (SI_INSTANCE_BEFORE_FINALS_ASSIGNED)すべての static final フィールドが初期化される前にスタティックイニシャライザがクラスのインスタンスを作成します。 SW: Swing メソッドは AWT イベントディスパッチスレッドから呼び出す必要がある (SW_SWING_METHODS_INVOKED_IN_SWING_THREAD)
(From JDC Tech Tip) Se: 直列化可能クラスの非 transient で非直列化可能なインスタンスフィールド (SE_BAD_FIELD)
この直列化可能クラスは、transient、Serializable、 Se: 非直列化可能クラスに直列化可能な内部クラスがある (SE_BAD_FIELD_INNER_CLASS)この直列化可能クラスは、非直列化可能クラスの内部クラスです。 内部クラスを直列化しようとすると関連する外部クラスのインスタンスを結びつけようとするので、実行時エラーの原因になります。 できれば、内部クラスを static にして問題を解決するべきです。 外部クラスを直列化可能にすることで動作するかもしれないが、内部クラスのインスタンスを直列化することは外部クラスも常に直列化することを意味します。 本当に望むことですか。 Se: 非直列化可能な値を直列化可能クラスのインスタンスフィールドに格納している (SE_BAD_FIELD_STORE)非直列化可能な値を直列化可能クラスの 非 transient フィールドに格納しています。 Se: Comparator は Serializable を実装していない (SE_COMPARATOR_SHOULD_BE_SERIALIZABLE)
このクラスは Se: 直列化可能な内部クラス (SE_INNER_CLASS)この直列化可能なクラスは内部クラスです。内部クラスを直列化しようとすると関連した外部クラスのインスタンスも直列化します。 外部クラスのインスタンスは直列化可能なので失敗しません。しかし、意図していたよりももっと多くのデータを直列化するかもしれません。 できれば、内部クラスを static にして問題を解決するべきです。 Se: serialVersionUID が final ではない (SE_NONFINAL_SERIALVERSIONID)
このクラスは、final でない Se: serialVersionUID が long ではない (SE_NONLONG_SERIALVERSIONID)
このクラスは、long でない Se: serialVersionUID が static ではない (SE_NONSTATIC_SERIALVERSIONID)
このクラスは、static でない Se: Serializable なクラスのスーパークラスで、引数なしコンストラクタを定義していない (SE_NO_SUITABLE_CONSTRUCTOR)
このクラスは Se: Externalizable なクラスが引数なしコンストラクタを定義していない (SE_NO_SUITABLE_CONSTRUCTOR_FOR_EXTERNALIZATION)
このクラスは、 Se: readResolve メソッドの戻り値の型が Object で宣言されていない (SE_READ_RESOLVE_MUST_RETURN_OBJECT)
Se: 直列化復元によって設定されない transient フィールド (SE_TRANSIENT_FIELD_NOT_RESTORED)このクラスには複数の場所で更新されるフィールドがあります。したがって、このクラスの状態の一部だと思われます。 しかしながら、フィールドは transient と宣言しているので、 readObject/readResolve で値が設定されません。 クラスの直列化復元されたインスタンスにはデフォルト値が設定されます。 SnVI: Serializable なクラスが serialVersionUID を定義していない (SE_NO_SERIALVERSIONID)
このクラスは UI: クラスが拡張されるなら getResource の使い方は安全ではないかもしれない (UI_INHERITANCE_UNSAFE_GETRESOURCE)
このクラスが別のパッケージによって拡張されるなら、 BC: 不可能なキャスト (BC_IMPOSSIBLE_CAST)このキャストは、常に ClassCastException をスローします。 FindBugs は、instanceof チェックから型情報を調査して、メソッドからの戻り値とフィールドからロードされた値の型について、より多くの正確な情報を使用します。 したがって、宣言された変数の型にはより多くの正確な情報があるかもしれないしれません。 また、キャストが常に実行時例外をスローするのかを決定するために利用する可能性があります。 BC: 不可能なダウンキャスト (BC_IMPOSSIBLE_DOWNCAST)このキャストは、常に ClassCastException をスローします。 解析はキャストしている値の正確な型がわかっていると信じています。 そして、サブタイプへダウンキャストしようとする試みは、ClassCastException のスローによって常に失敗します。 BC: toArray メソッドの結果の不可能なダウンキャスト (BC_IMPOSSIBLE_DOWNCAST_OF_TOARRAY)
このコードは、以下のように、 String[] getAsArray(Collection<String> c) { return (String[]) c.toArray(); }
これは通常 ClassCastException をスローして失敗します。
ほとんどすべてのコレクションの BC: 常に false を返す instanceof (BC_IMPOSSIBLE_INSTANCEOF)この instanceof は常に false を返します。これは安全で、誤解や論理エラーを指摘していないことを確認してください。 BIT: 符号付きバイト値のビット加算 (BIT_ADD_OF_SIGNED_BYTE)
バイト値と明らかに下位8ビットがあるとわかっている値を加算しています。
ビット演算を実行する前にバイト配列からロードされた値は32ビットまで符号拡張されます。
したがって、 特に、バイト配列 int にパックする以下のようなコードはひどく間違っています。 int result = 0; for(int i = 0; i < 4; i++) result = ((result << 8) + b[i]); その代わりに以下のようなイディオムは動作します。 int result = 0; for(int i = 0; i < 4; i++) result = ((result << 8) + (b[i] & 0xff)); BIT: 互換性のないビットマスク (BIT_AND)このメソッドは、(e & C) 形式の式を D と比較しています。 定数 C の特定の値と D ために常に等しくないことを比較します。論理エラーかタイプミスかもしれません。 BIT: ((...) & 0) == 0 なのか確かめている (BIT_AND_ZZ)このメソッドは、(e & 0) 形式の式を0と比較しています。それは、常に等価であることを比較します。論理エラーかタイプミスかもしれません。 BIT: 互換性のないビットマスク (BIT_IOR)
このメソッドは、 典型的に、このバグは、ビットセットで帰属関係のテストを実行したいコードで発生します。 しかし、ビット論理積演算子 ("&") の代わりにビット論理和演算子 ("|") を使用しています。 BIT: 符号付きバイト値のビット論理和 (BIT_IOR_OF_SIGNED_BYTE)
ロードしたバイト値 (たとえば、バイト配列からロードされた値や戻り値がバイト型のメソッドから返された値) とビット論理和を実行しています。
ビット演算を実行する前にバイト値は32ビットまで符号拡張されます。
したがって、 特に、バイト配列 int にパックする以下のようなコードはひどく間違っています。 int result = 0; for(int i = 0; i < 4; i++) { result = ((result << 8) | b[i]); } その代わりに以下のようなイディオムは動作します。 int result = 0; for(int i = 0; i < 4; i++) { result = ((result << 8) | (b[i] & 0xff)); } BIT: ビット演算の符号をチェックする (BIT_SIGNED_CHECK_HIGH_BIT)
このメソッドは、 Boris Bokowski BOA: スーパークラスの Adapter で実装されるメソッドを誤ってオーバーライドしているクラス (BOA_BADLY_OVERRIDDEN_ADAPTER)このメソッドは、スーパークラスで実装されているメソッドをオーバーライドしています。 スーパークラスは、java.awt.event や javax.swing.event パッケージで定義されているリスナを実装する Adapter です。 その結果、イベントが発生するときこのメソッドは呼び出されません。 BSHIFT: シフト演算の正しくない構文解析の可能性がある (BSHIFT_WRONG_ADD_PRIORITY)コードは (x << 8 + y) のような操作を行います。 これは正しいかもしれませんが、おそらく (x << 8) + y を行うことを意図していました。 しかし、シフト演算は優先順位が低いので、実際には x << (8 + y) として構文解析されます。 BSHIFT: 32ビット int の-31から31の範囲を超えた量によるシフト (ICAST_BAD_SHIFT_AMOUNT)このコードは、32ビット int の-31から31の範囲を超えた量でシフトを実行しています。 これの効果は、どのくらいシフトするのかを決めるために整数値の下位5ビット (32で割った余り) を使用することです (たとえば、40ビットでシフトすることは8ビットでシフトすることと同じで、32ビットでシフトすることは0ビットでシフトすることと同じです)。 これはおそらく期待されたことではなく、少なくとも紛らわしいです。 DLS: return 文に無駄なインクリメントがある (DLS_DEAD_LOCAL_INCREMENT_IN_RETURN)
DLS: クラスリテラルの無効な代入 (DLS_DEAD_STORE_OF_CLASS_LITERAL)
この命令は変数にクラスリテラルを代入していますが、決して使われません。 より多くの詳細と例と J2SE 5.0 のクラスの強制的な初期化の方法の提案は Sun の article on Java SE compatibility を参照してください。 DLS: 上書きされたインクリメント (DLS_OVERWRITTEN_INCREMENT)
このコードは、インクリメント演算 (たとえば、 DMI: 逆にされた引数 (DMI_ARGUMENTS_WRONG_ORDER)
このメソッド呼び出しへの引数は、順序が間違っているように見えます。
たとえば、呼び出し DMI: 月のための間違った定数値 (DMI_BAD_MONTH)このコードは、メソッドに0から11の範囲外の月定数値を渡しています。 DMI: 正確に表されない double から構築された BigDecimal (DMI_BIGDECIMAL_CONSTRUCTED_FROM_DOUBLE)
このコードは、10進数の数にうまく変換されない double 値から BigDecimal を作成しています。
たとえば、Java で
おそらく DMI: hasNext メソッドで next メソッドを呼び出している (DMI_CALLING_NEXT_FROM_HASNEXT)
DMI: コレクションは自分自身を含めるべきではない (DMI_COLLECTIONS_SHOULD_NOT_CONTAIN_THEMSELVES)
この総称型コレクションメソッドへの呼び出しはコレクションに自分自身が含まれている場合 (たとえば、 DMI: D'oh! 無意味なメソッド呼び出し (DMI_DOH)この部分的なメソッド呼び出しは、検査から明らかな理由で意味がありません。 DMI: 配列で hashCode メソッドを呼び出している (DMI_INVOKING_HASHCODE_ON_ARRAY)
このコードは、配列で DMI: int に対して Double.longBitsToDouble() を呼び出している (DMI_LONG_BITS_TO_DOUBLE_INVOKED_ON_INT)
DMI: コレクションへの無意味な呼び出し (DMI_VACUOUS_SELF_COLLECTION_CALL)
この呼び出しは意味がありません。
どんなコレクション Dm: ランタイムリテンションなしで、アノテーションの存在を調べるためにリフレクションを使用することはできない (DMI_ANNOTATION_IS_NOT_VISIBLE_TO_REFLECTION)
アノテーションは、 Dm: ScheduledThreadPoolExecutor の最大プールサイズを変えようとする無駄な試み (DMI_FUTILE_ATTEMPT_TO_CHANGE_MAXPOOL_SIZE_OF_SCHEDULED_THREAD_POOL_EXECUTOR)
Dm: コアプールサイズが0の ScheduledThreadPoolExecutor の作成 (DMI_SCHEDULED_THREAD_POOL_EXECUTOR_WITH_ZERO_CORE_THREADS)
コアプールサイズが0の Dm: EasyMock メソッドへの役に立たない/無意味な呼び出し (DMI_VACUOUS_CALL_TO_EASYMOCK_METHOD)この呼び出しは EasyMock メソッドにどんなオブジェクトも渡さないので何もしません。 Dm: Math.max と Math.min の間違った組み合わせ (DM_INVALID_MIN_MAX)
このコードは、 EC: equals メソッドを使用して配列と非配列を比較している (EC_ARRAY_AND_NONARRAY)
このメソッドは、配列と配列だと思われない参照を比較するために EC: 配列の equals メソッド呼び出しは == と等価である (EC_BAD_ARRAY_COMPARE)
このメソッドは、配列で EC: equals(...) メソッドを使用して互換性のない配列を比較している (EC_INCOMPATIBLE_ARRAY_COMPARE)
このメソッドは、互換性のない型の配列を比較するために EC: equals(null) の呼び出し (EC_NULL_ARG)
このメソッドは、 null 値の引数を渡して EC: equals メソッドを呼び出して無関係のクラスとインタフェースを比較している (EC_UNRELATED_CLASS_AND_INTERFACE)
このメソッドは、一方がクラスで他方がインタフェースである2つの参照で EC: equals メソッドを呼び出して異なる型のインタフェースを比較している (EC_UNRELATED_INTERFACES)
このメソッドは、どちらも他方のサブタイプでない無関係なインタフェース型の2つの参照で EC: equals メソッドを呼び出して異なる型を比較している (EC_UNRELATED_TYPES)
このメソッドは、異なるクラス型の2つの参照で EC: 参照等価性を使用して異なる型を比較している (EC_UNRELATED_TYPES_USING_POINTER_EQUALITY)このメソッドは異なる型と思われる2つの参照を比較するために参照等価性を使用しています。 この比較の結果は、常に false です。 Eq: equals メソッドは常に false を戻す (EQ_ALWAYS_FALSE)
このクラスでは、常に false を返す
おそらく意図されたことは、オブジェクトはそれ自身と等価であるというオブジェクト同一性です。
これは public boolean equals(Object o) { return this == o; } Eq: equals メソッドは常に true を返す (EQ_ALWAYS_TRUE)
このクラスは、常に true を返す Eq: equals メソッドはクラスオブジェクトではなくクラス名を比較している (EQ_COMPARING_CLASS_NAMES)このメソッドは、クラス名を比較することによって、2つのオブジェクトが同じクラスなのか確かめています。 異なるクラスローダによってロードされたクラスなら、同じ名前で異なるクラスがある可能性があります。 クラスオブジェクトが同じなのか確かめてください。 Eq: 列挙型は共変な equals メソッドを定義している (EQ_DONT_DEFINE_EQUALS_FOR_ENUM)
このクラスは列挙を定義していて、列挙の等価性はオブジェクト同一性を使用して定義されています。
列挙値のために共変な Eq: equals(Object) メソッドをオーバーライドしていない equals メソッドの定義 (EQ_OTHER_NO_OBJECT)
このクラスは、 Eq: Object.equals(Object) をオーバーライドしていない equals メソッドの定義 (EQ_OTHER_USE_OBJECT)
このクラスは、 Eq: equals メソッドはスーパークラスの equals メソッドをオーバーライドしているが、対称的ではないかもしれない (EQ_OVERRIDING_EQUALS_NOT_SYMMETRIC)
このクラスはスーパークラスの Eq: 共変な equals メソッドを定義して、Object.equals(Object) を継承している (EQ_SELF_USE_OBJECT)
このクラスは、共変な FE: NaN への等価性のための絶望的なテスト (FE_TEST_IF_EQUAL_TO_NOT_A_NUMBER)
このコードは、浮動小数点が特別な非数値と等価であるか確かめています (たとえば FS: 書式指示子へ渡している引数に互換性がない (VA_FORMAT_STRING_BAD_ARGUMENT)
書式指示子は、対応する引数と互換性がありません。
たとえば、 FS: 与えられた引数の型は書式指示子に合致しません (VA_FORMAT_STRING_BAD_CONVERSION)
引数の1つは、対応する書式指示子と互換性がありません。その結果、実行されるときに実行時例外を生成します。
たとえば、 FS: printf スタイルの書式が期待されているところで MessageFormat が与えられている (VA_FORMAT_STRING_EXPECTED_MESSAGE_FORMAT_SUPPLIED)Java の printf 書式文字列と引数のリストを期待するメソッドが呼び出されています。 しかしながら、書式文字列にはどんな書式指示子 (たとえば、%s) も含まないで、メッセージフォーマットの要素 (たとえば、{0}) を含んでいます。 printf スタイルの書式文字列が必要なときに、MessageFormat の文字列を与えている可能性が高いです。 実行時に、すべての引数は無視され、書式文字列は正確にフォーマットされずに返されます。 FS: 書式文字列で実際に使われるより、多くの引数が渡されている (VA_FORMAT_STRING_EXTRA_ARGUMENTS_PASSED)可変長引数による書式文字列メソッドが呼び出されていますが書式文字列で実際に使われるより多くの引数が渡されています。 これは実行時例外の原因とはなりませんが、コードはフォーマットされた文字列に含まれることを意図した情報を黙って省略しているかもしれません。 FS: 無効な書式文字列 (VA_FORMAT_STRING_ILLEGAL)書式文字列は構文的に無効です。この文が実行されると実行時例外が発生します。 FS: 書式文字列は足りない引数を参照している (VA_FORMAT_STRING_MISSING_ARGUMENT)書式文字列で書式指示子を満たすために十分な引数が渡されていません。この文が実行されると実行時例外が発生します。 FS: 書式文字列ための前の引数がない (VA_FORMAT_STRING_NO_PREVIOUS_ARGUMENT)
この書式文字列は、前の書式指示子の引数が再利用されるようにするために「相対インデックス ("<")」を指定しています。
しかしながら、前の引数がありません。
たとえば、 GC: 型パラメータとメソッド引数に関係がない (GC_UNRELATED_TYPES)
総称型コレクションメソッドへの呼び出しにコレクションのパラメータとは互換性のないクラスの引数があります (すなわち、引数の型は総称型引数に対応するスーパタイプでもサブタイプでもありません)。
したがって、コレクションにはここで使用されたメソッド引数と等価であるどんなオブジェクトも含まれていません。
多分間違った値がメソッドに渡されています。
一般的に2つの無関係なクラスのインスタンスは等価ではありません。
たとえば、
まれに、非対称 HE: ハッシュ化された文脈でハッシュ化できないクラスの使用がシグネチャで宣言されている (HE_SIGNATURE_DECLARES_HASHING_OF_UNHASHABLE_CLASS)
メソッド、フィールド、クラスは、ハッシュ可能なクラスが必要な文脈で、ハッシュ化できないクラスが使用される総称的なシグネチャを宣言しています。
クラスは、 HE: ハッシュデータ構造で hashCode メソッドのないクラスを使用している (HE_USE_OF_UNHASHABLE_CLASS)
このクラスは、 ICAST: int 値を long に変換して絶対時間として使用している (ICAST_INT_2_LONG_AS_INSTANT)
このコードは、32ビット int 値を64ビット long 値に変換して、絶対時間値を必要とするメソッドパラメータに渡しています。
絶対時間値は、「エポック」(すなわち、1970年1月1日、00:00:00 GMT)としてわかっている標準的な基準時間からのミリ秒数です。 Date getDate(int seconds) { return new Date(seconds * 1000); } 乗算は32ビット演算を使用して、64ビット値に変換されます。 32ビット値は、64ビットに変換されて、絶対時間値を表すために使用されるとき、1969年12月と1970年1月の日付しか表せません。 上記のメソッドの正しい実装は以下のとおりです。 // 失敗、2037年後の日付 Date getDate(int seconds) { return new Date(seconds * 1000L); } // より良い、すべての日付で動作する Date getDate(long seconds) { return new Date(seconds * 1000); } ICAST: 整数値を double にキャストして Math.ceil() に渡している (ICAST_INT_CAST_TO_DOUBLE_PASSED_TO_CEIL)
このコードは、整数値 (たとえば、int や long) を倍精度浮動小数点に変換してから、その結果を ICAST: 整数値を float にキャストして Math.round() に渡している (ICAST_INT_CAST_TO_FLOAT_PASSED_TO_ROUND)
このコードは、整数値を float 精度浮動小数点に変換してから、その結果を IJU: run メソッドでの JUnit アサーションは JUnit によって通知されない (IJU_ASSERT_METHOD_INVOKED_FROM_RUN_METHOD)
IJU: TestCase は suite メソッドの間違った宣言をしている (IJU_BAD_SUITE_METHOD)
JUnit の TestCase クラスで、 public static junit.framework.Test suite() か public static junit.framework.TestSuite suite() のどちらかを宣言する必要があります。 IJU: TestCase はテストがない (IJU_NO_TESTS)JUnit の TestCase クラスで、どんなテストメソッドも実装していません。 IJU: TestCase は super.setup() を呼び出さない setUp メソッドを実装している (IJU_SETUP_NO_SUPER)
JUnit の TestCase クラスで、 IJU: TestCase は 非 static な suite メソッドを実装している (IJU_SUITE_NOT_STATIC)
JUnit の TestCase クラスで、 IJU: TestCase は super.tearDown() を呼び出さない tearDown メソッドを実装している (IJU_TEARDOWN_NO_SUPER)
JUnit の TestCase クラスで、 IL: コレクションは自分自身を追加している (IL_CONTAINER_ADDED_TO_ITSELF)
コレクションは、自分自身を追加しています。その結果、hashCode を計算すると IL: 明らかな無限ループ (IL_INFINITE_LOOP)このループは、例外をスローする以外の方法で終了させることができないように思われます。 IL: 明らかな無限再帰ループ (IL_INFINITE_RECURSIVE_LOOP)このメソッドは、無条件で自分自身を呼び出します。これはスタックオーバーフローになる無限再帰ループを示しています。 IM: 整数剰余の結果の整数乗算 (IM_MULTIPLYING_RESULT_OF_IREM)このコードは、整数剰余の結果に整数定数を乗算しています。 紛らわしい演算子の優先順位がないことを確実にしてください。 たとえば、i % 60 * 1000 は、i % (60 * 1000) ではなく (i % 60) * 1000 となります。 INT: int 値と long 定数との間違った比較 (INT_BAD_COMPARISON_WITH_INT_VALUE)このコードは、int 値と int 値として表される値の範囲外の long 定数を比較しています。 この比較は無意味で、おそらく間違っています。 INT: 負でない値と負の定数またはゼロとの間違った比較 (INT_BAD_COMPARISON_WITH_NONNEGATIVE_VALUE)このコードは、負でないことが保証されている値と負の定数またはゼロとを比較しています。 INT: 符号付きバイトの間違った比較 (INT_BAD_COMPARISON_WITH_SIGNED_BYTE)
符号付バイトのとりうる値の範囲は-128~127です。その範囲外で符号付バイトを値と比較することは無意味で間違っていそうです。
符号付きバイト IO: オブジェクト出力ストリームへの追加は失敗に終わる (IO_APPENDING_TO_OBJECT_OUTPUT_STREAM)このコードは、ファイルを追加モードで開いて、オブジェクト出力ストリームの中で結果をラップしています。 これはファイルに格納された既存のオブジェクト出力ストリームに追加できないでしょう。 オブジェクト出力ストリームに追加したいなら、オブジェクト出力ストリームを開いておく必要があります。 追加モードでファイルを開き、オブジェクト出力ストリームで書き込むことができる唯一の状況は、 ファイルを読み出すときにランダムアクセスモードで開き、追加を開始するところまでバイトオフセットをシークすると計画した場合です。 IP: メソッドで読み取られずに上書きされているパラメータ (IP_PARAMETER_IS_DEAD_BUT_OVERWRITTEN)このパラメータの初期値は無視され、ここで上書きされています。 これは多くの場合、パラメータへの書き込みが呼び出し元に戻されるという誤った考えを示しています。 MF: スーパークラスのフィールドを隠すフィールドを定義しているクラス (MF_CLASS_MASKS_FIELD)このクラスは、スーパークラスの可視インスタンスフィールドと同じ名前でフィールドを定義しています。 これは紛らわしくて、メソッドがフィールドを更新するかアクセスするなら、間違いを指摘するかもしれません。 MF: フィールドを隠す変数を定義しているメソッド (MF_METHOD_MASKS_FIELD)このメソッドは、このクラスまたはスーパークラスのフィールドと同じ名前でローカル変数を定義しています。 フィールドから初期化されていない値を読み出す、初期化されていないフィールドをそのままにしておくか、または両方を引き起こすかもしれません。 NP: null 値を利用している (NP_ALWAYS_NULL)ここで null 値を利用しようとしています。 コードが実行されると NullPointerException が発生します。 NP: null 値を例外経路で利用している (NP_ALWAYS_NULL_EXCEPTION)例外経路上のここで null 値を利用しています。コードが実行されると NullPointerException が発生します。 現在の FindBugs は実行不可能な例外経路を刈り取れていないので、誤検出かもしれないことに注意してください。 switch 文の default が多くの場合実行不可能なので FindBugs が例外経路である default を検討することに注意して下さい。 NP: null の引数をチェックしていないメソッド (NP_ARGUMENT_MIGHT_BE_NULL)このメソッドへのパラメータが null かどうか確かめるために常にチェックされるべき値として特定されました。 しかし、null チェックをしないで、null 値が利用されています。 NP: 常に null 値のオブジェクトで close メソッドを呼び出している (NP_CLOSING_NULL)
NP: null 値を利用することが保証されている (NP_GUARANTEED_DEREF)文または分岐が実行されるなら、この時点で値は null であり、null 値を利用する (フォワードパスで実行時例外を伴うこと以外は) ことが保証されています。
なお、 NP: null 値を例外経路で利用することが保証されている (NP_GUARANTEED_DEREF_ON_EXCEPTION_PATH)例外経路上の文または分岐が実行されるなら、この時点で値は null であり、null 値を利用する (フォワードパスで実行時例外を伴うこと以外は) ことが保証されています。 NP: 非 null フィールドは初期化されていない (NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR)フィールドは、非 null としてマークされていますが、コンストラクタで書き込まれていません。 フィールドは、コンストラクタの間、ほかの場所で初期化されるか、または使用する前に常に初期化されるかもしれません。 NP: メソッド呼び出しは非 null パラメータに対して null を渡している (NP_NONNULL_PARAM_VIOLATION)このメソッドは、非 null でなければならないメソッドのパラメータとして、null 値を渡しています。 このパラメータは、@Nonnull として明示的にアノテートされていたか、または解析が常に null 値を利用すると示していました。 NP: null を返すかもしれないメソッドが @Nonnull 宣言されている (NP_NONNULL_RETURN_VIOLATION)このメソッドは、null 値を返すかもしれないのにメソッド (またはスーパークラスのメソッド) の戻り値に @Nonnull が宣言されています。 NP: null とわかっている値をその型のインスタンスなのか確かめている (NP_NULL_INSTANCEOF)チェックされている値が null であることが保証されているので、instanceof は常に faluse を返します。 これは安全で、誤解や論理エラーを指摘していないことを確認してください。 NP: null 値を利用している可能性がある (NP_NULL_ON_SOME_PATH)そこで分岐または文が実行されるなら null 値が利用されて NullPointerException が発生します。 もちろん、問題は分岐または文が実行不可能で、NullPointerException が決して発生する可能性がないということかもしれません。 それを決めるのは FindBugs の能力を超えています。 NP: null 値を例外経路で利用している可能性がある (NP_NULL_ON_SOME_PATH_EXCEPTION)例外経路上のここで null 値が利用されています。コードが実行されると NullPointerException を引き起こすことがあります。 現在の FindBugs は実行不可能な例外経路を刈り取れていないので、誤検出かもしれないことに注意してください。 switch 文の default が多くの場合実行不可能なので FindBugs が例外経路である default を検討することに注意して下さい。 NP: メソッド呼び出しは非 null パラメータに対して null を渡している (NP_NULL_PARAM_DEREF)このメソッド呼び出しは非 null メソッドパラメータに対して null 値を渡しています。 パラメータは、常に非 null とすべきパラメータとしてアノテートされていたか、または解析が常に null 値を利用すると示していました。 NP: メソッド呼び出しは非 null パラメータに対して null を渡している (NP_NULL_PARAM_DEREF_ALL_TARGETS_DANGEROUS)すべての既知のターゲットメソッドが非 null であることをパラメータに要求する呼び出し場所で、おそらく null 値を渡しています。 パラメータは、常に非 null とすべきパラメータとしてアノテートされていたか、または解析が常に null 値を利用すると示していました。 NP: 非 null パラメータに null を渡している非仮想メソッドの呼び出し (NP_NULL_PARAM_DEREF_NONVIRTUAL)null の可能性がある値が 非 null メソッドパラメータに渡されています。 パラメータは、常に非 null とすべきパラメータとしてアノテートされていたか、または解析が常に null 値を利用すると示していました。 NP: Optional の戻り型を持つメソッドが明示的に null を返す (NP_OPTIONAL_RETURN_NULL)Optional の戻り型の使い方は、常に明示的に null を返すのは設計が望ましくないことを意味します。 null 値をこのようなケースで返すことは契約違反で、多分クライアントコードを破壊するでしょう。 NP: @Nonnull でアノテートされたフィールドに null を格納している (NP_STORE_INTO_NONNULL_FIELD)@Nonnull としてアノテートされたフィールドに null かもしれない値を格納しています。 NP: 書き込まれていないフィールドの読み出し (NP_UNWRITTEN_FIELD)プログラムは、決して null でない値を書き込むとは思われないフィールドの値を利用しています。 この値を利用すると NullPointerException が発生します。 Nm: クラスは equal(Object) を定義しています。equals(Object) にすべきですか? (NM_BAD_EQUAL)
このクラスは、 Nm: クラスは hashcode() を定義しています。hashCode() にすべきですか? (NM_LCASE_HASHCODE)
このクラスは、 Nm: クラスは tostring() を定義しています。toString() にすべきですか? (NM_LCASE_TOSTRING)
このクラスは、 Nm: 明らかなメソッドとコンストラクタの混乱 (NM_METHOD_CONSTRUCTOR_CONFUSION)この正規のメソッドは定義しているクラスと同じ名前です。 これはコンストラクタを意図していた可能性が高いです。もしそうなら void 戻り値の宣言を除去してください。 偶然メソッドを定義したことが間違いだとわかり、適切なコンストラクタを定義したが、後方互換性のためにこのメソッドを除去できないならメソッドを非推奨にしてください。 Nm: 非常に紛らわしい名前のメソッド (NM_VERY_CONFUSING)参照されたメソッドは、大文字の使い方だけによって異なる名前があります。 大文字の使い方が同一ならメソッドの1つが他のメソッドをオーバーライドするので、非常に紛らわしいです。 Nm: パラメータの間違ったパッケージのためにスーパークラスのメソッドをオーバーライドしていないメソッド (NM_WRONG_PACKAGE)
パラメータの型がスーパークラスで対応するパラメータの型と正確に合致していないので、サブクラスのメソッドはスーパークラスの類似したメソッドをオーバーライドしていません。 import alpha.Foo; public class A { public int f(Foo x) { return 17; } } ---- import beta.Foo; public class B extends A { public int f(Foo x) { return 42; } }
クラス QBA: 論理式で boolean リテラル値を代入しているメソッド (QBA_QUESTIONABLE_BOOLEAN_ASSIGNMENT)このメソッドは、if または while の式の中の boolean 変数に boolean リテラル値 (true または false) を代入しています。 おそらく、これは = による代入ではなく、== を使用して論理比較をすることになっていました。 RANGE: 配列インデックスは範囲外 (RANGE_ARRAY_INDEX)配列演算が行なわれますが、配列インデックスが範囲外なので実行時に ArrayIndexOutOfBoundsException が発生するでしょう。 RANGE: 配列の長さは範囲外 (RANGE_ARRAY_LENGTH)メソッドは、配列パラメータと長さパラメータで呼び出されますが、長さは範囲外です。 実行時に IndexOutOfBoundsException が発生するでしょう。 RANGE: 配列オフセットは範囲外 (RANGE_ARRAY_OFFSET)メソッドは、配列パラメータとオフセットパラメータで呼び出されますが、オフセットは範囲外です。 実行時に IndexOutOfBoundsException が発生するでしょう。 RANGE: 文字列インデックスは範囲外 (RANGE_STRING_INDEX)文字列メソッドが呼び出されます。指定された文字列インデックスは範囲外です。 実行時に StringIndexOutOfBoundsException が発生するでしょう。 RC: 疑わしい参照比較 (RC_REF_COMPARISON)
このメソッドは、 == または != 演算子を使用して2つの参照値を比較しています。
一般的にこの型のインスタンスを比較する正しい方法は RCN: 既に利用していた値の null チェック (RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE)ここで値が null なのかチェックしていますが、既に値を利用していたので null である可能性はありません。 値が null なら以前の利用で NullPointerException が発生していたでしょう。 基本的に、値が null であることを許すのかどうかに関係なく、このコードと以前の値の利用は一致しません。 チェックは冗長か、または以前の値の利用は誤りです。 RE: 正規表現のための無効な構文 (RE_BAD_SYNTAX_FOR_REGULAR_EXPRESSION)このコードは、正規表現の構文によると無効である正規表現を使用しています。 この文が実行されるとき PatternSyntaxException をスローします。 RE: 正規表現のために使われている File.separator (RE_CANT_USE_FILE_SEPARATOR_AS_REGULAR_EXPRESSION)
このコードは、正規表現が必要な場所で、 RE: 正規表現のために使われている "." または "|" (RE_POSSIBLE_UNINTENDED_PATTERN)String 機能が呼び出されていて、"." または "|" が引数として正規表現を取るパラメータに渡されています。 これは意図したことですか? たとえば
RV: 0から1の乱数値は整数値0に丸められる (RV_01_TO_INT)
0から1の乱数値は整数値0に丸められます。
おそらく整数に丸められる前に何か他のことによって乱数値を倍数にしたかったか、または RV: 符号付き32ビットハッシュコードの絶対値を計算する間違った試み (RV_ABSOLUTE_VALUE_OF_HASHCODE)
このコードは、ハッシュコードを生成して絶対値を計算しています。
ハッシュコードが
文字列の2^32個に1個は RV: 符号付き整数の乱数の絶対値を計算する間違った試み (RV_ABSOLUTE_VALUE_OF_RANDOM_INT)
このコードは、符号付き整数の乱数を生成して絶対値を計算しています。
乱数ジェネレータで返される数が RV: compareTo によって返された特定の値のコードチェック (RV_CHECK_COMPARETO_FOR_SPECIFIC_RETURN_VALUE)このコードは、compareTo または compare メソッドを呼び出して、戻り値が特定の値(たとえば1または-1) なのか確かめています。 これらのメソッドを呼び出すときは特定のゼロ以外の値ではなく、結果の符号だけをチェックするべきです。 多数または大部分の compareTo と比較メソッドは-1、0または1を返しますが、いくつかは他の値を返します。 RV: 作成した例外をスローするのではなく捨てている (RV_EXCEPTION_NOT_THROWN)
このコードは、例外 (またはエラー) オブジェクトを作成していますが、何もしていません。 if (x < 0) { new IllegalArgumentException("x must be nonnegative"); } おそらくプログラマの意図は、作成した例外をスローすることでした。 if (x < 0) { throw new IllegalArgumentException("x must be nonnegative"); } RV: 戻り値を無視しているメソッド (RV_RETURN_VALUE_IGNORED)
このメソッドの戻り値はチェックするべきです。
この警告の共通の原因は、オブジェクトが更新されると思って不変オブジェクトのメソッドを呼び出すことです。 String dateString = getHeaderField(name); dateString.trim();
プログラマは、 String dateString = getHeaderField(name); dateString = dateString.trim(); RpC: 条件テストの繰り返し (RpC_REPEATED_CONDITIONAL_TEST)
このコードには条件テストが2回、つまり、1つめの条件テストが正しいとき、2つめの条件テストが実行されます (たとえば、 SA: フィールドの自己代入 (SA_FIELD_SELF_ASSIGNMENT)
このメソッドにはフィールドの自己代入があります。 int x; public void foo() { x = x; } そのような代入は役に立たないので、論理エラーかタイプミスかもしれません。 SA: フィールドとそれ自身との自己比較 (SA_FIELD_SELF_COMPARISON)このメソッドは、フィールドをそれ自身と比較しています。 論理エラーかタイプミスかもしれません。正しいものを比較していることを確認してください。 SA: フィールドの無意味な自己演算 (たとえば、 x & x) (SA_FIELD_SELF_COMPUTATION)このメソッドは、フィールドと同じフィールドへの別の参照との無意味な計算を実行しています (たとえば、x & x または x - x)。 この計算の性質のため、演算は意味をなすとは思われないので、論理エラーかタイプミスかもしれません。 計算をチェックしてください。 SA: フィールドへの代入ではなくローカル変数への自己代入 (SA_LOCAL_SELF_ASSIGNMENT_INSTEAD_OF_FIELD)
このメソッドにはローカル変数の自己代入があり、ローカル変数とフィールドが同じ名前です。 int foo; public void setFoo(int foo) { foo = foo; } そのような代入は役に立ちません。そうではなく、フィールドに代入するつもりでしたか? SA: ローカル変数とそれ自身との自己比較 (SA_LOCAL_SELF_COMPARISON)このメソッドは、ローカル変数をそれ自身と比較しています。論理エラーかタイプミスかもしれません。 正しいものを比較していることを確認してください。 SA: 変数の無意味な自己演算 (たとえば、x & x) (SA_LOCAL_SELF_COMPUTATION)このメソッドは、ローカル変数と同じ変数への別の参照との無意味な計算を実行しています (たとえば、x & x または x - x)。 この計算の性質のため、演算は意味をなすとは思われないので、論理エラーかタイプミスかもしれません。 計算をダブルチェックしてください。 SF: switch 文のフォールスルーのために格納が無効になっている (SF_DEAD_STORE_DUE_TO_SWITCH_FALLTHROUGH)前の case で格納された値が switch 文のフォールスルーのためにここで上書きされています。 前の case の終わりに break または return を入れるのを忘れた可能性があります。 SF: スローする switch 文のフォールスルーのために格納が無効になっている (SF_DEAD_STORE_DUE_TO_SWITCH_FALLTHROUGH_TO_THROW)前の case で格納された値が例外がスローされる場所で、switch 文のフォールスルーのためにここで失われています。 前の case の終わりに break または return を入れるのを忘れた可能性があります。 SIC: 非 static 内部クラスとスレッドローカルのデッドロック (SIC_THREADLOCAL_DEADLY_EMBRACE)このクラスは内部クラスですが、おそらく static 内部クラスにすべきです。 実際には内部クラスと外部クラスのスレッドローカルとの間にデッドロックの深刻な危険性があります。 内部クラスが static でないので、外部クラスへの参照を保持します。 スレッドローカルに内部クラスのインスタンスの参照があるなら、内部と外部のインスタンスの両方が到達可能になり、ガベージされません。 SIO: instanceof 演算子を使用した不必要な型チェック (SIO_SUPERFLUOUS_INSTANCEOF)オブジェクトが要求する型であるかどうかにかかわらず、静的に判定される instanceof 演算子を使用して型チェックをしています。 SQL: インデックスが0で PreparedStatement にアクセスしようとしているメソッド (SQL_BAD_PREPARED_STATEMENT_ACCESS)
インデックスが0で、 SQL: インデックスが0で ResultSet にアクセスしようとしているメソッド (SQL_BAD_RESULTSET_ACCESS)
インデックスが0で、 STI: interrupted メソッドを呼び出すために不要な currentThread メソッドを呼び出している (STI_INTERRUPTED_ON_CURRENTTHREAD)
このメソッドは、 STI: スレッドインスタンスで static Thread.interrupted() を呼び出している (STI_INTERRUPTED_ON_UNKNOWNTHREAD)
このメソッドは、カレントスレッドでない Thread オブジェクトであるように見える Thread オブジェクトで Se: 直列化機構のために private にしなければならないメソッド (SE_METHOD_MUST_BE_PRIVATE)
このクラスは、 Se: readResolve メソッドが static メソッドとして宣言されている (SE_READ_RESOLVE_IS_STATIC)
TQ: 型修飾子でアノテーションされた値がその修飾子を付けてはならない値を必要とする場所で使われている (TQ_ALWAYS_VALUE_USED_WHERE_NEVER_REQUIRED)型修飾子でアノテートされた値がその修飾子を付けてはならない値を必要とする場所で使われています。 より正確に、when=ALWAYS を指定した型修飾子でアノテートされた値が到達することが保証されているか同じ型修飾子で when=NEVER を指定する場所で使用しています。 たとえば、@NonNegative は型修飾子アノテーション @Negative(when=When.NEVER) の略称とします。 以下のコードは、return 文が @NonNegative 値を要求するが @Negative としてマークされている値を受け取るのでこの警告を生成します。 public @NonNegative Integer example(@Negative Integer value) { return value; } TQ: 互換性のない型修飾子による比較値 (TQ_COMPARING_VALUES_WITH_INCOMPATIBLE_TYPE_QUALIFIERS)型修飾子アノテーションを指定した値がその修飾子のない値と比較しています。 より正確に、when=ALWAYS を指定した型修飾子でアノテートされた値が同じ型修飾子で when=NEVER を指定する値と比較しています。 たとえば、@NonNegative は型修飾子アノテーション @Negative(when=When.NEVER) の略称とします。 以下のコードは、return 文が @NonNegative 値を要求するが、@Negative としてマークされている値を受け取るのでこの警告を生成します。 public boolean example(@Negative Integer value1, @NonNegative Integer value2) { return value1.equals(value2); } TQ: 型修飾子を付けていないかもしれない値がその型修飾子を必要とする方法で常に使われている (TQ_MAYBE_SOURCE_VALUE_REACHES_ALWAYS_SINK)型修飾子によって示された値のインスタンスではない可能性としてアノテートされた値です。 値は、その型修飾子によって示された値を必要とする方法で使われることが保証されています。 TQ: 型修飾子を付けているかもしれない値がその型修飾子を禁止する方法で常に使われている (TQ_MAYBE_SOURCE_VALUE_REACHES_NEVER_SINK)型修飾子によって示された値のインスタンスである可能性としてアノテートされた値です。 値は、その型修飾子によって示された値を禁止する方法で使われることが保証されています。 TQ: 型修飾子でアノテートされていない値がその修飾子が付けられた値を必要とする場所で使われている (TQ_NEVER_VALUE_USED_WHERE_ALWAYS_REQUIRED)型修飾子でアノテートされていない値がその修飾子が付けられた値を必要とする場所で使われています。 より正確に、when=NEVER を指定した型修飾子でアノテートされた値が同じ型修飾子で when=ALWAYS を指定する場所で使用しています。 TQ: 型修飾子がない値が修飾子を必要とする場所で使われている (TQ_UNKNOWN_VALUE_USED_WHERE_ALWAYS_STRICTLY_REQUIRED)値が型修飾子アノテーションを必要とする方法で使われています。型修飾子は厳密なので、ツールは適切なアノテーションを指定していない値を拒絶します。 厳密なアノテーションを指定しているので値を型変換します。戻り値が厳密なアノテーションでアノテートされる同一性機能を定義してください。 これは厳密な型修飾子アノテーションで非アノテート値を値に変える唯一の方法です。 UMAC: 呼び出し不可能なメソッドが無名クラスで定義されている (UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS)この無名クラスは、直接呼び出されないスーパークラスのメソッドをオーバーライドしていないメソッドを定義しています。 他のクラスのメソッドが無名クラスで宣言されたメソッドを直接呼び出せないので、このメソッドは呼び出し不可能だと思われます。 メソッドは単にデッドコードであるかもしれません。しかし、メソッドがスーパークラスで宣言されるメソッドをオーバーライドすることを意図した可能性もあります。 そして、タイプミスまたは他の誤りのためにメソッドは、実際には意図しているメソッドをオーバーライドしません。 UR: コンストラクタで初期化されていないフィールドを読み出している (UR_UNINIT_READ)このコンストラクタは、まだ値が代入されていないフィールドを読み出しています。 多くの場合、プログラマがコンストラクタのパラメータの代わりに誤ってフィールドを使うときに起きます。 UR: スーパークラスのコンストラクタから呼び出されるメソッドで初期化されていないフィールドを読み出している (UR_UNINIT_READ_CALLED_FROM_SUPER_CONSTRUCTOR)このメソッドは、スーパークラスのコンストラクタで呼びされています。この時点では、クラスのフィールドはまだ初期化されていません。 これはたくさんの具象クラスを作るためです。以下のクラスを検討してください。 abstract class A { int hashCode; abstract Object getValue(); A() { hashCode = getValue().hashCode(); } } class B extends A { Object value; B(Object v) { this.value = v; } Object getValue() { return value; } }
USELESS_STRING: 名前のない配列で toString メソッドを呼び出している (DMI_INVOKING_TOSTRING_ON_ANONYMOUS_ARRAY)
このコードは、無名の配列で USELESS_STRING: 配列で toString メソッドを呼び出している (DMI_INVOKING_TOSTRING_ON_ARRAY)
このコードは、配列で USELESS_STRING: 書式文字列を使用して役に立たない方法で配列をフォーマットしている (VA_FORMAT_STRING_BAD_CONVERSION_FROM_ARRAY)
書式文字列でフォーマットされている引数の1つは配列です。
[I@304282 のように配列のコンテンツを表示しないかなり役に立たない書式を使用してフォーマットされます。
フォーマットで扱う前に UwF: null に設定されるだけのフィールド (UWF_NULL_FIELD)このフィールドに定数値 null を書き込みます。したがって、フィールドの読み出しは null を返します。 誤りをチェックしてください。役に立たないなら除去してください。 UwF: 書き込まれていないフィールド (UWF_UNWRITTEN_FIELD)このフィールドは決して書き込まれません。このフィールドからの読み出しはデフォルト値を返します。 誤りをチェックしてください (フィールドは初期化するべきでしたか?)。役に立たないなら除去してください。 VA: 可変長引数を期待しているメソッドにプリミティブ型の配列を渡している (VA_PRIMITIVE_ARRAY_PASSED_TO_OBJECT_VARARG)このコードは可変長引数をとるメソッドにプリミティブ型の配列を渡しています。 これはプリミティブ型の配列を保持するために長さが1の配列を作成してメソッドに渡します。 LG: ロガーの変更は OpenJDK の弱参照が原因で潜在的に失われる (LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE)
OpenJDK は、潜在的非互換性を取り入れました。特に、 public static void initLogging() throws Exception { Logger logger = Logger.getLogger("edu.umd.cs"); logger.addHandler(new FileHandler()); // ロガーの構成の変更 logger.setUseParentHandlers(false); // 別のロガーの構成の変更 }
ロガーの参照は、メソッドの終わり (メソッドは脱出しません) で失われるので、
public static void main(String[] args) throws Exception { initLogging(); // ファイルハンドラーをロガーに追加する System.gc(); // ロガーの構成が失われる Logger.getLogger("edu.umd.cs").info("Some message"); // 期待したようにファイルに記録されません } Ulf Ochsenfahrt と Eric Fellheimer OBL: ストリームやリソースのクリーンアップに失敗するかもしれないメソッド (OBL_UNSATISFIED_OBLIGATION)このメソッドは、ストリーム、データベースオブジェクト、またはクリーンアップ操作を明示的に必要としている他のリソースのクリーンアップ (クローズする、片付ける) に失敗するかもしれません。 一般的にメソッドがストリープや他のリソースを開いたなら、メソッドはストリームやリソースがメソッドが戻る前にクリーンアップされることを確認するために try/finally ブロックを使用するべきです。 このバグパターンは、OS_OPEN_STREAM と ODR_OPEN_DATABASE_RESOURCE と基本的に同じですが異なる (そして、うまくいけばより良い) 静的解析技術に基づいています。 私たちは、このバグパターンの有効性についてのフィードバックを得ることに関心があります。 どちらかの方法でフィードバックを送ってください。
特に、このバグパターンの誤検出抑制探索法は詳細にわたって調整されていないので、誤検出についてのレポートは我々の助けになります。 解析技術の説明は、Weimer と Necula による Finding and Preventing Run-Time Error Handling Mistakes を参照してください。 OBL: チェック例外でストリームやリソースのクリーンアップに失敗するかもしれないメソッド (OBL_UNSATISFIED_OBLIGATION_EXCEPTION_EDGE)このメソッドは、ストリーム、データベースオブジェクト、またはクリーンアップ操作を明示的必要としている他のリソースのクリーンアップ (クローズする、片付ける) に失敗するかもしれません。 一般的にメソッドがストリープや他のリソースを開いたなら、メソッドはストリームやリソースがメソッドが戻る前にクリーンアップされることを確認するために try/finally ブロックを使用するべきです。 このバグパターンは、OS_OPEN_STREAM と ODR_OPEN_DATABASE_RESOURCE と基本的に同じですが異なる (そして、うまくいけばより良い) 静的解析技術に基づいています。 私たちは、このバグパターンの有効性についてのフィードバックを得ることに関心があります。 どちらかの方法でフィードバックを送ってください。
特に、このバグパターンの誤検出抑制探索法は詳細にわたって調整されていないので、誤検出についてのレポートは我々の助けになります。 解析技術の説明は、Weimer と Necula による Finding and Preventing Run-Time Error Handling Mistakes を参照してください。 Dm: 呼び出したメソッドの Locale パラメータの使用を検討する (DM_CONVERT_CASE)文字列がプラットホームのデフォルトエンコーディングを使用して大文字、小文字に変換されています。 国際文字で使われると不適切な変換になることがあります。
Dm: デフォルトエンコーディングへの依存 (DM_DEFAULT_ENCODING)byte から String (または String から byte) への変換で、デフォルトプラットホームエンコーディングが適切だと仮定するメソッドの呼び出しを発見しました。 これはアプリケーションの振る舞いがプラットホーム間で異なる原因となります。代替 API を使用して、文字セット名または Charset オブジェクトを明示的に指定して下さい。 DP: doPrivileged ブロック内で作成されるべきクラスローダ (DP_CREATE_CLASSLOADER_INSIDE_DO_PRIVILEGED)このコードはクラスローダを作成していますが、セキュリティ管理がインストールされるなら許可が必要です。 このコードがセキュリティ許可がないコードによって呼び出されるなら、クラスローダの作成は doPrivileged ブロックの中で行う必要があります。 DP: doPrivileged ブロック内で呼び出すべきメソッド (DP_DO_INSIDE_DO_PRIVILEGED)このコードは、セキュリティ許可チェックが必要なメソッドを呼び出しています。 このコードにセキュリティ許可が与えられるとしても、セキュリティ許可を持たないコードによって呼び出されるなら doPrivileged ブロックの中で呼び出す必要があります。 EI: 可変オブジェクトへの参照を返すことによって内部表現を暴露するかもしれないメソッド (EI_EXPOSE_REP)オブジェクトのフィールドに格納された可変オブジェクトの参照を返すと、オブジェクトの内部表現を暴露します。 インスタンスが信頼できないコードによってアクセスされるなら、可変オブジェクトのチェックされていない変更がセキュリティや他の重要なプロパティを危うくするでしょう。 何か違うことをする必要があります。オブジェクトの新しいコピーを返すことは、多くの状況でより良いアプローチです。 EI2: 可変オブジェクトへの参照を取り込むことによって内部表現を暴露するかもしれないメソッド (EI_EXPOSE_REP2)このコードは、オブジェクトの内部表現に外部の可変オブジェクトの参照を格納しています。 インスタンスが信頼できないコードによってアクセスされるなら、可変オブジェクトのチェックされていない変更がセキュリティや他の重要なプロパティを危うくするでしょう。 何か違うことをする必要があります。オブジェクトの新しいコピーを返すことは、多くの状況でより良いアプローチです。 FI: ファイナライザは public ではなく protected にすべき (FI_PUBLIC_SHOULD_BE_PROTECTED)
このクラスの MS: static フィールドに可変オブジェクトを格納することによって、内部の静的状態を暴露するかもしれないメソッド (EI_EXPOSE_STATIC_REP2)このコードは、static フィールドに外部の可変オブジェクトを格納しています。 可変オブジェクトのチェックされていない変更がセキュリティや他の重要なプロパティを危うくするでしょう。 何か違うことをする必要があります。オブジェクトのコピーを保存することは、多くの状況でより良いアプローチです。 MS: final でないフィールドは悪意のあるコードから保護できない (MS_CANNOT_BE_FINAL)この可変 static フィールドは悪意のあるコードや偶然別のパッケージによって変更できます。 残念ながらこのような使い方は簡単に解決できません。 MS: 配列を返すことによって内部表現を暴露するかもしれない public static メソッド (MS_EXPOSE_REP)public static メソッドは、クラスの 静的な状態の一部である配列の参照を返します。 このメソッドを呼び出すどんなコードも、基底配列を自由に変更できます。 解決策は、配列のコピーを返すことです。 MS: final かつパッケージプロテクテッドにすべきフィールド (MS_FINAL_PKGPROTECT)この可変 static フィールドは悪意のあるコードや偶然別のパッケージによって変更できます。 フィールドは、脆弱性を回避するために final および/またはパッケージプロテクテッドにします。 MS: 可変配列のフィールド (MS_MUTABLE_ARRAY)この final static フィールドは配列を参照しているので、悪意のあるコードや偶然別のパッケージによってアクセスできます。 このコードは、配列のコンテンツを自由に変更できます。 MS: 可変コレクションのフィールド (MS_MUTABLE_COLLECTION)可変コレクションのインスタンスが final static フィールドに割り当てられています。 したがって、 悪意のあるコードや偶然別のパッケージによって変更できます。 脆弱性を避けるために Collections.unmodifiableSet/List/Map などでこのフィールドをラップすることを検討してください。 MS: パッケージプロテクテッドにすべき可変コレクションのフィールド (MS_MUTABLE_COLLECTION_PKGPROTECT)可変コレクションのインスタンスが final static フィールドに割り当てられています。 したがって、悪意のあるコードや偶然別のパッケージによって変更できます。 フィールドは脆弱性を避けるためにパッケージプロテクテッドにできます。 代わりに Collections.unmodifiableSet/List/Map などでこのフィールドをラップしても脆弱性を避けることができます。 MS: 可変 Hashtable のフィールド (MS_MUTABLE_HASHTABLE)この final static フィールドは Hashtable を参照しているので、悪意のあるコードや偶然別のパッケージによってアクセスできます。 このコードは、Hashtable のコンテンツを自由に変更できます。 MS: インタフェースから移動してパッケージプロテクテッドにすべきフィールド (MS_OOI_PKGPROTECT)インタフェースに定義された final static フィールドが配列や Hashtable などの可変オブジェクトを参照しています。 この可変オブジェクトは悪意のあるコードや偶然別のパッケージによって変更できます。 これを解決するためにフィールドはクラスへ移動する必要があり、脆弱性を回避するためにパッケージプロテクテッドにします。 MS: パッケージプロテクテッドにすべきフィールド (MS_PKGPROTECT)この可変 static フィールドは悪意のあるコードや偶然別のパッケージによって変更できます。 フィールドは、脆弱性を回避するためにパッケージプロテクテッドにします。 MS: final にすべきフィールド (MS_SHOULD_BE_FINAL)final でない public static フィールドは悪意のあるコードや偶然別のパッケージによって変更できます。 フィールドは、脆弱性を回避するために final にします。 MS: final でないフィールドはリファクタリングするべき (MS_SHOULD_BE_REFACTORED_TO_BE_FINAL)final でない public static フィールドは悪意のあるコードや偶然別のパッケージによって変更できます。 フィールドは、脆弱性を回避するために final にします。 しかしながら、スタティックイニシャライザには複数のフィールドへの書き込みがあるので、何らかのリファクタリングを必要とするでしょう。 AT: 並行抽象の呼び出しシーケンスはアトミックではないかもしれない (AT_OPERATION_SEQUENCE_ON_CONCURRENT_ABSTRACTION)このコードには並行抽象化 (たとえば、並行ハッシュマップ) の呼び出しシーケンスがあります。 これらの呼び出しは原子的に実行されません。 DC: フィールドのダブルチェックの可能性 (DC_DOUBLECHECK)
このメソッドにはダブルチェックロッキングのインスタンスがあるかもしれません。このイディオムは、Java のメモリモデルでは正しくありません。 DC: 部分的に初期化されたオブジェクトを暴露する可能性がある (DC_PARTIALLY_CONSTRUCTED)ダブルチェックロッキングと共に遅延初期化フィールドを使用するメソッドのようです。 フィールドが正しく volatile として宣言される間にオブジェクトの内部構造がフィールドに割り当てられた後で変更される可能性があります。 したがって、他のスレッドが部分的に初期化されたオブジェクトを見るかもしれません。 この問題を直すために、最初にローカル変数をオブジェクトに格納して、完全に構築した後で volatile フィールドを保存することを考えてください。 DL: Boolean の同期化 (DL_SYNCHRONIZATION_ON_BOOLEAN)
private static Boolean inited = Boolean.FALSE; synchronized(inited) { if (!inited) { init(); inited = Boolean.TRUE; } }
一般には2つの DL: デッドロックの原因になる可能性があるボクシングされたプリミティブ型の同期化 (DL_SYNCHRONIZATION_ON_BOXED_PRIMITIVE)このコードは、Integer のようなボクシングされたプリミティブ型の定数で同期化しています。 private static Integer count = 0; synchronized(count) { count++; }
CERT の CON08-J. Do not synchronize on objects that may be reused を参照してください。 DL: 正準化した文字列の同期化 (DL_SYNCHRONIZATION_ON_SHARED_CONSTANT)このコードは、正準化した文字列で同期化しています。 private static String LOCK = "LOCK"; synchronized(LOCK) { ... }
文字列定数は正準化され、Java 仮想マシンによってロードされたすべてのクラス全体で共有されます。
したがって、これは他のコードがロックしているかもしれない何かをロックしている可能性があります。
これはブロッキングとデッドロックの振る舞いの診断を難しくして、とても奇妙な結果になる可能性があります。 DL: ボクシングされたプリミティブ値の同期化 (DL_SYNCHRONIZATION_ON_UNSHARED_BOXED_PRIMITIVE)
このコードは、明らかに共有されていない private static final Integer fileLock = new Integer(1); synchronized(fileLock) { .. do something .. } このコードは、 fileLock を以下のように宣言するとより良くなります。 private static final Object fileLock = new Object();
既存のコードとしては間違っていないかもしれないが、紛らわしいので将来リファクタリングするべきかもしれません。
たとえば、IntelliJ の "Remove Boxing" のようなリファクタリングは Java 仮想マシンを通して共有される正準化された Dm: Condition で wait メソッドを呼び出している (DM_MONITOR_WAIT_ON_CONDITION)
このメソッドは、 Dm: デフォルトの空の run メソッドを使用して作成されたスレッド (DM_USELESS_THREAD)
このメソッドは、 ESync: 空の synchronized ブロック (ESync_EMPTY_SYNC)このコードには空の synchronized ブロックがあります。 synchronized() { } 空の synchronized ブロックは巧妙で正しく使用するのは困難です。 空の synchronized ブロックはわざとらしくて決して良い解決策ではありません。 IS: 一貫性のない同期化 (IS2_INCONSISTENT_SYNC)このクラスのフィールドは、同期化に関して一貫性なくアクセスされるように見えます。 このバグレポートは、バグパターンディテクタが以下のように判断したことを示します。
ディテクタがどこでフィールドが同期化なしでアクセスされると信じていたかを示すコードの場所に「非同期アクセス」というラベルがついているノードを選択できます。 不正確ないろいろな原因がこのディテクタにあることに注意してください。 たとえば、ディテクタはロックを保持されるすべての状況を静的に検出できるわけではありません。 また、ディテクタがロックされたアクセスとアンロックされたアクセスの区別が正確なときでも、問題のコードは依然として正しいかもしれません。 IS: 並行アクセスに対してガードされていないフィールド (IS_FIELD_NOT_GUARDED)このフィールドは、net.jcip.annotations.GuardedBy または javax.annotation.concurrent.GuardedBy でアノテートされていますが、アノテーションに違反すると思われる方法でアクセスできます。 JLM: Lock で同期化している (JLM_JSR166_LOCK_MONITORENTER)
このメソッドは、 JLM: java.util.concurrent のインスタンスで同期化している (JLM_JSR166_UTILCONCURRENT_MONITORENTER)
このメソッドは、java.util.concurrent パッケージのクラス (またはサブクラス) のインスタンスで同期化しています。
これらのクラスのインスタンスは、 そのようなコードは正しいかもしれないが、将来コードを維持しなければならない人々を混乱させるかもしれないので慎重にレビューし文書化するべきです、 JLM: util.concurrent 抽象でモニタスタイルの wait メソッドを使用している (JML_JSR166_CALLING_WAIT_RATHER_THAN_AWAIT)
このメソッドは、 LI: static フィールドの間違った遅延初期化 (LI_LAZY_INIT_STATIC)
このメソッドにはvolatile でない static フィールドの非同期な遅延初期化があります。
コンパイラやプロセッサが命令を並べ替えるかもしれないので、メソッドが複数のスレッドによって呼び出されるなら、
スレッドは完全に初期化されたオブジェクトを見るとは保証されていません。
フィールドにアクセスした際に、中途半端に初期化されたインスタンスが見えてしまう危険があります。
この問題を修正するためにフィールドを volatile にできます。 LI: 更新される static フィールドの間違った遅延初期化 (LI_LAZY_INIT_UPDATE_STATIC)このメソッドにはstatic フィールドの非同期な遅延初期化があります。 フィールドが設定された後で、その場所に格納されるオブジェクトはさらに更新されるかアクセスされます。 それが設定されるとすぐに、フィールドを設定することは他のスレッドに見えます。 フィールドを設定するさらなるアクセスがオブジェクトを初期化するのに役に立つなら、 それが完全に初期化されるまでどんな他のスレッドも格納されたオブジェクトにアクセスするのを防がないかぎり、非常に深刻なマルチスレッドバグがあります。 たとえメソッドが複数のスレッドによって決して呼び出されないと確信していても、 それは、フィールドに設定している値が完全にデータを読み込まれるか初期化されるまで、 static フィールドを設定しないほうが良いかもしれません。 ML: フィールドを同期化でガードしようとする無駄な試み (ML_SYNC_ON_FIELD_TO_GUARD_CHANGING_THAT_FIELD)
このメソッドは、フィールドの同時更新に対して同期化でガードしようとしています。しかし、フィールドをガードするとフィールドではなく、フィールドが参照するオブジェクトのロックを獲得します。
これはあなたが必要とする相互排除ができないかもしれません。
他のスレッドは (他の目的のための) 参照されたオブジェクトのロックを獲得するかもしれません。 private Long myNtfSeqNbrCounter = new Long(0); private Long getNotificationSequenceNumber() { Long result = null; synchronized(myNtfSeqNbrCounter) { result = new Long(myNtfSeqNbrCounter.longValue() + 1); myNtfSeqNbrCounter = new Long(result.longValue()); } return result; } ML: 更新されるフィールドで同期化しているメソッド (ML_SYNC_ON_UPDATED_FIELD)このメソッドは、可変フィールドから参照されたオブジェクトで同期化しています。 異なるスレッドが異なるオブジェクトで同期化しているかもしれないので、有用な意味を持っている可能性が低いです。 MSF: 可変サーブレットフィールド (MSF_MUTABLE_SERVLET_FIELD)Web サーバは、一般的にサーブレットや JSP クラスのインスタンスを1つだけ作成します (すなわち、シングルトンとして扱います)。 複数のスレッドが複数同時のリクエストに応えるためにそのインスタンスでメソッドを呼び出します。 したがって、一般に可変インスタンスフィールドは競合状態を作ります。 MWN: 不整合な notify メソッド (MWN_MISMATCHED_NOTIFY)
このメソッドは、オブジェクトで明らかにロックを保持することなく MWN: 不整合な wait メソッド (MWN_MISMATCHED_WAIT)
このメソッドは、オブジェクトで明らかにロックを保持することなく、 NN: 裸の notify メソッド (NN_NAKED_NOTIFY)
可変オブジェクトの状態変更が通知があるメソッドを呼び出したメソッドで起こったかもしれないので、このバグが必ずしもエラーを示すというわけではありません。 NP: 同じフィールドでの同期化と null チェック (NP_SYNC_AND_NULL_CHECK_FIELD)フィールドは同期化しているので、おそらく null ではないと思われます。 null のフィールドを同期化すると NullPointerException がスローされるので、null チェックは無意味になります。 別のフィールドで同期化したほうがよいです。 No: notifyAll メソッドではなく notify メソッドを使用している (NO_NOTIFY_NOT_NOTIFYALL)
このメソッドは、 RS: readObject メソッドを同期化しているクラス (RS_READOBJECT_SYNC)
この直列化可能クラスは同期化する RV: putIfAbsent の戻り値は無視されて putIfAbsent に渡した値は再利用された (RV_RETURN_VALUE_OF_PUTIFABSENT_IGNORED)
Ru: スレッドで run メソッドを呼び出している (RU_INVOKE_RUN)
このメソッドは、スレッドで 明示的に SC: Thread.start() を呼び出しているコンストラクタ (SC_START_IN_CTOR)コンストラクタがスレッドを開始しています。クラスが拡張され、サブクラスが作られるなら間違っていそうです。 なぜなら、サブクラスのコンストラクタでスレッドが開始される前にスーパークラスのスレッドが開始されてしまうためです。 SP: スピンロックをしているメソッド (SP_SPIN_ON_FIELD)このメソッドは、フィールドを読み出すループで回り続けます。 コンパイラがフィールドの読み出しをループの外に出すかもしれません。コードを無限ループに変えます。 正しい同期化 (wait/notify を呼び出すように含む) を使うようにクラスを変更するべきです。 STCAL: static Calendar の呼び出し (STCAL_INVOKE_ON_STATIC_CALENDAR_INSTANCE)たとえ JavaDoc にそれに関する手がかりがないとしても、Calendar はマルチスレッドでの使用は本質的に安全ではありません。 ディテクタは、static フィールドから得られた Calendar のインスタンスの呼び出しを発見しました。 これは疑わしく見えます。 詳細については、Sun Bug #6231579 や Sun Bug #6178997 を参照してください。 STCAL: static DateFormat の呼び出し (STCAL_INVOKE_ON_STATIC_DATE_FORMAT_INSTANCE)JavaDoc に書かれているように DateFormat はマルチスレッドでの使用は本質的に安全ではありません。 ディテクタは、static フィールドから得られた DateFormat のインスタンスの呼び出しを発見しました。 これは疑わしく見えます。 詳細については、Sun Bug #6231579 や Sun Bug #6178997 を参照してください。 STCAL: static Calendar フィールド (STCAL_STATIC_CALENDAR_INSTANCE)
たとえ JavaDoc にそれに関する手がかりがないとしても、Calendar はマルチスレッドでの使用は本質的に安全でありません。
正しい同期化をしないでスレッド境界の向こうで1つのインスタンスを共有することは、アプリケーションの誤動作になります。
JDK 5.0に比べて JDK 1.4 のほうが問題が表面化するように思われ、おそらく sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate() の ArrayIndexOutOfBoundsExceptions や IndexOutOfBoundsExceptions がランダムに発生します。
直列化問題も経験するかもしれません。インスタンスフィールドを使用することを推奨します。 STCAL: static DateFormat (STCAL_STATIC_SIMPLE_DATE_FORMAT_INSTANCE)
JavaDoc に書かれているように DateFormat はマルチスレッドでの使用は本質的に安全ではありません。
正しい同期化をしないでスレッド境界の向こうで1つのインスタンスを共有することは、アプリケーションの誤動作になります。
JDK 5.0に比べて JDK 1.4 のほうが問題が表面化するように思われ、おそらく sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate() の ArrayIndexOutOfBoundsExceptions や IndexOutOfBoundsExceptions がランダムに発生します。
直列化問題も経験するかもしれません。インスタンスフィールドを使用することを推奨します。 SWL: ロックを保持して Thread.sleep() を呼び出しているメソッド (SWL_SLEEP_WITH_LOCK_HELD)
このメソッドは、ロックを保持して、 TLW: 2つ以上のロックを保持して wait メソッドを呼び出している (TLW_TWO_LOCK_WAIT)
2つ以上のロックを保持して、モニタで待機させるとデッドロックを引き起こすことがあります。
UG: 同期化していない get メソッド、同期化している set メソッド (UG_SYNC_SET_UNSYNC_GET)このクラスには類似した名前の get メソッドと set メソッドがあり、set メソッドは同期化していて、get メソッドは同期化していません。 get メソッドの呼び出し元がオブジェクトの一貫した状態を必ずしも見るというわけではないので、実行時に間違った振る舞いの原因になることがあります。 get メソッドは同期化するべきです。 UL: すべての経路でロックが解除されないメソッド (UL_UNRELEASED_LOCK)
このメソッドは、JSR-166( Lock l = ...; l.lock(); try { // do something } finally { l.unlock(); } UL: すべての例外経路でロックが解除されないメソッド (UL_UNRELEASED_LOCK_EXCEPTION_PATH)
このメソッドは、JSR-166( Lock l = ...; l.lock(); try { // do something } finally { l.unlock(); } UW: wait メソッドの無条件呼び出し (UW_UNCOND_WAIT)
このメソッドには条件制御フローによってガードされない VO: volatile フィールドへのインクリメントはアトミックではない (VO_VOLATILE_INCREMENT)このコードは、volatile フィールドをインクリメントしています。 volatile フィールドのインクリメントはアトミックではありません。 複数のスレッドが同時にフィールドをインクリメントすると、インクリメントが失われる可能性があります。 VO: 配列への volatile 参照は、配列要素を volatile として扱わない (VO_VOLATILE_REFERENCE_TO_ARRAY)配列に volatile 参照を宣言していますが、あなたが望むものではないかもしれません。 配列への volatile 参照は、配列への参照の読み出し、書き込みは volatile として扱われますが、配列要素は volatile として扱われません。 配列要素を volatile として扱いたいのであれば、J2SE 5.0で提供された java.util.concurrent パッケージのアトミック配列クラスを使用する必要があります。 WL: クラスリテラルではなく getClass で同期化している (WL_USING_GETCLASS_RATHER_THAN_CLASS_LITERAL)
このインスタンスメソッドは、 private static final String base = "label"; private static int nameCounter = 0; String constructComponentName() { synchronized (getClass()) { return base + nameCounter++; } }
private static final String base = "label"; private static int nameCounter = 0; String constructComponentName() { synchronized (Label.class) { return base + nameCounter++; } } Jason Mehrens によって寄贈されたバグパターン WS: writeObject メソッドは同期化しているがその他のメソッドは同期化していないクラス (WS_WRITEOBJECT_SYNC)
このクラスには同期化している Wa: Condition.await() がループの中にない (WA_AWAIT_NOT_IN_LOOP)
このメソッドは、ループの中にない Wa: wait メソッドがループの中にない (WA_NOT_IN_LOOP)
このメソッドは、ループの中にない Bx: プリミティブ値がボクシングされて、すぐにアンボクシングされる (BX_BOXING_IMMEDIATELY_UNBOXED)プリミティブ値がボクシングされて、すぐにアンボクシングされます。 おそらくアンボクシングされた値が必要な場所で手動でボクシングをしているためです。 その結果、コンパイラにボクシングの機能を取り消すことを強制しています。 Bx: プリミティブ値がプリミティブ型の型変換をするためにボクシングされて、アンボクシングされる (BX_BOXING_IMMEDIATELY_UNBOXED_TO_PERFORM_COERCION)
プリミティブ値がコンストラクタでボクシングされて、すぐに異なるプリミティブ型に変換されます (たとえば Bx: プリミティブ値が3項演算子のためにアンボクシングされて、型変換される (BX_UNBOXED_AND_COERCED_FOR_TERNARY_OPERATOR)
ラップされたプリミティブ値は、3項演算子 ( Bx: ボクシングされた値がアンボクシングされて、すぐに再ボクシングされる (BX_UNBOXING_IMMEDIATELY_REBOXED)ボクシングされた値がアンボクシングされて、すぐに再ボクシングされます。 Bx: プリミティブが比較でボクシングされている (DM_BOXED_PRIMITIVE_FOR_COMPARE)ボクシングされたプリミティブが単に compareTo メソッドを呼び出すために作られています。 直接プリミティブで働く static compare メソッド (double と float は Java 1.4から、他のプリミティブ型は Java 1.7から) を使うほうがより効率的です。 Bx: ボクシング/アンボクシングはプリミティブを解析する (DM_BOXED_PRIMITIVE_FOR_PARSING)ボックス化されたプリミティブは、String から生成されていて、アンボックス化されたプリミティブ値を抽出します。 static parseXXX メソッドを呼び出す方が効率的です。 Bx: toString メソッドを呼び出すためにプリミティブ型のラッパクラスのインスタンスを作成している (DM_BOXED_PRIMITIVE_TOSTRING)
Bx: 効率が悪い浮動小数点 Number コンストラクタを呼び出しているメソッド (DM_FP_NUMBER_CTOR)
クラスが J2SE 5.0より前の Java 仮想マシンとの互換性が不要なら、オートボクシングか Bx: 効率が悪い Number コンストラクタを呼び出しているメソッド (DM_NUMBER_CTOR)
-128から127までの値は対応するキャッシュされたインスタンスを持つことが保証されています。
そして、
クラスが J2SE 5.0より前の Java 仮想マシンとの互換性が不要なら、 Dm: URL の equals メソッドと hashCode メソッドはブロックする (DMI_BLOCKING_METHODS_ON_URL)
URL の Dm: URL の Map や Set はひどい性能になる (DMI_COLLECTION_OF_URLS)
このメソッドまたはフィールドは、URL の Dm: 効率が悪い Boolean コンストラクタを呼び出しているメソッド (DM_BOOLEAN_CTOR)
Dm: 明示的なガベージコレクション (DM_GC)明示的にガベージコレクションを呼び出しています。ベンチマークの特定の用途を除いて非常に疑わしいです。
過去に、 Dm: クラスオブジェクトを得るためだけにインスタンスを作成しているメソッド (DM_NEW_FOR_GETCLASS)
メソッドは、クラスオブジェクトを得るためにインスタンスを生成して Dm: 整数の乱数を生成するためには nextDouble メソッド ではなく nextInt メソッドを使用する (DM_NEXTINT_VIA_NEXTDOUBLE)
Dm: 効率が悪い new String(String) コンストラクタを呼び出しているメソッド (DM_STRING_CTOR)
Dm: String の toString メソッドを呼び出しているメソッド (DM_STRING_TOSTRING)
Dm: 効率が悪い new String() コンストラクタを呼び出しているメソッド (DM_STRING_VOID_CTOR)
引数がないコンストラクタを使用して、新しい HSC: 複数のクラスファイルにわたって複製されている巨大な文字列定数 (HSC_HUGE_SHARED_STRING_CONSTANT)巨大な文字列定数が複数のクラスファイルにわたって複製されています。 final フィールドが文字列定数で初期化され、Java 言語によって他のクラスからの final フィールドへのすべての参照がクラスファイルにインライン化されるからです。
JDK はこのバグを解決してサイズを1MB減らすことができました。 SBSC: ループの中で + を使用して文字列を連結しているメソッド (SBSC_USE_STRINGBUFFER_CONCATENATION)
このメソッドは、ループの中で + を使用して
たとえば、 // This is bad String s = ""; for (int i = 0; i < field.length; ++i) { s = s + field[i]; } // This is better StringBuffer buf = new StringBuffer(); for (int i = 0; i < field.length; ++i) { buf.append(field[i]); } String s = buf.toString(); SIC: static 内部クラスにすべき (SIC_INNER_SHOULD_BE_STATIC)このクラスは内部クラスなのにそれを作成したオブジェクトへの埋め込まれた参照を使用していません。 この参照はより大きなクラスのインスタンスを作成して、必要以上に作成オブジェクトへの参照を存続しておくことがあります。 できれば、クラスは static にすべきです。 SIC: 名前付き static 内部クラスにリファクタリングできるかもしれない (SIC_INNER_SHOULD_BE_STATIC_ANON)このクラスは内部クラスなのにそれを作成したオブジェクトへの埋め込まれた参照を使用していません。 この参照はより大きなクラスのインスタンスを作成して、必要以上に作成オブジェクトへの参照を存続しておくことがあります。 できれば、クラスは static 内部クラスにすべきです。 無名内部クラスは static にできないので、名前付き内部クラスにリファクタリングする必要があります。 SIC: static 内部クラスにリファクタリングできるかもしれない (SIC_INNER_SHOULD_BE_STATIC_NEEDS_THIS)このクラスは内部クラスなのにそれを作成したオブジェクトへの埋め込まれた参照を使用していません。 この参照はより大きなクラスのインスタンスを作成して、必要以上に長く作成オブジェクトへの参照を存続しておくかもしれません。 できれば、クラスは static 内部クラスにすべきです。 外部オブジェクトへの参照が内部クラスのインスタンスを構築する間必要なので内部クラスのコンストラクタに外部インスタンスへの参照を渡すようにリファクタリングする必要があります。 SS: 読み出されないフィールド (SS_SHOULD_BE_STATIC)このクラスにはコンパイル時に静的な値に初期化されるインスタンス final フィールドがあります。 static フィールドにすることを検討してください。 UM: 定数値で Math クラスの static メソッドを呼び出しているメソッド (UM_UNNECESSARY_MATH)
このメソッドは、定数値で
UPM: private メソッドは決して呼び出されない (UPM_UNCALLED_PRIVATE_METHOD)この private メソッドは、決して呼び出されません。 メソッドがリフレクションによって呼び出されるかもしれないが、決して使われないなら除去するべきです。 UrF: 読み出されないフィールド (URF_UNREAD_FIELD)このフィールドは決して読み出されません。クラスから除去することを検討してください。 UuF: 未使用のフィールド (UUF_UNUSED_FIELD)このフィールドは決して使われません。クラスから除去することを検討してください。 WMI: entrySet イテレータではなく効率が悪い keySet イテレータを使用している (WMI_WRONG_MAP_ITERATOR)
このメソッドは、keySet イテレータから取り出されたキーを使用して、マップエントリの値にアクセスしています。
Map の entrySet イテレータを使用したほうが Dm: ハードコードされた定数データベースパスワード (DMI_CONSTANT_DB_PASSWORD)このコードは、ハードコードされた定数パスワードを使用してデータベース接続を作成しています。 ソースコードかコンパイルされたコードへアクセスできる人なら誰でも簡単にパスワードを知ることができてしまいます。 Dm: 空のデータベースパスワード (DMI_EMPTY_DB_PASSWORD)このコードは、空白または空のパスワードを使用してデータベース接続を作成しています。 これはデータベースがパスワードによって保護されていないことを示しています。 HRS: 信頼できない入力から形成された HTTP cookie (HRS_REQUEST_PARAMETER_TO_COOKIE)
このコードは信頼できない HTTP パラメータを使用して HTTP クッキーを構築しています。
このクッキーが HTTP レスポンスに追加されるなら、HRS(HTTP レスポンススプリッティング) 脆弱性を可能にします。 FindBugs は、HRS の最も露骨で自明なケースだけを探します。 FindBugs が何かを発見したならほぼ間違いなく FindBugs が報告しないより多くの脆弱性があるでしょう。 HRS を心配するなら、商用の静的解析ツールかペネトレーションテストツールの使用を真剣に検討するべきです。 HRS: HTTP レスポンススプリッティング脆弱性 (HRS_REQUEST_PARAMETER_TO_HTTP_HEADER)
このコードは、HTTP ヘッダに HTTP パラメータを直接書き込んでいます。これは HRS(HTTP レスポンススプリッティング) 脆弱性を可能にします。 FindBugs は、HRS の最も露骨で自明なケースだけを探します。 FindBugs が何かを発見したならほぼ間違いなく FindBugs が報告しないより多くの脆弱性があるでしょう。 HRS を心配するなら、商用の静的解析ツールかペネトレーションテストツールの使用を真剣に検討するべきです。 PT: サーブレットの絶対パストラバーサル (PT_ABSOLUTE_PATH_TRAVERSAL)ソフトウェアは、制限されたディレクトリ内にあるべきパス名を構築するためにHTTPリクエストのパラメータを使いますが、パラメータはそのディレクトリの外にある場所に解決できる「/abs/path」のような絶対パスシーケンスを適切に無効にしていません。 詳細は、http://cwe.mitre.org/data/definitions/36.html を参照してください。 FindBugs は、相対パストラバーサルの最も露骨で自明なケースだけを探します。 FindBugs が何かを発見したならほぼ間違いなく FindBugs が報告しないより多くの脆弱性があるでしょう。 相対パストラバーサルを心配するなら、商用の静的解析ツールかペネトレーションテストツールの使用を真剣に検討するべきです。 PT: サーブレットの相対パストラバーサル (PT_RELATIVE_PATH_TRAVERSAL)ソフトウェアは、制限されたディレクトリ内にあるべきパス名を構築するためにHTTPリクエストのパラメータを使いますが、パラメータはそのディレクトリの外にある場所に解決できる「..」のようなシーケンスを適切に無効にしていません。 詳細は、http://cwe.mitre.org/data/definitions/23.html を参照してください。 FindBugs は、相対パストラバーサルの最も露骨で自明なケースだけを探します。 FindBugs が何かを発見したならほぼ間違いなく FindBugs が報告しないより多くの脆弱性があるでしょう。 相対パストラバーサルを心配するなら、商用の静的解析ツールかペネトレーションテストツールの使用を真剣に検討するべきです。 SQL: SQL の Statement の execute または addBatch メソッドに定数でない文字列を渡している (SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE)
このメソッドは、動的に生成されるように思われる文字列で、 SQL 文 の SQL: PreparedStatement が定数でない文字列から生成されている (SQL_PREPARED_STATEMENT_GENERATED_FROM_NONCONSTANT_STRING)
このコードは、定数でない文字列から SQL の XSS: 反射型クロスサイトスクリプティング脆弱性がある JSP (XSS_REQUEST_PARAMETER_TO_JSP_WRITER)
このコードは、JSP の出力に HTTP パラメータを直接書き込んでいます。これは XSS(クロスサイトスクリプティング) 脆弱性を可能にします。 FindBugs は、XSS の最も露骨で自明なケースだけを探します。 FindBugs が何かを発見したならほぼ間違いなく FindBugs が報告しないより多くの脆弱性があるでしょう。 XSS に関して心配しているなら商用の静的解析ツールかペネトレーションテストツールの使用を真剣に検討するべきです。 XSS: 反射型クロスサイトスクリプティング脆弱性がエラーページにあるサーブレット (XSS_REQUEST_PARAMETER_TO_SEND_ERROR)
このコードは、サーブレットのエラーページに FindBugs は、XSS の最も露骨で自明なケースだけを探します。 FindBugs が何かを発見したならほぼ間違いなく FindBugs が報告しないより多くの脆弱性があるでしょう。 XSS を心配するなら、商用の静的解析ツールかペネトレーションテストツールの使用を真剣に検討するべきです。 XSS: 反射型クロスサイトスクリプティング脆弱性があるサーブレット (XSS_REQUEST_PARAMETER_TO_SERVLET_WRITER)
このコードは、サーブレットの出力に HTTP パラメータを直接書き込んでいます。これは反射型 XSS(クロスサイトスクリプティング) 脆弱性を可能にします。 FindBugs は、XSS の最も露骨で自明なケースだけを探します。 FindBugs が何かを発見したならほぼ間違いなく FindBugs が報告しないより多くの脆弱性があるでしょう。 XSS を心配するなら、商用の静的解析ツールかペネトレーションテストツールの使用を真剣に検討するべきです。 BC: 抽象コレクションへの疑わしいキャスト (BC_BAD_CAST_TO_ABSTRACT_COLLECTION)
このコードは、Collection を抽象コレクションにキャストしています (たとえば BC: 具象コレクションへの疑わしいキャスト (BC_BAD_CAST_TO_CONCRETE_COLLECTION)このコードは抽象コレクション (たとえば、Collection、List、Set) を特定の具象実装 (たとえば、ArrayList、HashSet) にキャストしています。 これは正しくないかもしれません。そして、将来の時点で他の具象実装への切り替えをとても困難にするので、脆弱なコードになるかもしれません。 そうするための特別な理由がないかぎり抽象コレクションクラスを使用してください。 BC: 未チェック/未確認のキャスト (BC_UNCONFIRMED_CAST)このキャストはチェックされていません。すべての型のインスタンスをキャストする型へキャストできるわけではありません。 プログラムのロジックがこのキャストが失敗しないことを確実に確認してください。 BC: メソッドからの戻り値の未チェック/未確認のキャスト (BC_UNCONFIRMED_CAST_OF_RETURN_VALUE)このコードは、メソッドの戻り値の未確認のキャストを実行しています。 コードは、キャストが安全であることが保証されるようにメソッドを呼び出しているかもしれませんが、FindBugs はキャストが安全であることを検証できません。 プログラムのロジックがこのキャストが失敗しないことを確実に確認してください。 BC: 常に true を返す instanceof (BC_VACUOUS_INSTANCEOF)この instanceof は常に true を返します (テストしている値が null でないかぎり)。 これは安全で、誤解や論理エラーを指摘していないことを確認してください。 本当に null なのか値をテストしたいなら、多分、instanceof ではなく null テストをしたほうが良く、より明確になります。 BSHIFT: 符号なし右シフトを short/byte にキャストしている (ICAST_QUESTIONABLE_UNSIGNED_RIGHT_SHIFT)このコードは、符号なしキャストの実行結果を short または byte にキャストしています。結果の上位ビットは捨てられます。 上位ビットが捨てられるので、符号付きと符号なし右シフト (シフトのサイズによって) との違いがないかもしれません。 CI: final なクラスが protected フィールドを宣言している (CI_CONFUSED_INHERITANCE)このクラスは、final と宣言されていますが、フィールドは protected と宣言されています。 クラスは fainal なので派生できません。、protected の使用は紛らわしいです。 フィールドのためのアクセス修飾子は、フィールドの真の用途を表すため、 private か public に変更するべきです。 DB: 2つの分岐のために同じコードを使用しているメソッド (DB_DUPLICATE_BRANCHES)このメソッドは、条件分岐の2つの分岐を実装するために同じコードを使用しています。これがコーディングミスではないことを確認してください。 DB: switch 文の2つの case のために同じコードを使用しているメソッド (DB_DUPLICATE_SWITCH_CLAUSES)このメソッドは、switch 文の2つの case を実装するために同じコードを使用しています。 複製コードの case かもしれないし、コーディングミスかもしれません。 DLS: ローカル変数への無効な代入 (DLS_DEAD_LOCAL_STORE)この命令はローカル変数に値を代入していますが、値は読み出されないか以降の命令でも使われません。 多くの場合、計算された値が決して使われないので、これは誤りを示します。 Sun の javac コンパイラが final なローカル変数のためにしばしば無効な格納を生成することに注意してください。 FindBugs は、バイトコードベースのツールなので誤検出をなくす簡単な方法がありません。 DLS: return 文に役に立たない代入がある (DLS_DEAD_LOCAL_STORE_IN_RETURN)この文は、return 文でローカル変数に代入をしています。この代入は効果がありません。 この文が正しいことを確かめてください。 DLS: ローカル変数への無効な null 代入 (DLS_DEAD_LOCAL_STORE_OF_NULL)このコードはローカル変数に null を代入していますが代入された値は読み出されていません。 この代入はガベージコレクタを手伝うために導入されたのかもしれませんが、Java SE 6 ではもはや必要とされないか有用ではありません。 DLS: フィールドを遮るローカル変数への無効な代入 (DLS_DEAD_LOCAL_STORE_SHADOWS_FIELD)この命令は、ローカル変数に値を代入していますが、値は読み出されないか以降の命令でも使われません。 多くの場合、計算された値が決して使われないので、これは誤りを示します。 フィールドがローカル変数と同じ名前です。そうではなく、フィールドに代入するつもりでしたか? DMI: ハードコードされた絶対パス名への参照がある (DMI_HARDCODED_ABSOLUTE_FILENAME)
このコードは、ハードコードされた絶対パス名を使用して File オブジェクトを構築しています (たとえば DMI: ObjectOutput に書き込まれる非直列化可能オブジェクト (DMI_NONSERIALIZABLE_OBJECT_WRITTEN)
このコードは、 DMI: substring(0) の呼び出しは元の値を返す (DMI_USELESS_SUBSTRING)
このコードは、文字列で Dm: Thread オブジェクトが Runnable が期待されているところに渡されている (DMI_THREAD_PASSED_WHERE_RUNNABLE_EXPECTED)Threadオブジェクトが Runnable が期待されているメソッドへのパラメータとして渡されています。 これはかなり異常で、論理エラーを示すか、予想外の振る舞いの原因になることがあります。 Eq: スーパークラスの equals メソッドをオーバーライドしていないクラス (EQ_DOESNT_OVERRIDE_EQUALS)
このクラスは、 Eq: 異常な equals メソッド (EQ_UNUSUAL)
このクラスの FE: 浮動小数点の等価性のためのテスト (FE_FLOATING_POINT_EQUALITY)
この演算は、等価性のために2つの浮動小数点値を比較しています。
浮動小数点の計算は丸めを伴うかもしれないので計算された float と double の値は正確ではないかもしれません。
通貨のような正確でなければならない値のために FS: Boolean 型でない引数を %b 書式指示子を使用してフォーマットしている (VA_FORMAT_STRING_BAD_CONVERSION_TO_BOOLEAN)Boolean 型でない引数を %b 書式指示子でフォーマットしています。これは例外をスローしません。 その代わりに、非 null 値では true 、null では false を出力します。 書式文字列のこの機能は奇妙で意図したことではないかもしれません。 IA: 潜在的な継承されたメソッドなのか外部のメソッドなのかあいまいなメソッドの呼び出し (IA_AMBIGUOUS_INVOCATION_OF_INHERITED_OR_OUTER_METHOD)
内部クラスは、継承されたメソッドか外部クラスで定義されたメソッドなのかどちらとも解釈できるメソッドを呼び出しています。
たとえば、 本当に継承されたメソッドを呼び出すつもりなら super を付けて (例:super.foo(17)) 呼び出してください。 そうすれば、外部クラスのメソッドではなく継承されたメソッドを呼び出したいことがこのコードを読む人と FindBugs に明確になります。
IC: 初期化が循環している (IC_INIT_CIRCULARITY)バグインスタンスによって参照される2つのクラスのスタティックイニシャライザで循環が検出されました。 さまざまな予想外の振る舞いはそのような循環に起因することがあります。 ICAST: 整数の除算の結果を double または float にキャストしている (ICAST_IDIV_CAST_TO_DOUBLE)
このコードは 整数の除算の結果を double または float にキャストしています。
整数で除算をすることは、ゼロに最も近い整数値まで結果を切り捨てます。
結果が double にキャストされたという事実は、この精度が維持されるべきだったことを示唆しています。
おそらく意味されたことは、除算を実行する前にオペランドの1つまたは両方を double にキャストすることでした。 int x = 2; int y = 5; // Wrong: yields result 0.0 double value1 = x / y; // Right: yields result 0.4 double value2 = x / (double) y; ICAST: 整数乗算の結果を long にキャストしている (ICAST_INTEGER_MULTIPLY_CAST_TO_LONG)このコードは、以下のように整数の乗算を実行してから結果を long に変換しています。 long convertDaysToMilliseconds(int days) { return 1000*3600*24*days; }
long を使用して乗算をすれば、結果がオーバーフローするという可能性を回避できます。 long convertDaysToMilliseconds(int days) { return 1000L*3600*24*days; } または static final long MILLISECONDS_PER_DAY = 24L*3600*1000; long convertDaysToMilliseconds(int days) { return days * MILLISECONDS_PER_DAY; } IM: 平均の計算はオーバーフローする可能性がある (IM_AVERAGE_COMPUTATION_COULD_OVERFLOW)
このコードは、除算か符号付き右シフトを使用して2つの整数の平均を計算して、結果を配列の添字として使用しています。
平均値が非常に大きいならオーバーフローする可能性があります (結果として負の平均の計算になる)。
結果が負でないことを意図していたなら、その代わりに符号なし右シフトを使用できます。
つまり、 このバグは、二分探索とマージソートの多くの以前の実装で存在します。 Martin Buchholz が JDK ライブラリのバグを発見して修正しています。 Joshua Bloch が バグパターンとして公表しました。 IM: 負数で機能しない奇数チェック (IM_BAD_CHECK_FOR_ODD)
このコードは、 INT: 1を法とする整数の剰余 (INT_BAD_REM_BY_1)
どんな式 INT: 整数値の無意味なビットマスク演算 (INT_VACUOUS_BIT_OPERATION)
どんな有用な仕事もしない整数ビット演算 (AND、OR、XOR) です (たとえば INT: 整数値の無意味な比較 (INT_VACUOUS_COMPARISON)
常に同じ値を返す整数の比較があります (たとえば MTIA: Servlet クラスを拡張したクラスでのインスタンス変数の使用 (MTIA_SUSPECT_SERVLET_INSTANCE_FIELD)Servletクラスを拡張したクラスで、インスタンス変数を使用しています。 Servlet クラスの1つのインスタンスだけが Java EE フレームワークによって作成され、マルチスレッドによって使われるので、このパラダイムは極めて問題があり、推奨できません。 ローカル変数を使用することだけを検討してください。 MTIA: Struts Action を拡張したクラスでのインスタンス変数の使用 (MTIA_SUSPECT_STRUTS_INSTANCE_FIELD)Struts Action クラスを拡張したクラスで、インスタンス変数を使用しています。 Struts Action クラスの1つのインスタンスだけが Struts フレームワークによって作成され、マルチスレッドによって使われるので、このパラダイムは極めて問題があり、推奨できません。 ローカル変数を使用することだけを検討してください。 モニタを除いて書き込まれるインスタンスフィールドだけが報告されます。 NP: readLine メソッドの結果が null なのか確かめないで値を利用している (NP_DEREFERENCE_OF_READLINE_VALUE)
NP: readLine メソッドの結果をすぐに利用している (NP_IMMEDIATE_DEREFERENCE_OF_READLINE)
NP: null とわかっている値のロード (NP_LOAD_OF_KNOWN_NULL_VALUE)ここで参照されている変数は、以前に null なのかチェックしているため null であることがわかっています。 これは有効ですが、間違いかもしれません (多分異なる変数を参照することを意図してました、または以前の null チェックで null でないのか確かめるべきでした)。 NP: メソッドはパラメータに nullness アノテーションを強化している (NP_METHOD_PARAMETER_TIGHTENS_ANNOTATION)メソッドは、オーバーライドするメソッドの契約を常に実装するべきです。 したがって、メソッドが @Nullable としてマークされるパラメーターを取るならば、サブクラスでパラメーターを @Nonnull にしてメソッドをオーバーライドするべきでありません。 そうするとメソッドが null パラメータを処理すべき契約を破ります。 NP: メソッドは戻り値の nullness アノテーションを緩和している (NP_METHOD_RETURN_RELAXING_ANNOTATION)メソッドは、オーバーライドするメソッドの契約を常に実装するべきです。 したがって、メソッドが @Nonnull 値を返すようにアノテートしているならば、サブクラスでメソッドが @Nullable または @CheckForNull 値を返すようにアノテートしてメソッドをオーバーライドするべきでありません。 そうするとメソッドが null を返すべできではない契約を破ります。 NP: null になっている可能性があるメソッドの戻り値を利用している (NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE)メソッドからの戻り値を null チェックしないで利用しています。メソッドの戻り値は null なのかチェックするべきです。 コードが実行されると NullPointerException を引き起こすことがあります。 NP: null 値を実行不可能かもしれない分岐で利用している可能性がある (NP_NULL_ON_SOME_PATH_MIGHT_BE_INFEASIBLE)分岐または文が実行されるなら、null 値が利用されて NullPointerException が発生します。 もちろん、問題は分岐または文が実行不可能で、NullPointerException が決して発生する可能性がないということかもしれません。 それを決めるのは FindBugs の能力を超えています。 この値が既に null であることを検査したという事実からこれは明確な可能性です。 NP: パラメータは 非 null でなければならないが null 可能としてアノテートされている (NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE)このパラメータは、常に 非 null にすることを要求する方法で使われていますが、パラメータには明示的に null 可能としてアノテートされています。 パラメータかアノテーションのどちらかの使い方が間違っています。 NP: 書き込まれていない public または protected フィールドの読み出し (NP_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD)プログラムは、決して null 値でない値を書き込むと思われない public または protected フィールドの null 値を利用しています。 フィールドが解析によって見られない機構を通して初期化されないかぎり、この値を利用すると NullPointerException が発生します。 NS: 潜在的な非短絡論理の危険な使用 (NS_DANGEROUS_NON_SHORT_CIRCUIT)このコードは、短絡論理 (&& や ||) ではなく非短絡論理 (& や |) を使用していると思われます。 さらに、左辺値によって右辺を評価したくない (例外のスローや演算が高くつく副作用があるため) と思っているのかもしれません。 非短絡論理は、左辺を知ることによって結果を推論できたとしても両側の式が評価されます。 これは効率が悪く、右辺の評価でエラーが発生するケースを左辺でガードしているなら、結果としてエラーになる可能性があります。 詳細については、the Java Language Specification を参照してください。 NS: 非短絡論理の疑わしい使用 (NS_NON_SHORT_CIRCUIT)このコードは、短絡論理 (&& や ||) ではなく非短絡論理 (& や |) を使用していると思われます。 非短絡論理は、左辺を知ることによって結果を推論できたとしても両側の式が評価されます。 これは効率が悪く、右辺の評価でエラーが発生するケースを左辺でガードしているなら、結果としてエラーになる可能性があります。 詳細については、the Java Language Specification を参照してください。 PZLA: null ではなく長さが0の配列を返すことを検討する (PZLA_PREFER_ZERO_LENGTH_ARRAYS)結果がないこと (すなわち、結果の空のリスト) を示すために null 参照ではなく長さが0の配列 を返すことは、多くの場合より良い設計です。
他方では、「この質問に対する答えがない」ことを示すために null を使用することはおそらく適切です。
たとえば、 QF: 複雑か巧妙か間違ったインクリメントの for ループ (QF_QUESTIONABLE_FOR_LOOP)本当にこの for ループが正しい変数をインクリメントしていますか? 別の変数が for ループによって初期化されてチェックされるように見えます。 RCN: 非 null 値と null 値との冗長な比較 (RCN_REDUNDANT_COMPARISON_OF_NULL_AND_NONNULL_VALUE)このメソッドにはnull でないことがわかっている参照と null とわかっている別の参照との比較があります。 RCN: 2つの null 値の冗長な比較 (RCN_REDUNDANT_COMPARISON_TWO_NULL_VALUES)このメソッドには両方とも明らかに null とわかっている2つの参照の冗長な比較があります。 RCN: null でないことがわかっている値の冗長な null チェック (RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE)このメソッドには null でないことがわかっている値の冗長な null チェックがあります。 RCN: null とわかっている値の冗長な null チェック (RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE)このメソッドにはnull とわかっている値の冗長な null チェックがあります。 REC: 例外がスローされないのに例外をキャッチしている (REC_CATCH_EXCEPTION)
このメソッドは、例外オブジェクトをキャッチする try-catch ブロックを使用していますが、例外は try ブロックの中でスローされません。また、実行時例外は明示的にキャッチされません。
それぞれの catch ブロックが同一である多くの例外型をキャッチすることの短縮形として より良いアプローチは、明示的にキャッチするよりもスローされる特定の例外をスローします。 あるいは、以下に示すように明示的に RuntimeException をキャッチ、再スローして、非実行時例外をキャッチします。 try { ... } catch (RuntimeException e) { throw e; } catch (Exception e) { ... deal with all non-runtime exceptions ... } RI: スーパークラスと同じインタフェースを実装しているクラス (RI_REDUNDANT_INTERFACES)このクラスは、スーパークラスによっても実装されるインタフェースを実装することを宣言しています。 スーパークラスがインタフェースを実装するので、これは冗長です。デフォルトですべてのサブクラスもこのインタフェースを実装します。 このクラスが作成されてから継承階層が変わったことを指摘するかもしれません。インタフェースの実装の所有権を考慮するべきです。 RV: String.indexOf の結果が正かどうか確かめている (RV_CHECK_FOR_POSITIVE_INDEXOF)
このメソッドは RV: readLine メソッドの結果を null でないのか確かめた後で捨てている (RV_DONT_JUST_NULL_CHECK_READLINE)
RV: ハッシュコードの剰余は負かもしれない (RV_REM_OF_HASHCODE)このコードは、ハッシュコードを計算して別の値を法とする剰余を計算しています。 ハッシュコードは負になり、剰余演算の結果も負なります。
計算結果が負ではないことを確認したいなら、コードを変更する必要があるかもしれません。
除数が2の累乗であることがわかっているなら、代わりにビット演算を使用できます (すなわち、 RV: 符号付き32ビット整数の乱数の剰余 (RV_REM_OF_RANDOM_INT)
このコードは符号付き整数の乱数を生成して別の値を法とする剰余を計算しています。
乱数は負になり、剰余演算の結果も負になります。これが意図したことであることを確実にしてください。
その代わりに RV: メソッドは戻り値を無視しています、これは間違いではないですか? (RV_RETURN_VALUE_IGNORED_INFERRED)
このコードは、メソッドを呼び出して、戻り値を無視しています。
戻り値は、メソッドが呼び出される型と同じ型です。そして、我々の解析から戻り値が重要であるかもしれないように見えます (たとえば、 我々は、戻り値を無視することがメソッド本体の単純な解析から悪い考えかもしれないと推測しています。 このメソッドの戻り値を無視することが重要であるか許容できるかどうかに関して、FindBugs に指示する @CheckReturnValue アノテーションが使えます。 戻り値を無視することが間違いではないか決めるために厳密に調査してください。 RV: 副作用がないメソッドの戻り値は無視される (RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT)このコードは、メソッドを呼び出して戻り値を無視しています。 しかしながら、解析はメソッド (もしあればサブクラスの実装も含む) が戻り値以外の効果をもたらさないことを示しています。 この呼び出しは除去できます。 我々は、できる限り誤検出を減らそうとしていますが、いくつかのケースではこの警告が間違っているかもしれません。 よくある誤検出です。 - メソッドは、オーバライドされ解析対象外の他のプロジェクトで副作用がもたらされるように設計されている
- メソッドは、副作用をもたらすかもしれないクラスローダをトリガーするように呼び出されている - メソッドは、例外を取得するために呼び出されている 我々の仮定が正しくないと感じるなら、FindBugs にこのメソッドの戻り値が無視されることを許容するように指示する @CheckReturnValue アノテーションを使用することができます。 SA: フィールドの二重代入 (SA_FIELD_DOUBLE_ASSIGNMENT)
このメソッドにはフィールドの二重代入があります。 int x,y; public void foo() { x = x = 17; } フィールドに2回代入することは役に立たないので、論理エラーかタイプミスかもしれません。 SA: ローカル変数の二重代入 (SA_LOCAL_DOUBLE_ASSIGNMENT)
このメソッドにはローカル変数の二重代入があります。 public void foo() { int x,y; x = x = 17; } 変数に同じ値を2回代入することは役に立たないので、論理エラーかタイプミスかもしれません。 SA: ローカル変数の自己代入 (SA_LOCAL_SELF_ASSIGNMENT)
このメソッドにはローカル変数の自己代入があります。 public void foo() { int x = 3; x = x; } そのような代入は役に立たないので、論理エラーかタイプミスかもしれません。 SF: 1つの case が次の case へと通り抜ける switch 文を発見した (SF_SWITCH_FALLTHROUGH)このメソッドには1つの case が次の case へと通り抜ける switch 文があります。 通常は、break か return でこの case を終わらせる必要があります。 SF: default がない switch 文を発見した (SF_SWITCH_NO_DEFAULT)このメソッドにはdefault がない switch 文があります。 通常は、default を用意する必要があります。 解析は生成されたバイトコードを見るだけなので、default が switch 文の終わりにあって、他のケースに break 文が含まれていないなら誤検出のトリガーとなります。 ST: インスタンスメソッドから static フィールドへの書き込み (ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD)このインスタンスメソッドは、static フィールドに書き込みをしています。 複数のインスタンスが操作されているなら、正しくさせるのは難しいです。一般的にバッドプラクティスです。 Se: サブクラスで継承できない private な readResolve メソッド (SE_PRIVATE_READ_RESOLVE_NOT_INHERITED)
このクラスは、private な Se: Serializable でないクラスの transient フィールド (SE_TRANSIENT_FIELD_OF_NONSERIALIZABLE_CLASS)フィールドは、transient と宣言していますが、クラスは直列化可能ではないので、まったく効果がありません。 クラスが transient だったときの名残かもしれません、または直列化機構を誤解しているのかもしれません。 TQ: 値は型修飾子を必要としているが、不明としてマークされている (TQ_EXPLICIT_UNKNOWN_SOURCE_VALUE_REACHES_ALWAYS_SINK)値は、常に型修飾子によって示された値であることを必要とする方法で使われています。 しかし、値はどこでその型修飾子が必要なのかわからないと述べている明示的なアノテーションがあります。 使い方かアノテーションのどちらかが間違っています。 TQ: 値は型修飾子を必要としないが、不明としてマークされている (TQ_EXPLICIT_UNKNOWN_SOURCE_VALUE_REACHES_NEVER_SINK)値は、型修飾子によって示された値でないことを必要とする方法で使われています。 しかし、値はどこでその型修飾子がいるのか禁止されていのるかわからないと述べている明示的なアノテーションがあります。 使い方かアノテーションのどちらかが間違っています。 UC: 条件は効果がない (UC_USELESS_CONDITION)この条件は常に関係している変数の値が前に絞られたのと同じ結果を作り出します。 おそらく何かほかのことを意味していたのか、あるいは条件を除去できます。 UC: 条件は変数型のために効果がない (UC_USELESS_CONDITION_TYPE)この条件は関係している変数の型範囲のために常に同じ結果を作り出します。 おそらく何かほかのことを意味していたのか、あるいは条件を除去できます。 UC: 役に立たないオブジェクトを作成した (UC_USELESS_OBJECT)我々の解析でオブジェクトが役に立たないことを示しています。 作成され、変更されていますが、値はメソッドの外に出ないし、副作用をもたらしません。 間違いかオブジェクトが使われることを意図していたかのどちらか、あるいは除去できます。 この解析はめったに誤検出することはありません。よくある誤検出のケースです。 - 暗黙のうちに曖昧な例外をスローした - コードを一般化してスタブとして使用された - 弱/ソフト参照オブジェクトへの強い参照を持っていた UC: 役に立たないオブジェクトをスタックで作成した (UC_USELESS_OBJECT_STACK)このオブジェクトは副作用を持たない修正を行うために作成されています。 おそらく何かほかのことを意味していたのか、あるいはオブジェクトを除去できます。 UC: 役に立たない空ではない void メソッド (UC_USELESS_VOID_METHOD)我々の解析は、この空ではない void メソッドが実際に有用な仕事を行わないことを示しています。 確認してください。おそらくそのコードが間違っているか、またはボディを完全に除去できます。 我々はできる限り誤検出を減らそうと努力しているが、いくつかのケースでは警告は間違っているかもしれません。 よくある誤検出例です。 - メソッドは、副作用を持つかもしれないクラスのロードをトリガすることを意図している - メソッドは、暗黙のわかりにくい例外をスローするように意図されている UCF: 役に立たない制御フロー (UCF_USELESS_CONTROL_FLOW)
このメソッドには分岐するのかどうかに関係なく、制御フローが同じ場所へと続く、役に立たない制御フロー文があります。 if (argv.length == 0) { // TODO: handle this case } UCF: 次の行へ続くだけの役に立たない制御フロー (UCF_USELESS_CONTROL_FLOW_NEXT_LINE)
このメソッドには分岐するのかどうかに関係なく、制御フローが同じか次の行へと続く、役に立たない制御フロー文があります。 if (argv.length == 1); System.out.println("Hello, " + argv[0]); UrF: 読み出されない public または protected フィールド (URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD)このフィールドは決して読み出されません。 フィールドは、public か protected なので、多分、それは解析の一部として見えないクラスで使用されることを意図しています。 そうでなければ、クラスから除去することを検討してください。 UuF: 未使用の public または protected フィールド (UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD)このフィールドは決して使用されません。 フィールドは、public か protected なので、多分、それは解析の一部として見えないクラスで使用されることを意図しています。 そうでなければ、クラスから除去することを検討してください。 UwF: コンストラクタで初期化されていないフィールドを null チェックなしで null 値を利用している (UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR)このフィールドは、どんなコンストラクタの中でも決して初期化されません。したがって、オブジェクトが構築された後、null である可能性があります。 どこかほかで、値がロードされて、null チェックなしで null 値が利用されます。 フィールドが初期化される前に利用されると NullPointerException が発生するので、誤りか疑わしい設計かもしれません。 UwF: 書き込まてれいない public または protected フィールド (UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD)この public または protected フィールドは書き込まれていません。このフィールドからの読み出しはデフォルト値を返します。 誤りをチェックしてください (フィールドは初期化するべきでしたか?)。役に立たないなら除去してください。 XFB: XMLインタフェースの特定の実装のインスタンスを作成しているメソッド (XFB_XML_FACTORY_BYPASS)
このメソッドは、XMLインタフェースの特定の実装のインスタンスを作成しています。
提供されたファクトリクラスを使用してオブジェクトを作成して実行時に実装を変更できるようにすることが望ましいです。
Send comments to findbugs@cs.umd.edu |