PMD Javaルール Performanceカテゴリ

PMDのJavaルールについてまとめます。バージョン6.35.0時のルールとなっています。
非推奨となっているルールには「△」を先頭に付与しています。

バージョン6.35.0から6.47.0までのルールの差分については別の記事でまとめています。 olafnosuke.hatenablog.com

Performanceカテゴリ

最適でないコードにフラグを立てるルールを含むカテゴリ。

AddEmptyString

空の文字列と連結して文字列変換していないか

// NG
String s = "" + 123;

// OK
String t = Integer.toString(123);

ルール設定例

<rule ref="category/java/performance.xml/AddEmptyString" />

AppendCharacterWithChar

StringBuffer/StringBuilder.append メソッドで文字を文字列として連結していないか

// NG
StringBuilder builder = new StringBuilder();
builder.append("a");

// OK
StringBuilder builder = new StringBuilder();
builder.append('a');

ルール設定例

<rule ref="category/java/performance.xml/AppendCharacterWithChar" />

AvoidArrayLoops

手動で配列をコピーしていないか

// NG
String[] a = { "1", "2", "3" };
String[] b = new String[3];
for (int i = 0; i < a.length; i++) {
    b[i] = a[i];
}

// OK
String[] a = { "1", "2", "3" };
String[] b = Arrays.copyOf(a, 3);

ルール設定例

<rule ref="category/java/performance.xml/AvoidArrayLoops" />

AvoidCalendarDateCreation

カレンダーの利用を避ける

// NG
Calendar.getInstance().getTime();

// OK
new Date();
LocalDateTime.now();

ルール設定例

<rule ref="category/java/performance.xml/AvoidCalendarDateCreation" />

AvoidFileStream

FileInputStream, FileOutputStream, FileReader, FileWriterの使用を避ける

// NG
try (FileInputStream fis = new FileInputStream("test")) {
} catch (IOException e) {
}

// OK
try (InputStream is = Files.newInputStream(Paths.get("test"))) {
} catch (IOException e) {
}

ルール設定例

<rule ref="category/java/performance.xml/AvoidFileStream" />

AvoidInstantiatingObjectsInLoops

ループ内でインスタンスを生成しない

// NG
for (int i = 0; i < 10; i++) {
    Book book = new Book();
}

ルール設定例

<rule ref="category/java/performance.xml/AvoidInstantiatingObjectsInLoops" />

△AvoidUsingShortType

非推奨のため省略


BigIntegerInstantiation

定数で指定できるBigInteger, BigDecimalインスタンスは生成しない

// NG
BigInteger one = new BigInteger("1");

// OK
BigInteger one = BigInteger.ONE;

ルール設定例

<rule ref="category/java/performance.xml/BigIntegerInstantiation" />

BooleanInstantiation

Booleanのインスタンスは生成しない

// NG
Boolean b = new Boolean("true"); // 非推奨
Boolean b2 = Boolean.valueOf(true);

// OK
Boolean b = Boolean.TRUE;

ルール設定例

<rule ref="category/java/performance.xml/BooleanInstantiation" />

ByteInstantiation

Byteのインスタンスは生成しない

// NG
Byte b = new Byte("0"); // 非推奨

// OK
Byte b = Byte.valueOf("0");

ルール設定例

<rule ref="category/java/performance.xml/ByteInstantiation" />

ConsecutiveAppendsShouldReuse

StringBuffer/StringBuilder.appendの連続呼び出しを避ける

// NG
StringBuilder builder = new StringBuilder();
builder.append("aa");
builder.append("bb");
builder.append("cc");

// OK
StringBuilder builder = new StringBuilder();
builder.append("aa").append("bb").append("cc");

ルール設定例

<rule ref="category/java/performance.xml/ConsecutiveAppendsShouldReuse" />

ConsecutiveLiteralAppends

StringBuffer/StringBuilder.appendで文字列を連続で連結しない

// NG
StringBuilder builder = new StringBuilder();
builder.append("aa").append("bb").append("cc");

// OK
StringBuilder builder = new StringBuilder();
builder.append("aabbcc");

プロパティ

名前 デフォルト値 説明 複数指定
threshold 1 最大連続追加可能回数 -

ルール設定例

<!-- プロパティ設定なし -->
<rule ref="category/java/performance.xml/ConsecutiveLiteralAppends" />

<!-- プロパティ設定あり -->
<rule ref="category/java/performance.xml/ConsecutiveLiteralAppends">
    <properties>
        <property name="threshold" value="1" />
    </properties>
</rule>

InefficientEmptyStringCheck

String.trim().length()で文字列が空かどうか確認しない

// NG
String s = "pppp";
if (s != null && s.trim().length() > 0) {
}

// OK
// 文字列を1文字ずつチェックした方がパフォーマンスが上がる
for (int i = 0; i < s.length(); i++) {
  if (!Character.isWhitespace(s.charAt(i))) {
  }
}

ルール設定例

<rule ref="category/java/performance.xml/InefficientEmptyStringCheck" />

InefficientStringBuffering

効率の悪いStringBufferの使用方法をしていないか

// NG
StringBuilder builder = new StringBuilder();
builder.append("aa" + getStr()); // append()の中で+で連結しない

// OK
StringBuilder builder = new StringBuilder();
builder.append("aa").append(getStr());

ルール設定例

<rule ref="category/java/performance.xml/InefficientStringBuffering" />

InsufficientStringBufferDeclaration

StringBufferの初期化時にサイズを指定するべき

// NG
// 何も指定しないで生成した場合16文字分のサイズでインスタンスは作成される
StringBuffer bad = new StringBuffer();
bad.append("This project made for PMD rule research.");

// OK
// 16文字を超える場合はインスタンス生成時にサイズを指定する
StringBuffer bad = new StringBuffer(50);
bad.append("This project made for PMD rule research.");

ルール設定例

<rule ref="category/java/performance.xml/InsufficientStringBufferDeclaration" />

IntegerInstantiation

new Integer()は使用しない

// NG
Integer i = new Integer(0); //非推奨

// OK
Integer i = Integer.valueOf(0);

ルール設定例

<rule ref="category/java/performance.xml/IntegerInstantiation" />

LongInstantiation

new Long()は使用しない

// NG
Long l = new Long(0); //非推奨

// OK
Long l = Long.valueOf(0);

ルール設定例

<rule ref="category/java/performance.xml/LongInstantiation" />

OptimizableToArrayCall

Collection.toArray()は必要なサイズの配列で呼び出す

// NG
List<String> list = new ArrayList<String>();
list.toArray(new String[0]);

// OK
List<String> list = new ArrayList<String>();
list.toArray(new String[list.size()]);

ルール設定例

<rule ref="category/java/performance.xml/OptimizableToArrayCall" />

RedundantFieldInitializer

Javaのデフォルト値でフィールドを初期化しない

// NG
public class Sample {
    int i = 0;
}

// OK
public class Sample {
    int i;
}

ルール設定例

<rule ref="category/java/performance.xml/RedundantFieldInitializer" />

ShortInstantiation

new Short()は使用しない

// NG
Short s = new Short(0); //非推奨

// OK
Short s = Short.valueOf(0);

ルール設定例

<rule ref="category/java/performance.xml/ShortInstantiation" />

△SimplifyStartsWith

非推奨のため省略


StringInstantiation

new String()は使用しない

// NG
String s = new String("abc"); 

// OK
String s = "abc";

ルール設定例

<rule ref="category/java/performance.xml/StringInstantiation" />

StringToString

Stringオブジェクトに対してtoString()を呼ばない

// NG
String s = "abc";
s.toString();

ルール設定例

<rule ref="category/java/performance.xml/StringToString" />

TooFewBranchesForASwitchStatement

ケースが少ない場合はswitchを使用しない

// NG
String i = "abc";
switch (i) {
case "abc":
    break;
default:
    break;
}

// OK
if ("abc".equals(i)) {
} else {
}

プロパティ

名前 デフォルト値 説明 複数指定
minimumNumberCaseForASwitch 3 スイッチの最小ケース数 -

ルール設定例

<!-- プロパティ設定なし -->
<rule ref="category/java/performance.xml/TooFewBranchesForASwitchStatement" />

<!-- プロパティ設定あり -->
<rule ref="category/java/performance.xml/TooFewBranchesForASwitchStatement">
    <properties>
        <property name="minimumNumberCaseForASwitch" value="3" />
    </properties>
</rule>

UnnecessaryWrapperObjectCreation

ラッパーオブジェクトは不必要に作成しない

// NG
String s = "12";
int i;
i = Integer.valueOf(s).intValue();

// OK
String s = "12";
int i;
i = Integer.parseInt(s);

ルール設定例

<rule ref="category/java/performance.xml/UnnecessaryWrapperObjectCreation" />

UseArrayListInsteadOfVector

Vectorの代わりにjava.util.ArrayListを使用する

// NG
void doSomething() {
    Vector<String> v = new Vector<String>();
}

// OK
void doSomething() {
    List<String> l = new ArrayList<String>();
}

ルール設定例

<rule ref="category/java/performance.xml/UseArrayListInsteadOfVector" />

UseArraysAsList

配列からリストへの変換はArrays.asListを使用する

// NG
int[] ints = { 1, 2, 3 };
List<Integer> list = new ArrayList<>();
for (int i = 0; i < ints.length; i++) {
    list.add(ints[i]);
}

// OK
int[] ints = { 1, 2, 3 };
Arrays.asList(ints);

ルール設定例

<rule ref="category/java/performance.xml/UseArraysAsList" />

UseIndexOfChar

1文字のインデックスをチェックはString.indexOf(char) を使う

// NG
String s = "hello world";
s.indexOf("d");

// OK
String s = "hello world";
s.indexOf('d');

ルール設定例

<rule ref="category/java/performance.xml/UseIndexOfChar" />

UseIOStreamsWithApacheCommonsFileItem

ApacheCommonsのFileItem.get(),FileItem.getString() は使用しない

// NG
private String doSomething(FileItem fileItem) {
    return fileItem.getString();
}

// OK
private InputStream doSomething(FileItem fileItem) {
    return fileItem.getInputStream();
}

ルール設定例

<rule ref="category/java/performance.xml/UseIOStreamsWithApacheCommonsFileItem" />

UselessStringValueOf

不必要なString.valueOf()がないか

// NG
String s = "hello " + String.valueOf("world");

// OK
String s = "hello " + "world";

ルール設定例

<rule ref="category/java/performance.xml/UselessStringValueOf" />

UseStringBufferForStringAppends

文字列を+=で連結しない

// NG
String s = "hello ";
s += "world";

// OK
StringBuffer buffer = new StringBuffer("hello ");
buffer.append("world");

ルール設定例

<rule ref="category/java/performance.xml/UseStringBufferForStringAppends" />

UseStringBufferLength

StringBufferの長さを求める時はStringBuffer.length()を使用する

// NG
if (buffer.toString().length() == 0) {
}

// OK
if (buffer.length() == 0) {
}

ルール設定例

<rule ref="category/java/performance.xml/UseStringBufferLength" />

他のカテゴリのルールもまとめています。

Best Practiceカテゴリのまとめはこちら: olafnosuke.hatenablog.com

Code Styleカテゴリのまとめはこちら: olafnosuke.hatenablog.com

Designカテゴリのまとめはこちら: olafnosuke.hatenablog.com

Documentationカテゴリのまとめはこちら: olafnosuke.hatenablog.com

Error Proneカテゴリのまとめはこちら: olafnosuke.hatenablog.com

Multithreadingカテゴリのまとめはこちら: olafnosuke.hatenablog.com

Securityカテゴリのまとめはこちら: olafnosuke.hatenablog.com