PMDのJavaルールについてまとめます。バージョン6.35.0時のルールとなっています。 非推奨となっているルールには「△」を先頭に付与しています。
バージョン6.35.0から6.47.0までのルールの差分については別の記事でまとめています。 olafnosuke.hatenablog.com
Error Proneカテゴリには、紛らわしい、もしくはランタイムエラーが発生しやすい構造を検出するためのルールを含んでいる。
AssignmentInOperand
オペランド中の代入ロジックを検出
// NG例 public void doSomething() { if ((x = getX()) == 10) { // 複雑になり読みにくくなる ... } } // OK例 public void doSomething() { int x = getX(); // 外で代入した値を使用する if (x == 10) { System.out.println(x); } }
プロパティ
名前 | デフォルト値 | 説明 | 複数指定 |
---|---|---|---|
allowIf | false | ifの条件式内での代入を許可する | - |
allowFor | false | forの条件式内での代入を許可する | - |
allowWhile | false | whileの条件式内での代入を許可する | - |
allowIncrementDecrement | false | if、for、whileの条件式内でインクリメント演算子やデクリメント演算子の使用を許可する | - |
ルール設定例
<!-- プロパティ設定なし --> <rule ref="category/java/errorprone.xml/AssignmentInOperand" /> <!-- プロパティ設定あり --> <rule ref="category/java/errorprone.xml/AssignmentInOperand"> <properties> <property name="allowIf" value="false" /> <property name="allowFor" value="false" /> <property name="allowWhile" value="false" /> <property name="allowIncrementDecrement" value="false" /> </properties> </rule>
AssignmentToNonFinalStatic
コンストラクタでstaticフィールドへ代入されていないか
// NG例 static int x; public Sample(int y) { x = y; // 安全じゃない }
ルール設定例
<rule ref="category/java/errorprone.xml/AssignmentToNonFinalStatic" />
△AvoidAccessibilityAlteration
getDeclaredConstructors()、getDeclaredConstructor(Class[])、setAccessible() などのメソッドをPrivilegedAction以外の場所で呼んでいないか
PrivilegedActionはローカルPCから環境変数などの情報を取得するための特権を使用する際に使う。
Webアプリ開発時には不要。
ルール設定例
<rule ref="category/java/errorprone.xml/AvoidAccessibilityAlteration" />
AvoidAssertAsIdentifier
assertという識別子を使用している箇所を検出
// NG例 public void doSomething() { // JDK4以降assertは予約語 // コンパイルエラーになる String assert = "not good"; }
ルール設定例
<rule ref="category/java/errorprone.xml/AvoidAssertAsIdentifier" />
AvoidBranchingStatementAsLastInLoop
continueとbreakの変な使用方法を検出
// NG例 public void doSomething() { for (int i = 0; i < 10; i++) { if (i*i <= 25) { continue; // バグや混乱を招く可能性がある } break; } } // OK例 for (int i = 0; i < 10; i++) { if (i*i > 25) { break; } }
プロパティ
名前 | デフォルト値 | 説明 | 複数指定 |
---|---|---|---|
checkBreakLoopTypes | for|do|while | breakの使い方をチェックするループ対象 | 「|」区切り |
checkContinueLoopTypes | for|do|while | continueの使い方をチェックするループ対象 | 「|」区切り |
checkReturnLoopTypes | for|do|while | returnの使い方をチェックするループ対象 | 「|」区切り |
ルール設定例
<!-- プロパティ設定なし --> <rule ref="category/java/errorprone.xml/AvoidBranchingStatementAsLastInLoop" /> <!-- プロパティ設定あり --> <rule ref="category/java/errorprone.xml/AvoidBranchingStatementAsLastInLoop"> <properties> <property name="checkBreakLoopTypes" value="for|do|while" /> <property name="checkContinueLoopTypes" value="for|do|while" /> <property name="checkReturnLoopTypes" value="for|do|while" /> </properties> </rule>
AvoidCallingFinalize
Object.finalize()メソッドを明示的に呼び出していないか
// NG例 public void doSomething() { Bar b = new Bar(); b.finalize(); // アプリケーションでロジックの一部として呼ぶべきではない // java9以降はDeprecatedになっている + protectedなのでそもそも呼べない }
ルール設定例
<rule ref="category/java/errorprone.xml/AvoidCallingFinalize" />
AvoidCatchingNPE
NullPointerExceptionをcatchしていないか 通常の状況では、コードが NullPointerExceptions をスローすることはなく、元のエラーを隠し、後々問題を引き起こす可能性がある
// NG例 public void doSomething() { try { } catch (NullPointerException ex) { } }
ルール設定例
<rule ref="category/java/errorprone.xml/AvoidCatchingNPE" />
AvoidCatchingThrowable
Throwableをcatchしていないか Throwableは範囲が広く、OutOfMemoryError などのランタイムの問題も含まれるので良くない
// NG例 public void doSomething() { try { } catch (Throwable ex) { } }
ルール設定例
<rule ref="category/java/errorprone.xml/AvoidCatchingThrowable" />
AvoidDecimalLiteralsInBigDecimalConstructor
BigDecimal コンストラクタの引数に数値で小数値を与えている箇所を検出
// NG例 public void doSomething() { new BigDecimal(1.123); // 精度が失われる可能性がある } // OK例 public void doSomething() { new BigDecimal("1.123"); }
ルール設定例
<rule ref="category/java/errorprone.xml/AvoidDecimalLiteralsInBigDecimalConstructor" />
AvoidDuplicateLiterals
重複する文字列リテラルを含むコードを検出
// NG例 public void doSomething() { // 複数回同じ文字列を使用。 System.out.println("aaa"); System.out.println("aaa"); System.out.println("aaa"); System.out.println("aaa"); } // OK例 public void doSomething() { String s = "aaa"; System.out.println(s); System.out.println(s); System.out.println(s); System.out.println(s); }
プロパティ
名前 | デフォルト値 | 説明 | 複数指定 |
---|---|---|---|
separator | , | リスト区切り文字を無視 | - |
maxDuplicateLiterals | 4 | 最大重複リテラル数 | - |
minimumLength | 3 | チェックする文字列の最小文字数 | - |
skipAnnotations | false | アノテーション内のリテラルをスキップする | - |
exceptionList | 無視するリテラルのリスト | 「,」区切り |
ルール設定例
<!-- プロパティ設定なし --> <rule ref="category/java/errorprone.xml/AvoidDuplicateLiterals" /> <!-- プロパティ設定あり --> <rule ref="category/java/errorprone.xml/AvoidDuplicateLiterals"> <properties> <property name="separator" value="," /> <property name="maxDuplicateLiterals" value="4" /> <property name="minimumLength" value="3" /> <property name="skipAnnotations" value="false" /> <property name="exceptionList" value="" /> </properties> </rule>
AvoidEnumAsIdentifier
“enum”が使用されているか
// NG例 public void doSomething() { // JDK1.5以降enumは予約語 // コンパイルエラーになる String enum = "not good"; }
ルール設定例
<rule ref="category/java/errorprone.xml/AvoidEnumAsIdentifier" />
AvoidFieldNameMatchingMethodName
メソッド名と同じ名前のフィールド名がないか
// NG例 public String doSomething = "not good"; public void doSomething() { // 処理 }
ルール設定例
<rule ref="category/java/errorprone.xml/AvoidFieldNameMatchingMethodName" />
AvoidFieldNameMatchingTypeName
宣言している型名と同じ名前のフィールド名がないか
// NG例 public class Sample { public String sample; }
ルール設定例
<rule ref="category/java/errorprone.xml/AvoidFieldNameMatchingTypeName" />
AvoidInstanceofChecksInCatchClause
catch節の中で例外の種類をチェックしない
// NG例 public void doSomething() { try { } catch (Exception ex) { if (ex instanceof IOException) { // 例外の種類で処理を分けたい場合はcatch節を増やす // 例外処理 } } }
ルール設定例
<rule ref="category/java/errorprone.xml/AvoidInstanceofChecksInCatchClause" />
AvoidLiteralsInIfCondition
ifの条件式でハードコードされたリテラルを使用しない
// NG例 public void doSomething() { int i = 3; if (i == 10) { // 処理 } } // OK例 private static final int MAX_COUNT = 10; public void doSomething() { int i = 3; if (i == MAX_COUNT) { // 処理 } }
プロパティ
名前 | デフォルト値 | 説明 | 複数指定 |
---|---|---|---|
ignoreMagicNumbers | -1,0 | 無視するマジックナンバーリスト | 「,」区切り |
ignoreExpressions | true | trueの場合単純なif条件のリテラルのみが考慮される。falseの場合は式の中のリテラルもチェックする | - |
ルール設定例
<!-- プロパティ設定なし --> <rule ref="category/java/errorprone.xml/AvoidLiteralsInIfCondition" /> <!-- プロパティ設定あり --> <rule ref="category/java/errorprone.xml/AvoidLiteralsInIfCondition"> <properties> <property name="ignoreMagicNumbers" value="-1,0" /> <property name="ignoreExpressions" value="true" /> </properties> </rule>
AvoidLosingExceptionInformation
例外のインスタンスから得た情報を使用しているかどうか
// NG例 public void doSomething() { try { } catch (Exception ex) { ex.getMessage(); // getしているだけで戻り値を使用していない } }
ルール設定例
<rule ref="category/java/errorprone.xml/AvoidLosingExceptionInformation" />
AvoidMultipleUnaryOperators
複数の単項演算子を使用しない
// NG例 int i = - -1; boolean b = !!true; // OK例 int i = 1; boolean b = true;
ルール設定例
<rule ref="category/java/errorprone.xml/AvoidMultipleUnaryOperators" />
AvoidUsingOctalValues
整数をゼロから始めない
// NG例 int i = 012; // 0始まりは8進数として解釈される // OK例 int i = 12;
プロパティ
名前 | デフォルト値 | 説明 | 複数指定 |
---|---|---|---|
strict | false | 00と07の間の違反を検出するか | - |
ルール設定例
<!-- プロパティ設定なし --> <rule ref="category/java/errorprone.xml/AvoidUsingOctalValues" /> <!-- プロパティ設定あり --> <rule ref="category/java/errorprone.xml/AvoidUsingOctalValues"> <properties> <property name="strict" value="false" /> </properties> </rule>
BadComparison
Double.NaN との等価比較をしていないか
// NG例 boolean x = (y == Double.NaN);
ルール設定例
<rule ref="category/java/errorprone.xml/BadComparison" />
BeanMembersShouldSerialize
Beanクラスの中でgetter,setterが定義されているか
// NG例 private String name; //getter, setterが必要。命名規則に従っていない場合も検出される
プロパティ
名前 | デフォルト値 | 説明 | 複数指定 |
---|---|---|---|
ignoredAnnotations | lombok.Data| lombok.Getter| lombok.Value | このルールで無視するアノテーションの完全修飾名 | 「|」区切り |
prefix | スキップする変数のプレフィックス | - |
ルール設定例
<!-- プロパティ設定なし --> <rule ref="category/java/errorprone.xml/BeanMembersShouldSerialize" /> <!-- プロパティ設定あり --> <rule ref="category/java/errorprone.xml/BeanMembersShouldSerialize"> <properties> <property name="ignoredAnnotations" value="lombok.Data|lombok.Getter|lombok.Value" /> <property name="prefix" value="" /> </properties> </rule>
BrokenNullCheck
NullPointerExceptionをスローするようなNullチェックが行われていないか
// NG例 public String doSomething() { String string = "string"; if (string != null || !string.equals("")){ return string; } if (string == null && string.equals("")){ return string; } return string; }
ルール設定例
<rule ref="category/java/errorprone.xml/BrokenNullCheck" />
CallSuperFirst
android.app.Activity、android.app.Application、android.app.Serviceを継承したクラスは、メソッドの開始時に super を呼び出す必要がある
// NG例 public class DummyActivity extends Activity { public void onCreate(Bundle bundle) { // missing call to super.onCreate(bundle) foo(); } }
ルール設定例
<rule ref="category/java/errorprone.xml/CallSuperFirst" />
CallSuperLast
android.app.Activity、android.app.Application、android.app.Serviceを継承したクラスは、メソッドの終了時に super を呼び出す必要がある
// NG例 public class DummyActivity extends Activity { public void onCreate(Bundle bundle) { foo(); // missing call to super.onCreate(bundle) } }
ルール設定例
<rule ref="category/java/errorprone.xml/CallSuperLast" />
CheckSkipResult
InputStream.skip() メソッドは、要求されたバイト数よりも少ないバイト数をスキップする場合があるので、きちんとスキップされたかチェックする必要がある
// NG例 public void skip(int n) throws IOException { FileInputStream _s = new FileInputStream("file"); _s.skip(n); // You are not sure that exactly n bytes are skipped } // OK例 public void skipExactly(int n) throws IOException { FileInputStream _s = new FileInputStream("file"); while (n != 0) { long skipped = _s.skip(n); if (skipped == 0){ throw new EOFException(); } n -= skipped; } }
ルール設定例
<rule ref="category/java/errorprone.xml/CheckSkipResult" />
ClassCastExceptionWithToArray
ClassCastExceptionが発生するようなtoArray()メソッドの使い方をしているところがないか
// NG例 Collection c = new ArrayList(); Integer obj = Integer.valueOf(1); c.add(obj); Integer[] a = (Integer [])c.toArray(); // OK例 Integer[] b = (Integer [])c.toArray(new Integer[c.size()]);
ルール設定例
<rule ref="category/java/errorprone.xml/ClassCastExceptionWithToArray" />
CloneMethodMustBePublic
Cloneableを実装するクラスは、パブリックメソッドでObject.clone をオーバーライドする必要がある
// NG例 public class Sample implements Cloneable { @Override protected Object clone() throws CloneNotSupportedException { return null; } } // OK例 public class Sample implements Cloneable { @Override public Object clone() throws CloneNotSupportedException { return null; } }
ルール設定例
<rule ref="category/java/errorprone.xml/CloneMethodMustBePublic" />
CloneMethodMustImplementCloneable
clone()メソッドはCloneableをimplementsしているときのみ実装できる
// NG例 public class Sample { @Override public Object clone() throws CloneNotSupportedException { return null; } } // OK例 public class Sample implements Cloneable { @Override public Object clone() throws CloneNotSupportedException { return null; } }
ルール設定例
<rule ref="category/java/errorprone.xml/CloneMethodMustImplementCloneable" />
CloneMethodReturnTypeMustMatchClassName
cloneable を実装する場合、メソッド clone() の戻り型はクラス名にする
// NG例 public class Sample implements Cloneable { @Override public Object clone() throws CloneNotSupportedException { return null; } } // OK例 public class Sample implements Cloneable { @Override public Sample clone() throws CloneNotSupportedException { return null; } }
ルール設定例
<rule ref="category/java/errorprone.xml/CloneMethodReturnTypeMustMatchClassName" />
△CloneThrowsCloneNotSupportedException
非推奨のため省略
CloseResource
閉じられていないリソースがないかチェック
// NG例 public void doSomething(String string) throws FileNotFoundException { InputStream file = new FileInputStream(new File("/tmp/foo")); try { byte[] readAllBytes = file.readAllBytes(); } catch (IOException e) { // handle exception } }
プロパティ
名前 | デフォルト値 | 説明 | 複数指定 |
---|---|---|---|
closeTargets | このリソースを閉じる可能性があるメソッド | 「,」区切り | |
types | java.lang.AutoCloseable, java.sql.Connection, java.sql.Statement, java.sql.ResultSet | 影響のある型 | 「,」区切り |
closeAsDefaultTarget | true | スキップする変数のプレフィックス | - |
allowedResourceTypes | java.io.ByteArrayOutputStream| java.io.ByteArrayInputStream| java.io.StringWriter| java.io.CharArrayWriter| java.util.stream.Stream| java.util.stream.IntStream| java.util.stream.LongStream| java.util.stream.DoubleStream | クローズする必要のないクラス名 | 「|」区切り |
closeNotInFinally | false | 'close' (または他の closeTargets) がfinallyの外で呼び出されたかどうかを検出するか | - |
ルール設定例
<!-- プロパティ設定なし --> <rule ref="category/java/errorprone.xml/CloseResource" /> <!-- プロパティ設定あり --> <rule ref="category/java/errorprone.xml/CloseResource"> <properties> <property name="closeTargets" value="" /> <property name="types" value="java.lang.AutoCloseable,java.sql.Connection,java.sql.Statement,java.sql.ResultSet" /> <property name="closeAsDefaultTarget" value="true" /> <property name="allowedResourceTypes" value="java.io.ByteArrayOutputStream|java.io.ByteArrayInputStream|java.io.StringWriter|java.io.CharArrayWriter|java.util.stream.Stream|java.util.stream.IntStream|java.util.stream.LongStream|java.util.stream.DoubleStream" /> <property name="closeNotInFinally" value="false" /> </properties> </rule>
CompareObjectsWithEquals
オブジェクト参照の比較時にequals()を使用しているか
// NG例 public void doSomething() { String s1 = ""; String s2 = "ss"; if (s1 == s2) { // 処理 } } // OK例 public void doSomething() { String s1 = ""; String s2 = "ss"; if (s1.equals(s2)) { // 処理 } }
プロパティ
名前 | デフォルト値 | 説明 | 複数指定 |
---|---|---|---|
typesThatCompareByReference | java.lang.Enum, java.lang.Class | 参照比較が許可される型名のリスト | 「,」区切り |
ルール設定例
<!-- プロパティ設定なし --> <rule ref="category/java/errorprone.xml/CompareObjectsWithEquals" /> <!-- プロパティ設定あり --> <rule ref="category/java/errorprone.xml/CompareObjectsWithEquals"> <properties> <property name="typesThatCompareByReference" value="java.lang.Enum,java.lang.Class" /> </properties> </rule>
ConstructorCallsOverridableMethod
コンストラクタの実装にそのクラスのオーバライド可能なメソッドを呼び出す処理がないか
// NG例 public class Parent { public Parent() { toString(); } public String toString() { return "IAmSeniorClass"; } } public class Child extends Parent { private String name; public Child() { super(); //Automatic call leads to NullPointerException name = "JuniorClass"; } public String toString() { return name.toUpperCase(); } }
ルール設定例
<rule ref="category/java/errorprone.xml/ConstructorCallsOverridableMethod" />
△DataflowAnomalyAnalysis
非推奨のため省略
DetachedTestCase
テストケースに見えるメソッドがないか
// NG例 class SampleTest { @Test void test() { } void something() { } } // OK例 class SampleTest { @Test void test() { } private void something() { } }
ルール設定例
<rule ref="category/java/errorprone.xml/DetachedTestCase" />
DoNotCallGarbageCollectionExplicitly
System.gc()、Runtime.getRuntime().gc()、および System.runFinalization() を呼んでいないか
// NG例 public void doSomething() { System.gc(); }
ルール設定例
<rule ref="category/java/errorprone.xml/DoNotCallGarbageCollectionExplicitly" />
DoNotExtendJavaLangThrowable
Throwableを継承したクラスがないか
// NG例 public class SampleException extends Throwable { } // OK例 public class SampleException extends Exception { }
ルール設定例
<rule ref="category/java/errorprone.xml/DoNotExtendJavaLangThrowable" />
DoNotHardCodeSDCard
Androidでsdcardのパスをハードコーディングしない
// NG例 public class MyActivity extends Activity { protected void foo() { String storageLocation = "/sdcard/mypackage"; } }
ルール設定例
<rule ref="category/java/errorprone.xml/DoNotHardCodeSDCard" />
DoNotTerminateVM
System.exit()を呼んでいないか
// NG例 public void doSomething() { System.exit(0); }
ルール設定例
<rule ref="category/java/errorprone.xml/DoNotTerminateVM" />
DoNotThrowExceptionInFinally
finallyで例外をスローしていないか
// NG例 public void doSomething() { try { // 処理 } finally { throw new Exception(); } }
ルール設定例
<rule ref="category/java/errorprone.xml/DoNotThrowExceptionInFinally" />
DontImportSun
sun.*で始まるimport文がないか
// NG例 import sun.misc.foo; public class Foo {}
ルール設定例
<rule ref="category/java/errorprone.xml/DontImportSun" />
DontUseFloatTypeForLoopIndices
ループのインデックスにfloatを使用していないか
// NG例 public void doSomething() { for (float f = 0; f <= 3; f++) { // 処理 } }
ルール設定例
<rule ref="category/java/errorprone.xml/DontUseFloatTypeForLoopIndices" />
EmptyCatchBlock
空のcatch節がないか
// NG例 public void doSomething() { try { FileInputStream fis = new FileInputStream("/tmp/bugger"); } catch (IOException ioe) { } } // OK例 public void doSomething() { try { FileInputStream fis = new FileInputStream("/tmp/bugger"); } catch (IOException ex) { // catch節に処理を追加する logger.error("例外です", ex); } }
プロパティ
名前 | デフォルト値 | 説明 | 複数指定 |
---|---|---|---|
allowCommentedBlocks | false | コメントを含む空のブロックは許可する | - |
allowExceptionNameRegex | ^(ignored|expected)$ | この正規表現に一致する名前で例外をキャッチする空のブロックは許可する | - |
ルール設定例
<!-- プロパティ設定なし --> <rule ref="category/java/errorprone.xml/EmptyCatchBlock" /> <!-- プロパティ設定あり --> <rule ref="category/java/errorprone.xml/EmptyCatchBlock"> <properties> <property name="allowCommentedBlocks" value="false" /> <property name="allowExceptionNameRegex" value="^(ignored|expected)$" /> </properties> </rule>
EmptyFinalizer
空のファイナライザーがないか
// NG例 public class Sample { protected void finalize() { } }
ルール設定例
<rule ref="category/java/errorprone.xml/EmptyFinalizer" />
EmptyFinallyBlock
空のfinallyブロックがないか
// NG例 public void doSomething() { try { // 処理 } finally { } }
ルール設定例
<rule ref="category/java/errorprone.xml/EmptyFinallyBlock" />
EmptyIfStmt
空の if ステートメントがないか
// NG例 public void doSomething(String s) { if(s == null){ } }
ルール設定例
<rule ref="category/java/errorprone.xml/EmptyIfStmt" />
EmptyInitializer
空のイニシャライザがないか
// NG例 public class Sample { static {} }
ルール設定例
<rule ref="category/java/errorprone.xml/EmptyInitializer" />
EmptyStatementBlock
空のブロックステートメントがないか
// NG例 public void doSomething() { {} }
ルール設定例
<rule ref="category/java/errorprone.xml/EmptyStatementBlock" />
EmptyStatementNotInLoop
無駄な空文がないか
// NG例 public void doSomething() { ; }
ルール設定例
<rule ref="category/java/errorprone.xml/EmptyStatementNotInLoop" />
EmptySwitchStatements
空のswitchがないか
// NG例 public void doSomething() { int x = 2; switch (x) { } }
ルール設定例
<rule ref="category/java/errorprone.xml/EmptySwitchStatements" />
EmptySynchronizedBlock
空のsynchronizedブロックがないか
// NG例 public void doSomething() { synchronized (this) { } }
ルール設定例
<rule ref="category/java/errorprone.xml/EmptySynchronizedBlock" />
EmptyTryBlock
空のtryブロックがないか
// NG例 public void doSomething() { try { } catch (Exception e) { e.printStackTrace(); } }
ルール設定例
<rule ref="category/java/errorprone.xml/EmptyTryBlock" />
EmptyWhileStmt
空のwhileステートメントがないか
// NG例 public void doSomething() { int a = 2; int b = 3; while (a == b) { } }
ルール設定例
<rule ref="category/java/errorprone.xml/EmptyWhileStmt" />
EqualsNull
equals()でnullと比較されていないか
// NG例 public void doSomething() { String x = "foo"; if (x.equals(null)){ // 処理 } }
ルール設定例
<rule ref="category/java/errorprone.xml/EqualsNull" />
FinalizeDoesNotCallSuperFinalize
finalize()メソッドの最後でsuper.finalize()を呼び出しているか
// NG例 public class Sample { protected void finalize() { // 処理 } }
ルール設定例
<rule ref="category/java/errorprone.xml/FinalizeDoesNotCallSuperFinalize" />
FinalizeOnlyCallsSuperFinalize
super.finalize()だけを呼び出していないか
// NG例 public class Sample { protected void finalize() { super.finalize(); // java9以降非推奨 } }
ルール設定例
<rule ref="category/java/errorprone.xml/FinalizeOnlyCallsSuperFinalize" />
FinalizeOverloaded
finalize()メソッドをオーバーロードしていないか
// NG例 public class Sample { protected void finalize(int a) { } }
ルール設定例
<rule ref="category/java/errorprone.xml/FinalizeOverloaded" />
FinalizeShouldBeProtected
finalize()メソッドがprotectedで宣言されているか
// NG例 public class Sample { public void finalize() { } }
ルール設定例
<rule ref="category/java/errorprone.xml/FinalizeShouldBeProtected" />
IdempotentOperations
べき等演算をしていないか
// NG例 public void doSomething() { int a = 2; a = a; }
ルール設定例
<rule ref="category/java/errorprone.xml/IdempotentOperations" />
△ImportFromSamePackage
非推奨のため省略
InstantiationToGetClass
getClass() を呼び出すためだけにオブジェクトをインスタンス化していないか
// NG例 Class c = new String().getClass(); // OK例 Class c = String.class;
ルール設定例
<rule ref="category/java/errorprone.xml/InstantiationToGetClass" />
InvalidLogMessageFormat
slf4j および log4j2 (6.19.0 以降) ロガーで、引数とプレースホルダーの数が一致しないメッセージがないか
// NG例 logger.error("forget the arg %s");
ルール設定例
<rule ref="category/java/errorprone.xml/InvalidLogMessageFormat" />
JumbledIncrementer
間違ったインクリメント文を検出する
// NG例 for (int i = 0; i < 10; i++) { for (int k = 0; k < 20; i++) { // k++の間違い ... } }
ルール設定例
<rule ref="category/java/errorprone.xml/JumbledIncrementer" />
JUnitSpelling
Junit3用:setUp()とtearDown()のメソッド名スペルミス検出
ルール設定例
<rule ref="category/java/errorprone.xml/JUnitSpelling" />
JUnitStaticSuite
Junit3用suite()がpublic staticであるか
ルール設定例
<rule ref="category/java/errorprone.xml/JUnitStaticSuite" />
△LoggerIsNotStaticFinal
非推奨のため省略
MethodWithSameNameAsEnclosingClass
コンストラクタ以外でクラス名と同じメソッド名のメソッドはないか
// NG例 public class Sample { public void Sample(){ } }
ルール設定例
<rule ref="category/java/errorprone.xml/MethodWithSameNameAsEnclosingClass" />
MisplacedNullCheck
見当違いなnullチェックでないか
// NG例 public void doSomething() { String a = null; String baz = "baz"; if (a.equals(baz) && a != null) { } }
ルール設定例
<rule ref="category/java/errorprone.xml/MisplacedNullCheck" />
MissingBreakInSwitch
break文が記述されていないswitch文がないか
// NG例 public void doSomething() { int status = 1; switch (status) { case 1: System.out.println("1"); case 2: System.out.println("2"); break; } }
ルール設定例
<rule ref="category/java/errorprone.xml/MissingBreakInSwitch" />
MissingSerialVersionUID
SerialVersionUIDが定義されているか
// NG例 public class Book implements Serializable { String name; public String getName(){ return name; } public void setName(String name){ this.name = name; } }
ルール設定例
<rule ref="category/java/errorprone.xml/MissingSerialVersionUID" />
MissingStaticMethodInNonInstantiatableClass
staticメソッドおよびpublicコンストラクタが存在しないクラスを検出
// NG例 public class Sample private Sample(){ } void foo() { } }
プロパティ
名前 | デフォルト値 | 説明 | 複数指定 |
---|---|---|---|
annotations | org.springframework.beans.factory.annotation.Autowired, javax.inject.Inject | コンストラクターにこれらのいずれかのアノテーションが付けられている場合、クラスは無視される | 「,」区切り |
ルール設定例
<!-- プロパティ設定なし --> <rule ref="category/java/errorprone.xml/MissingStaticMethodInNonInstantiatableClass" /> <!-- プロパティ設定あり --> <rule ref="category/java/errorprone.xml/MissingStaticMethodInNonInstantiatableClass"> <properties> <property name="annotations" value="org.springframework.beans.factory.annotation.Autowired,javax.inject.Inject" /> </properties> </rule>
MoreThanOneLogger
クラス内に複数のLoggerが宣言されていないか
// NG例 public class Sample Logger log = Logger.getLogger(Sample.class); Logger log2 = Logger.getLogger(Sample.class); }
ルール設定例
<rule ref="category/java/errorprone.xml/MoreThanOneLogger" />
NonCaseLabelInSwitchStatement
switch文でcaseラベル以外が記述されていないか
// NG例 public void doSomething() { int status = 1; switch (status) { case 1: System.out.println("1"); break; mycase 2: System.out.println("2"); break; } }
ルール設定例
<rule ref="category/java/errorprone.xml/NonCaseLabelInSwitchStatement" />
NonStaticInitializer
staticでないinitializerがあるか
// NG例 public class Sample { // 処理 } }
ルール設定例
<rule ref="category/java/errorprone.xml/NonStaticInitializer" />
NullAssignment
変数宣言以外で変数にnullが設定されていないか
// NG例 public void doSomething() { String a = null; a = "aaa"; a = null; }
ルール設定例
<rule ref="category/java/errorprone.xml/NullAssignment" />
OverrideBothEqualsAndHashcode
equals(Object other) と hashCode() の片方しか定義されていないクラスを検出
// NG例 public class Book { public boolean equals(Object o) { return true; } }
ルール設定例
<rule ref="category/java/errorprone.xml/OverrideBothEqualsAndHashcode" />
ProperCloneImplementation
super.clone() が呼び出されていない clone() メソッドを検出
// NG例 public class Book { public Object clone() { return new Book(); } }
ルール設定例
<rule ref="category/java/errorprone.xml/ProperCloneImplementation" />
ProperLogger
Loggerがprivate static finalで宣言されているか
// NG例 public class Sample Logger log = Logger.getLogger(Sample.class); }
プロパティ
名前 | デフォルト値 | 説明 | 複数指定 |
---|---|---|---|
staticLoggerName | LOG | staticなロガー変数の名前 | - |
loggerName | log | Loggerインスタンス変数の名前 | - |
loggerClass | Log | ロガーのクラス名 | - |
ルール設定例
<!-- プロパティ設定なし --> <rule ref="category/java/errorprone.xml/ProperLogger" /> <!-- プロパティ設定あり --> <rule ref="category/java/errorprone.xml/ProperLogger"> <properties> <property name="staticLoggerName" value="LOG" /> <property name="loggerName" value="log" /> <property name="loggerClass" value="Log" /> </properties> </rule>
ReturnEmptyArrayRatherThanNull
配列を返すメソッドでnullではなく空の配列を返しているか
// NG例 public int[] doSomething() { return null; // OK例 public int[] doSomething() { return new int[10]; }
ルール設定例
<rule ref="category/java/errorprone.xml/ReturnEmptyArrayRatherThanNull" />
ReturnFromFinallyBlock
finallyブロックからreturnしていないか
// NG例 public String doSomething() { try { throw new Exception("a"); } finally { return "abcde"; } }
ルール設定例
<rule ref="category/java/errorprone.xml/ReturnFromFinallyBlock" />
SimpleDateFormatNeedsLocale
SimpleDateFormat生成時にロケールが指定されているか
// NG例 private SimpleDateFormat format = new SimpleDateFormat("pattern");
ルール設定例
<rule ref="category/java/errorprone.xml/SimpleDateFormatNeedsLocale" />
SingleMethodSingleton
オーバーロードされたgetInstanceメソッドがないか
// NG例 public class Book { private static Book book = new Book( ); public static Book getInstance( ) { return book; } public static Book getInstance(Object obj){ Book book = (Book) obj; return book; } }
ルール設定例
<rule ref="category/java/errorprone.xml/SingleMethodSingleton" />
SingletonClassReturningNewInstance
シングルトンクラスはインスタンスを1つだけ持つ
// NG例 public class Book { private static Book book = null; public static Book getInstance( ) { synchronized(Book.class) { return new Book(); } } }
ルール設定例
<rule ref="category/java/errorprone.xml/SingletonClassReturningNewInstance" />
StaticEJBFieldShouldBeFinal
EJB にstaticフィールドがfinalで定義されていない箇所を検出
// NG例 public class SomeEJB extends EJBObject implements EJBLocalHome { private static int CountA; } // OK public class SomeEJB extends EJBObject implements EJBLocalHome { private static final int CountB; // preferred, read-only access }
ルール設定例
<rule ref="category/java/errorprone.xml/StaticEJBFieldShouldBeFinal" />
StringBufferInstantiationWithChar
StringBufferのコンストラクタでcharを指定していないか
// NG例 StringBuffer sb1 = new StringBuffer('c'); // OK例 StringBuffer sb2 = new StringBuffer("c");
ルール設定例
<rule ref="category/java/errorprone.xml/StringBufferInstantiationWithChar" />
SuspiciousEqualsMethodName
equals()メソッドと間違えてそうなメソッドがないか
// NG例 public int equals(Object o) { }
ルール設定例
<rule ref="category/java/errorprone.xml/SuspiciousEqualsMethodName" />
SuspiciousHashcodeMethodName
hashCode()メソッドと間違えてそうなメソッドがないか
// NG例 public int hashcode() { }
ルール設定例
<rule ref="category/java/errorprone.xml/SuspiciousHashcodeMethodName" />
SuspiciousOctalEscape
疑わしい8進数の記述がないかチェック
// NG例 String s = null; s = "\128"; // "\12" + "8" と見なされる
ルール設定例
<rule ref="category/java/errorprone.xml/SuspiciousOctalEscape" />
TestClassWithoutTestCases
テストクラスみたいな名前のクラスがないか
// NG例 public class BookTest { public void doSomething() { } }
ルール設定例
<rule ref="category/java/errorprone.xml/TestClassWithoutTestCases" />
UnconditionalIfStatement
常にtrueまたはfalseであるif文がないか
// NG例 if(true) { // 処理 }
ルール設定例
<rule ref="category/java/errorprone.xml/UnconditionalIfStatement" />
UnnecessaryBooleanAssertion
不要なassertFalse()、assertTrue()がないか
// NG例 class SampleTest { @Test void test() { assertTrue(true); } }
ルール設定例
<rule ref="category/java/errorprone.xml/UnnecessaryBooleanAssertion" />
UnnecessaryCaseChange
不必要なtoUpperCase()、toLowerCase()がないか
// NG例 boolean answer1 = str.toUpperCase().equals("baz"); // OK例 boolean answer2 = str.equalsIgnoreCase("baz");
ルール設定例
<rule ref="category/java/errorprone.xml/UnnecessaryCaseChange" />
UnnecessaryConversionTemporary
プリミティブ型を文字列に変換する場合に無駄な一時変数を使用していないか
// NG例 String s1 = new Integer(x).toString(); // OK例 String s2 = Integer.toString(x);
ルール設定例
<rule ref="category/java/errorprone.xml/UnnecessaryConversionTemporary" />
UnusedNullCheckInEquals
nullチェックした後、別のオブジェクトの equals()メソッドに渡すのではなく、そのオブジェクトでequals()を呼び出しているか
// NG例 public void doSomething() { String s = ""; String t = ""; if (s != null && t.equals(s)) { } }
ルール設定例
<rule ref="category/java/errorprone.xml/UnusedNullCheckInEquals" />
UseCorrectExceptionLogging
完全なスタックトレースが確実に出力されるようにするには、2 つの引数 (String と Throwable) を指定した logging ステートメントを使用しているか
// NG例 public void doSomething() { try { FileInputStream fis = new FileInputStream("/tmp/bugger"); } catch (IOException ex) { logger.error(ex); } }
ルール設定例
<rule ref="category/java/errorprone.xml/UseCorrectExceptionLogging" />
UseEqualsToCompareStrings
==
または !=
を使用した文字列の比較をしていないか
// NG例 public void doSomething() { String s = ""; if (s != "") { } }
ルール設定例
<rule ref="category/java/errorprone.xml/UseEqualsToCompareStrings" />
UselessOperationOnImmutable
String、BigDecimal、BigIntegerに対する無意味なロジックがないか
// NG例 BigDecimal bd = new BigDecimal(10); bd.add(new BigDecimal(5)); // OK例 BigDecimal bd = new BigDecimal(10); bd = bd.add(new BigDecimal(5));
ルール設定例
<rule ref="category/java/errorprone.xml/UselessOperationOnImmutable" />
UseLocaleWithCaseConversions
String.toLowerCase()メソッド/toUpperCase()メソッドでロケールが指定されているか
// NG例 String s = a.toLowerCase(); // OK例 String s = a.toLowerCase(Locale.EN);
ルール設定例
<rule ref="category/java/errorprone.xml/UseLocaleWithCaseConversions" />
UseProperClassLoader
getClassLoader()メソッドが使用されていないか
// NG例 ClassLoader cl = Book.class.getClassLoader(); // OK例 ClassLoader cl = Thread.currentThread().getContextClassLoader();
ルール設定例
<rule ref="category/java/errorprone.xml/UseProperClassLoader" />
他のカテゴリのルールもまとめています。
Best Practiceカテゴリのまとめはこちら: olafnosuke.hatenablog.com
Code Styleカテゴリのまとめはこちら: olafnosuke.hatenablog.com
Designカテゴリのまとめはこちら: olafnosuke.hatenablog.com
Documentationカテゴリのまとめはこちら: olafnosuke.hatenablog.com
Multithreadingカテゴリのまとめはこちら: olafnosuke.hatenablog.com
Performanceカテゴリのまとめはこちら: olafnosuke.hatenablog.com
Securityカテゴリのまとめはこちら: olafnosuke.hatenablog.com