Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors. Avoid assignments in operands; this can make code more complicated and harder to read. 3 Identifies a possible unsafe usage of a static field. 3 Methods such as getDeclaredConstructors(), getDeclaredConstructor(Class[]) and setAccessible(), as the interface PrivilegedAction, allow for the runtime alteration of variable, class, or method visibility, even if they are private. This violates the principle of encapsulation. 3 Use of the term 'assert' will conflict with newer versions of Java since it is a reserved word. 2 //VariableDeclaratorId[@Image='assert'] Using a branching statement as the last part of a loop may be a bug, and/or is confusing. Ensure that the usage is not a bug, or consider using another approach. 2 25) { break; } } ]]> The method Object.finalize() is called by the garbage collector on an object when garbage collection determines that there are no more references to the object. It should not be invoked by application logic. Note that Oracle has declared Object.finalize() as deprecated since JDK 9. 3 Code should never throw NullPointerExceptions under normal circumstances. A catch block may hide the original error, causing other, more subtle problems later on. 3 Catching Throwable errors is not recommended since its scope is very broad. It includes runtime issues such as OutOfMemoryError that should be exposed and managed separately. 3 One might assume that the result of "new BigDecimal(0.1)" is exactly equal to 0.1, but it is actually equal to .1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding. The (String) constructor, on the other hand, is perfectly predictable: 'new BigDecimal("0.1")' is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one. 3 Code containing duplicate String literals can usually be improved by declaring the String as a constant field. 3 Use of the term 'enum' will conflict with newer versions of Java since it is a reserved word. 2 //VariableDeclaratorId[@Image='enum'] It can be confusing to have a field name with the same name as a method. While this is permitted, having information (field) and actions (method) is not clear naming. Developers versed in Smalltalk often prefer this approach as the methods denote accessor methods. 3 It is somewhat confusing to have a field name matching the declaring class name. This probably means that type and/or field names should be chosen more carefully. 3 Each caught exception type should be handled in its own catch clause. 3 Avoid using hard-coded literals in conditional statements. By declaring them as static variables or private members with descriptive names maintainability is enhanced. By default, the literals "-1" and "0" are ignored. More exceptions can be defined with the property "ignoreMagicNumbers". 3 = 0) { } // alternative approach if (aDouble > 0.0) {} // magic number 0.0 if (aDouble >= Double.MIN_VALUE) {} // preferred approach } ]]> Statements in a catch block that invoke accessors on the exception without using the information only add to code size. Either remove the invocation, or use the return result. 2 The use of multiple unary operators may be problematic, and/or confusing. Ensure that the intended usage is not a bug, or consider simplifying the expression. 2 Integer literals should not start with zero since this denotes that the rest of literal will be interpreted as an octal value. 3 Avoid equality comparisons with Double.NaN. Due to the implicit lack of representation precision when comparing floating point numbers these are likely to cause logic errors. 3 If a class is a bean, or is referenced by a bean directly or indirectly it needs to be serializable. Member variables need to be marked as transient, static, or have accessor methods in the class. Marking variables as transient is the safest and easiest modification. Accessor methods should follow the Java naming conventions, i.e. for a variable named foo, getFoo() and setFoo() accessor methods should be provided. 3 The null check is broken since it will throw a NullPointerException itself. It is likely that you used || instead of && or vice versa. 2 Super should be called at the start of the method 3 Super should be called at the end of the method 3 The skip() method may skip a smaller number of bytes than requested. Check the returned value to find out if it was the case or not. 3 When deriving an array of a specific class from your Collection, one should provide an array of the same class as the parameter of the toArray() method. Doing otherwise you will will result in a ClassCastException. 3 The java Manual says "By convention, classes that implement this interface should override Object.clone (which is protected) with a public method." 3 The method clone() should only be implemented if the class implements the Cloneable interface with the exception of a final method that only throws CloneNotSupportedException. The rule can also detect, if the class implements or extends a Cloneable class. 3 If a class implements cloneable the return type of the method clone() must be the class name. That way, the caller of the clone method doesn't need to cast the returned clone to the correct type. Note: This is only possible with Java 1.5 or higher. 3 The method clone() should throw a CloneNotSupportedException. 3 Ensure that resources (like Connection, Statement, and ResultSet objects) are always closed after use. 3 Use equals() to compare object references; avoid comparing them with ==. 3 Calling overridable methods during construction poses a risk of invoking methods on an incompletely constructed object and can be difficult to debug. It may leave the sub-class unable to construct its superclass or forced to replicate the construction process completely within itself, losing the ability to call super(). If the default constructor contains a call to an overridable method, the subclass may be completely uninstantiable. Note that this includes method calls throughout the control flow graph - i.e., if a constructor Foo() calls a private method bar() that calls a public method buz(), this denotes a problem. 1 The dataflow analysis tracks local definitions, undefinitions and references to variables on different paths on the data flow. From those informations there can be found various problems. 1. UR - Anomaly: There is a reference to a variable that was not defined before. This is a bug and leads to an error. 2. DU - Anomaly: A recently defined variable is undefined. These anomalies may appear in normal source text. 3. DD - Anomaly: A recently defined variable is redefined. This is ominous but don't have to be a bug. 5 dd-anomaly foo(buz); buz = 2; } // buz is undefined when leaving scope -> du-anomaly ]]> Calls to System.gc(), Runtime.getRuntime().gc(), and System.runFinalization() are not advised. Code should have the same behavior whether the garbage collection is disabled using the option -Xdisableexplicitgc or not. Moreover, "modern" jvms do a very good job handling garbage collections. If memory usage issues unrelated to memory leaks develop within an application, it should be dealt with JVM options rather than within the code itself. 2 Web applications should not call System.exit(), since only the web container or the application server should stop the JVM. This rule also checks for the equivalent call Runtime.getRuntime().exit(). 3 Extend Exception or RuntimeException instead of Throwable. 3 Use Environment.getExternalStorageDirectory() instead of "/sdcard" 3 //Literal[starts-with(@Image,'"/sdcard')] Throwing exceptions within a 'finally' block is confusing since they may mask other exceptions or code defects. Note: This is a PMD implementation of the Lint4j rule "A throw in a finally block" 4 //FinallyStatement[descendant::ThrowStatement] Avoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change. 4 Don't use floating point for loop indices. If you must use floating point, use double unless you're certain that float provides enough precision and you have a compelling performance need (space or time). 3 Empty Catch Block finds instances where an exception is caught, but nothing is done. In most circumstances, this swallows an exception which should either be acted on or reported. 3 Empty finalize methods serve no purpose and should be removed. Note that Oracle has declared Object.finalize() as deprecated since JDK 9. 3 Empty finally blocks serve no purpose and should be removed. 3 Empty If Statement finds instances where a condition is checked but nothing is done about it. 3 Empty initializers serve no purpose and should be removed. 3 //Initializer/Block[count(*)=0] Empty block statements serve no purpose and should be removed. 3 //BlockStatement/Statement/Block[count(*) = 0] An empty statement (or a semicolon by itself) that is not used as the sole body of a 'for' or 'while' loop is probably a bug. It could also be a double semicolon, which has no purpose and should be removed. 3 Empty switch statements serve no purpose and should be removed. 3 //SwitchStatement[count(*) = 1] Empty synchronized blocks serve no purpose and should be removed. 3 //SynchronizedStatement/Block[1][count(*) = 0] Avoid empty try blocks - what's the point? 3 Empty While Statement finds all instances where a while statement does nothing. If it is a timing loop, then you should use Thread.sleep() for it; if it is a while loop that does a lot in the exit expression, rewrite it to make it clearer. 3 Tests for null should not use the equals() method. The '==' operator should be used instead. 1 If the finalize() is implemented, its last action should be to call super.finalize. Note that Oracle has declared Object.finalize() as deprecated since JDK 9. 3 If the finalize() is implemented, it should do something besides just calling super.finalize(). Note that Oracle has declared Object.finalize() as deprecated since JDK 9. 3 Methods named finalize() should not have parameters. It is confusing and most likely an attempt to overload Object.finalize(). It will not be called by the VM. Note that Oracle has declared Object.finalize() as deprecated since JDK 9. 3 0]] ]]> When overriding the finalize(), the new method should be set as protected. If made public, other classes may invoke it at inappropriate times. Note that Oracle has declared Object.finalize() as deprecated since JDK 9. 3 Avoid idempotent operations - they have no effect. 3 There is no need to import a type that lives in the same package. 3 Avoid instantiating an object just to call getClass() on it; use the .class public member instead. 4 Check for messages in slf4j loggers with non matching number of arguments and placeholders. 5 Avoid jumbled loop incrementers - its usually a mistake, and is confusing even if intentional. 3 Some JUnit framework methods are easy to misspell. 3 The suite() method in a JUnit test needs to be both public and static. 3 In most cases, the Logger reference can be declared as static and final. 2 Non-constructor methods should not have the same name as the enclosing class. 3 The null check here is misplaced. If the variable is null a NullPointerException will be thrown. Either the check is useless (the variable will never be "null") or it is incorrect. 3 Switch statements without break or return statements for each case option may indicate problematic behaviour. Empty cases are ignored as these indicate an intentional fall-through. 3 Serializable classes should provide a serialVersionUID field. The serialVersionUID field is also needed for abstract base classes. Each individual class in the inheritance chain needs an own serialVersionUID field. See also [Should an abstract class have a serialVersionUID](https://stackoverflow.com/questions/893259/should-an-abstract-class-have-a-serialversionuid). 3 A class that has private constructors and does not have any static methods or fields cannot be used. 3 Normally only one logger is used in each class. 2 A non-case label (e.g. a named break/continue label) was present in a switch statement. This legal, but confusing. It is easy to mix up the case labels and the non-case labels. 3 //SwitchStatement//BlockStatement/Statement/LabeledStatement A non-static initializer block will be called any time a constructor is invoked (just prior to invoking the constructor). While this is a valid language construct, it is rarely used and is confusing. 3 Assigning a "null" to a variable (outside of its declaration) is usually bad form. Sometimes, this type of assignment is an indication that the programmer doesn't completely understand what is going on in the code. NOTE: This sort of assignment may used in some cases to dereference objects and encourage garbage collection. 3 Override both public boolean Object.equals(Object other), and public int Object.hashCode(), or override neither. Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly delegating to your superclass. 3 Object clone() should be implemented with super.clone(). 2 0 ] ]]> A logger should normally be defined private static final and be associated with the correct class. Private final Log log; is also allowed for rare cases where loggers need to be passed around, with the restriction that the logger needs to be passed into the constructor. 3 For any method that returns an array, it is a better to return an empty array rather than a null reference. This removes the need for null checking all results and avoids inadvertent NullPointerExceptions. 1 Avoid returning from a finally block, this can discard exceptions. 3 //FinallyStatement//ReturnStatement except //FinallyStatement//(MethodDeclaration|LambdaExpression)//ReturnStatement Be sure to specify a Locale when creating SimpleDateFormat instances to ensure that locale-appropriate formatting is used. 3 Some classes contain overloaded getInstance. The problem with overloaded getInstance methods is that the instance created using the overloaded method is not cached and so, for each call and new objects will be created for every invocation. 2 Some classes contain overloaded getInstance. The problem with overloaded getInstance methods is that the instance created using the overloaded method is not cached and so, for each call and new objects will be created for every invocation. 2 According to the J2EE specification, an EJB should not have any static fields with write access. However, static read-only fields are allowed. This ensures proper behavior especially when instances are distributed by the container on several JREs. 3 Individual character values provided as initialization arguments will be converted into integers. This can lead to internal buffer sizes that are larger than expected. Some examples: ``` new StringBuffer() // 16 new StringBuffer(6) // 6 new StringBuffer("hello world") // 11 + 16 = 27 new StringBuffer('A') // chr(A) = 65 new StringBuffer("A") // 1 + 16 = 17 new StringBuilder() // 16 new StringBuilder(6) // 6 new StringBuilder("hello world") // 11 + 16 = 27 new StringBuilder('C') // chr(C) = 67 new StringBuilder("A") // 1 + 16 = 17 ``` 4 The method name and parameter number are suspiciously close to equals(Object), which can denote an intention to override the equals(Object) method. 2 The method name and return type are suspiciously close to hashCode(), which may denote an intention to override the hashCode() method. 3 A suspicious octal escape sequence was found inside a String literal. The Java language specification (section 3.10.6) says an octal escape sequence inside a literal String shall consist of a backslash followed by: OctalDigit | OctalDigit OctalDigit | ZeroToThree OctalDigit OctalDigit Any octal escape sequence followed by non-octal digits can be confusing, e.g. "\038" is interpreted as the octal escape sequence "\03" followed by the literal character "8". 3 Test classes end with the suffix Test. Having a non-test class with that name is not a good practice, since most people will assume it is a test case. Test classes have test methods named testXXX. 3 Do not use "if" statements whose conditionals are always true or always false. 3 A JUnit test assertion with a boolean literal is unnecessary since it always will evaluate to the same thing. Consider using flow control (in case of assertTrue(false) or similar) or simply removing statements like assertTrue(true) and assertFalse(false). If you just want a test to halt after finding an error, use the fail() method and provide an indication message of why it did. 3 Using equalsIgnoreCase() is faster than using toUpperCase/toLowerCase().equals() 3 Avoid the use temporary objects when converting primitives to Strings. Use the static conversion methods on the wrapper classes instead. 3 After checking an object reference for null, you should invoke equals() on that object rather than passing it to another object's equals() method. 3 To make sure the full stacktrace is printed out, use the logging statement with two arguments: a String and a Throwable. 3 Using '==' or '!=' to compare strings only works if intern version is used on both sides. Use the equals() method instead. 3 An operation on an Immutable object (String, BigDecimal or BigInteger) won't change the object itself since the result of the operation is a new object. Therefore, ignoring the operation result is an error. 3 When doing String.toLowerCase()/toUpperCase() conversions, use Locales to avoids problems with languages that have unusual conventions, i.e. Turkish. 3 In J2EE, the getClassLoader() method might not work as expected. Use Thread.currentThread().getContextClassLoader() instead. 3 //PrimarySuffix[@Image='getClassLoader']