Rules that flag suboptimal code. The conversion of literals to strings by concatenating them with empty strings is inefficient. It is much better to use one of the type-specific toString() methods instead. 3 Avoid concatenating characters as strings in StringBuffer/StringBuilder.append methods. 3 Instead of manually copying data between two arrays, use the efficient Arrays.copyOf or System.arraycopy method instead. 3 The FileInputStream and FileOutputStream classes contains a finalizer method which will cause garbage collection pauses. See [JDK-8080225](https://bugs.openjdk.java.net/browse/JDK-8080225) for details. The FileReader and FileWriter constructors instantiate FileInputStream and FileOutputStream, again causing garbage collection issues while finalizer methods are called. * Use `Files.newInputStream(Paths.get(fileName))` instead of `new FileInputStream(fileName)`. * Use `Files.newOutputStream(Paths.get(fileName))` instead of `new FileOutputStream(fileName)`. * Use `Files.newBufferedReader(Paths.get(fileName))` instead of `new FileReader(fileName)`. * Use `Files.newBufferedWriter(Paths.get(fileName))` instead of `new FileWriter(fileName)`. Please note, that the `java.nio` API does not throw a `FileNotFoundException` anymore, instead it throws a `NoSuchFileException`. If your code dealt explicitly with a `FileNotFoundException`, then this needs to be adjusted. Both exceptions are subclasses of `IOException`, so catching that one covers both. 1 New objects created within loops should be checked to see if they can created outside them and reused. 3 Java uses the 'short' type to reduce memory usage, not to optimize calculation. In fact, the JVM does not have any arithmetic capabilities for the short type: the JVM must convert the short into an int, do the proper calculation and convert the int back to a short. Thus any storage gains found through use of the 'short' type may be offset by adverse impacts on performance. 1 Don't create instances of already existing BigInteger (BigInteger.ZERO, BigInteger.ONE) and for Java 1.5 onwards, BigInteger.TEN and BigDecimal (BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN) 3 Avoid instantiating Boolean objects; you can reference Boolean.TRUE, Boolean.FALSE, or call Boolean.valueOf() instead. Note that new Boolean() is deprecated since JDK 9 for that reason. 2 Calling new Byte() causes memory allocation that can be avoided by the static Byte.valueOf(). It makes use of an internal cache that recycles earlier instances making it more memory efficient. Note that new Byte() is deprecated since JDK 9 for that reason. 2 Consecutive calls to StringBuffer/StringBuilder .append should be chained, reusing the target object. This can improve the performance by producing a smaller bytecode, reducing overhead and improving inlining. A complete analysis can be found [here](https://github.com/pmd/pmd/issues/202#issuecomment-274349067) 3 Consecutively calling StringBuffer/StringBuilder.append(...) with literals should be avoided. Since the literals are constants, they can already be combined into a single String literal and this String can be appended in a single method call. 3 3 0) { doSomething(); } } ]]> Avoid concatenating non-literals in a StringBuffer constructor or append() since intermediate buffers will need to be be created and destroyed by the JVM. 3 Failing to pre-size a StringBuffer or StringBuilder properly could cause it to re-size many times during runtime. This rule attempts to determine the total number the characters that are actually passed into StringBuffer.append(), but represents a best guess "worst case" scenario. An empty StringBuffer/StringBuilder constructor initializes the object to 16 characters. This default is assumed if the length of the constructor can not be determined. 3 Calling new Integer() causes memory allocation that can be avoided by the static Integer.valueOf(). It makes use of an internal cache that recycles earlier instances making it more memory efficient. Note that new Integer() is deprecated since JDK 9 for that reason. 2 Calling new Long() causes memory allocation that can be avoided by the static Long.valueOf(). It makes use of an internal cache that recycles earlier instances making it more memory efficient. Note that new Long() is deprecated since JDK 9 for that reason. 2 Calls to a collection's `toArray(E[])` method should specify a target array of zero size. This allows the JVM to optimize the memory allocation and copying as much as possible. Previous versions of this rule (pre PMD 6.0.0) suggested the opposite, but current JVM implementations perform always better, when they have full control over the target array. And allocation an array via reflection is nowadays as fast as the direct allocation. See also [Arrays of Wisdom of the Ancients](https://shipilev.net/blog/2016/arrays-wisdom-ancients/) Note: If you don't need an array of the correct type, then the simple `toArray()` method without an array is faster, but returns only an array of type `Object[]`. 3 foos = getFoos(); // much better; this one allows the jvm to allocate an array of the correct size and effectively skip // the zeroing, since each array element will be overridden anyways Foo[] fooArray = foos.toArray(new Foo[0]); // inefficient, the array needs to be zeroed out by the jvm before it is handed over to the toArray method Foo[] fooArray = foos.toArray(new Foo[foos.size()]); ]]> Java will initialize fields with known default values so any explicit initialization of those same defaults is redundant and results in a larger class file (approximately three additional bytecode instructions per field). 3 Since it passes in a literal of length 1, calls to (string).startsWith can be rewritten using (string).charAt(0) at the expense of some readability. 3 Calling new Short() causes memory allocation that can be avoided by the static Short.valueOf(). It makes use of an internal cache that recycles earlier instances making it more memory efficient. Note that new Short() is deprecated since JDK 9 for that reason. 2 Avoid instantiating String objects; this is usually unnecessary since they are immutable and can be safely shared. 2 Avoid calling toString() on objects already known to be string instances; this is unnecessary. 3 Switch statements are intended to be used to support complex branching behaviour. Using a switch for only a few cases is ill-advised, since switches are not as easy to understand as if-then statements. In these cases use the if-then statement to increase code readability. 3 Most wrapper classes provide static conversion methods that avoid the need to create intermediate objects just to create the primitive forms. Using these avoids the cost of creating objects that also need to be garbage-collected later. 3 ArrayList is a much better Collection implementation than Vector if thread-safe operation is not required. 3 0] //AllocationExpression/ClassOrInterfaceType [@Image='Vector' or @Image='java.util.Vector'] ]]> (Arrays.asList(...)) if that is inconvenient for you (e.g. because of concurrent access). ]]> 3 l= new ArrayList<>(100); for (int i=0; i< 100; i++) { l.add(ints[i]); } for (int i=0; i< 100; i++) { l.add(a[i].toString()); // won't trigger the rule } } } ]]> Use String.indexOf(char) when checking for the index of a single character; it executes faster. 3 No need to call String.valueOf to append to a string; just use the valueOf() argument directly. 3 The use of the '+=' operator for appending strings causes the JVM to create and use an internal StringBuffer. If a non-trivial number of these concatenations are being used then the explicit use of a StringBuilder or threadsafe StringBuffer is recommended to avoid this. 3 Use StringBuffer.length() to determine StringBuffer length rather than using StringBuffer.toString().equals("") or StringBuffer.toString().length() == ... 3