Rules

Close
Name Severity Description
RuleAwtPeer Severe java.awt.peer interfaces were designed to handle platform-specific graphics issues in Java. Since Java is meant to be platform-independent, using java.awt.peer directly is forbidden.
Example

public static void main( String[] args ) {
Frame frame = new Frame( "Peers" );
Button button = new Button( "Hello World!" );
frame.setLayout( new GridLayout() );
frame.add( button );
frame.setVisible( true );
ButtonPeer peer = (ButtonPeer)button.getPeer();
peer.dispose();
}

Solution
Remove calls to peer objects. Use java.awt or javax.swing interfaces and classes instead.

public static void main( String[] args ) {
Frame frame = new Frame( "Peers" );
Button button = new Button( "Hello World!" );
frame.setLayout( new GridLayout() );
frame.add( button );
frame.setVisible( true );
}

RuleCloneableSuperClone Severe Calling super.clone() from the clone() is essential in order to ensure that a complete copy of the object is created. Failure to do so is likely to result in a NullPointerException thrown later or an unexpected object state in the course of program execution.
Example

public static void main (String[] args){
double x = 3.1;
int i = (int)x;
System.out.println(i);
}

Solution
Change the underlying data type to be lower precision.

public static void main (String[] args){
int i = 3;
System.out.println(i);
}

Solution
Update the calculation to operate on the higher precision data type.

public static void main (String[] args){
double x = 3.1;
System.out.println( x );
}

RuleComparisonEqualsHashCode Severe java.lang.Object.equals() and java.lang.Object.hashCode() are designed to work together for fast hash lookups. The value returned from the hashCode() is used to calculate the index of the bucket in the hash table array. The equals() is then used to find the actual matching object among all the objects that sit in the same bucket.
Example

public EqualsHashCode_Example(String s){
super();
this .s = s;
}

public int hashCode(){
return s.hashCode();
}

private String s = ""; //$NON-NLS-1$

Solution
Implement both hashCode() and equals().

public EqualsHashCode_Solution(String s){
super();
this .s = s;
}

public int hashCode(){
return s.hashCode();
}

public boolean equals( Object other ) {
return ( other instanceof EqualsHashCode_Solution ) &&
((EqualsHashCode_Solution)other).s.equals( s );
}

private String s = ""; //$NON-NLS-1$

RuleComparisonClassNameComparison Severe Using java.lang.Class.getName() bypasses the standard way of comparing classes and may lead to problems, including security violations. A standard way of comparing class objects is to use java.lang.Class.equals(). This method bases the class equality on all aspects of the class, for example, the ClassLoader that loaded the class.
Example

public static void main(String[] args){
Class c1 = null;
Class c2 = null;
if ( args.length > 1){
try {
c1 = Class.forName( args[0] );
c2 = Class.forName( args[1] );
System.out.println( c1.getName().equals(c2.getName()));
} catch ( ClassNotFoundException e){
e.printStackTrace();
}
}
}

Solution
Change the code to use java.lang.Class.equals() to establish class equality.

public static void main(String[] args){
Class c1 = null;
Class c2 = null;
if ( args.length > 1){
try {
c1 = Class.forName( args[0] );
c2 = Class.forName( args[1] );
System.out.println( c1.equals( c2 ) );
} catch ( ClassNotFoundException e){
e.printStackTrace();
}
}
}

RuleNullEmptyArray Severe Returning null instead of empty array is error-prone in majority of cases. By Java convention, the user of the interface that returns array does not have to check for null, but should assume the zero length array. Violating this convention is likely to result in null pointer exceptions.
Example

public NullEmptyArray_Example() {
super();
}

public void addValue( Integer value ) {
if ( values == null ) {
values = new ArrayList(10);
}
values.add( value );
}

public Integer[] getValues() {
if ( values == null ) {
return null;
}
return (Integer[])values.toArray( new Integer[ 0 ] );
}

private List values;

public static void main( String[] args ) {
NullEmptyArray_Example example = new NullEmptyArray_Example();
Integer[] values = example.getValues();
for ( int i = 0; i < values.length; i++ ) {
System.out.println( values[ i ] );
}
}

Solution
Return zero length array instead of null.

public NullEmptyArray_Solution() {
super();
}

public void addValue( Integer value ) {
if ( values == null ) {
values = new ArrayList(10);
}
values.add( value );
}

public Integer[] getValues() {
return ( values == null ) ? new Integer[ 0 ] :
(Integer[])values.toArray( new Integer[ 0 ] );
}

private List values;

public static void main( String[] args ) {
NullEmptyArray_Solution example = new NullEmptyArray_Solution();
Integer[] values = example.getValues();
for ( int i = 0; i < values.length; i++ ) {
System.out.println( values[ i ] );
}
}

RuleSerializationReadWriteObject Severe Declaring readObject() and writeObject() private is essential to follow Java serialization protocol. Failing to do so may lead to security problems in the application.
Example

public static class SerializableObject implements Serializable{

public void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
}

public void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject();
}

static final long serialVersionUID = 123;
}

Solution
Declare readObject() and writeObject() private.

public static class SerializableObject implements Serializable{

private void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
}

private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject();
}

static final long serialVersionUID = 123;
}

RuleSerializationResolveObject Severe Declaring resolveObject() protected is essential in order to follow Java serialization protocol. Failing to do so may lead to security problems in the application.
Example


public class ResolveObject implements Serializable {

public static ResolveObject getInstance() {
return INSTANCE;
}

private static final ResolveObject INSTANCE = new ResolveObject();

private ResolveObject() {
super();
}

public Object readResolve() throws ObjectStreamException {
return INSTANCE;
}

static final long serialVersionUID = 123;

}
Solution
Declare resolveObject() and writeReplace() protected.


public class ResolveObject implements Serializable {

public static ResolveObject getInstance() {
return INSTANCE;
}

private static final ResolveObject INSTANCE = new ResolveObject();

private ResolveObject() {}

private Object readResolve() throws ObjectStreamException {
return INSTANCE;
}

static final long serialVersionUID = 123;


}
RuleSerializationSerializableField Severe Every field of a serializable class must be either serializable or transient. Declaring non-transient fields of non-serializable type inside of a serializable class will result in an exception thrown during the serialization.
Example


public static final class SomeType {}

public class SerializableField implements Serializable {
public SerializableField( String str ) {
super();
this .str = str;
nonser = new SomeType();
}

private String str;
private SomeType nonser;

private static final long serialVersionUID = 123;
}


Solution
Make the field type serializable.

public static final class SomeType implements Serializable {}

public class SerializableField() implements Serializable {

public SerializableField( String str ) {
super();
this .str = str;
nonser = new SomeType();
}

private String str;
private SomeType nonser;

private static final long serialVersionUID = 123;
}

Solution
Declare the field transient.

public static final class SomeType {}

public class SerializableField implements Serializable {

public SerializableField( String str ) {
super();
this .str = str;
nonser = new SomeType();
}

private String str;
private transient SomeType nonser;

private static final long serialVersionUID = 123;


}

nonsynchronizednotify Severe A thread that is currently locking sections of the code that use a common lock should invoke java.lang.Object.notify() to tell the blocking thread to resume processing. Calling notify() from non-synchronized blocks will result in IllegalMonitorStateException, because no lock has been obtained.
Example

public static void main( String[] args ){
Lock lock = new Lock();
final Consumer consumer = new Consumer( lock );
final Producer producer = new Producer( lock );

(new Thread( new Runnable() {
public void run() {
consumer.consume();
}
})).start();


(new Thread( new Runnable() {
public void run() {
producer.produce();
}
})).start();
}

public static final class Lock {
public Lock() {
super();
lock();
}
public boolean isAvailable() {
return available;
}
public void lock() {
available = false;
}
public void unlock() {
available = true;
}
private boolean available = false;
}

public static final class Consumer {
public Consumer( Lock lock ) {
this .lock = lock;
}

public void consume() {
System.out.println( "Consumer: consume was called" ); //$NON-NLS-1$
synchronized ( lock ) {
while ( !lock.isAvailable() ) {
System.out.println( "Consumer: waiting..." ); //$NON-NLS-1$
try {
lock.wait();
} catch (InterruptedException e) {}
}
}
System.out.println( "Consumer: exiting" ); //$NON-NLS-1$
}

private Lock lock;
}

public static final class Producer {
public Producer( Lock lock ) {
this .lock = lock;
}
public void produce() {
System.out.println( "Producer: produce was called" ); //$NON-NLS-1$
System.out.println( "Producer: unlocking..." ); //$NON-NLS-1$
lock.unlock();
lock.notify();
System.out.println( "Producer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}

Solution
Place the call to java.lang.Object.notify() inside of the synchronized block.

public static void main( String[] args ){
Lock lock = new Lock();
final Consumer consumer = new Consumer( lock );
final Producer producer = new Producer( lock );

(new Thread( new Runnable() {
public void run() {
consumer.consume();
}
})).start();


(new Thread( new Runnable() {
public void run() {
producer.produce();
}
})).start();
}

public static final class Lock {
public Lock() {
super();
lock();
}
public boolean isAvailable() {
return available;
}
public void lock() {
available = false;
}
public void unlock() {
available = true;
}
private boolean available = false;
}

public static final class Consumer {
public Consumer( Lock lock ) {
this .lock = lock;
}

public void consume() {
System.out.println( "Consumer: consume was called" ); //$NON-NLS-1$
synchronized ( lock ) {
while ( !lock.isAvailable() ) {
System.out.println( "Consumer: waiting..." ); //$NON-NLS-1$
try {
lock.wait();
} catch (InterruptedException e) {}
}
}
System.out.println( "Consumer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}

public static final class Producer {
public Producer( Lock lock ) {
this .lock = lock;
}
public void produce() {
System.out.println( "Producer: produce was called" ); //$NON-NLS-1$
System.out.println( "Producer: unlocking..." ); //$NON-NLS-1$
synchronized ( lock ) {
lock.unlock();
lock.notify();
}
System.out.println( "Producer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}

nonsynchronizednotifyall Severe A thread that is currently locking sections of the code that use common lock should invoke java.lang.Object.notifyAll() to tell the blocking threads to resume processing. Calling notify() from non-synchronized blocks will result in IllegalMonitorStateException, because no lock has been obtained.
Example

public static void main( String[] args ){
Lock lock = new Lock();
final Consumer consumer1 = new Consumer( lock, 1 );
final Consumer consumer2 = new Consumer( lock, 2 );
final Producer producer = new Producer( lock );

(new Thread( new Runnable() {
public void run() {
consumer1.consume();
}
})).start();

(new Thread( new Runnable() {
public void run() {
consumer2.consume();
}
})).start();

(new Thread( new Runnable() {
public void run() {
producer.produce();
}
})).start();
}

public static final class Lock {
public Lock() {
super();
lock();
}
public boolean isAvailable() {
return available;
}
public void lock() {
available = false;
}
public void unlock() {
available = true;
}
private boolean available = false;
}

public static final class Consumer {
public Consumer( Lock lock, int id ) {
this .lock = lock;
this .id = id;
}

public void consume() {
System.out.println( "Consumer " + id + ": consume was called" ); //$NON-NLS-1$ //$NON-NLS-2$
synchronized ( lock ) {
while ( !lock.isAvailable() ) {
System.out.println( "Consumer" + id + ": waiting..." ); //$NON-NLS-1$ //$NON-NLS-2$
try {
lock.wait();
} catch (InterruptedException e) {}
}
}
System.out.println( "Consumer" + id + ": exiting" ); //$NON-NLS-1$ //$NON-NLS-2$
}

private Lock lock;
private int id;
}

public static final class Producer {
public Producer( Lock lock ) {
this .lock = lock;
}
public void produce() {
System.out.println( "Producer: produce was called" ); //$NON-NLS-1$
System.out.println( "Producer: unlocking..." ); //$NON-NLS-1$
lock.unlock();
lock.notifyAll();
System.out.println( "Producer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}

Solution
Place the call to java.lang.Object.notifyAll() inside of the synchronized block.

public static void main( String[] args ){
Lock lock = new Lock();
final Consumer consumer1 = new Consumer( lock, 1 );
final Consumer consumer2 = new Consumer( lock, 2 );
final Producer producer = new Producer( lock );

(new Thread( new Runnable() {
public void run() {
consumer1.consume();
}
})).start();

(new Thread( new Runnable() {
public void run() {
consumer2.consume();
}
})).start();

(new Thread( new Runnable() {
public void run() {
producer.produce();
}
})).start();
}

public static final class Lock {
public Lock() {
super();
lock();
}
public boolean isAvailable() {
return available;
}
public void lock() {
available = false;
}
public void unlock() {
available = true;
}
private boolean available = false;
}

public static final class Consumer {
public Consumer( Lock lock, int id ) {
this .lock = lock;
this .id = id;
}

public void consume() {
System.out.println( "Consumer " + id + ": consume was called" ); //$NON-NLS-1$ //$NON-NLS-2$
synchronized ( lock ) {
while ( !lock.isAvailable() ) {
System.out.println( "Consumer" + id + ": waiting..." ); //$NON-NLS-1$ //$NON-NLS-2$
try {
lock.wait();
} catch (InterruptedException e) {}
}
}
System.out.println( "Consumer" + id + ": exiting" ); //$NON-NLS-1$ //$NON-NLS-2$
}

private Lock lock;
private int id;
}

public static final class Producer {
public Producer( Lock lock ) {
this .lock = lock;
}
public void produce() {
System.out.println( "Producer: produce was called" ); //$NON-NLS-1$
System.out.println( "Producer: unlocking..." ); //$NON-NLS-1$
synchronized ( lock ) {
lock.unlock();
lock.notifyAll();
}
System.out.println( "Producer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}

nonsynchronizedwait Severe A thread that needs to wait on a common lock should invoke java.lang.Object.wait() to tell the JVM to suspend its processing until it receives notification from another thread. Calling wait() from non-synchronized blocks will result in IllegalMonitorStateException, because no lock has been obtained.
Example

public static void main( String[] args ){
Lock lock = new Lock();
final Consumer consumer = new Consumer( lock );
final Producer producer = new Producer( lock );

(new Thread( new Runnable() {
public void run() {
consumer.consume();
}
})).start();


(new Thread( new Runnable() {
public void run() {
producer.produce();
}
})).start();
}

public static final class Lock {
public Lock() {
super();
lock();
}
public boolean isAvailable() {
return available;
}
public void lock() {
available = false;
}
public void unlock() {
available = true;
}
private boolean available = false;
}

public static final class Consumer {
public Consumer( Lock lock ) {
this .lock = lock;
}

public void consume() {
System.out.println( "Consumer: consume was called" ); //$NON-NLS-1$
while ( !lock.isAvailable() ) {
System.out.println( "Consumer: waiting..." ); //$NON-NLS-1$
try {
lock.wait();
} catch (InterruptedException e) {}
}
System.out.println( "Consumer: exiting" ); //$NON-NLS-1$
}

private Lock lock;
}

public static final class Producer {
public Producer( Lock lock ) {
this .lock = lock;
}
public void produce() {
System.out.println( "Producer: produce was called" ); //$NON-NLS-1$
System.out.println( "Producer: unlocking..." ); //$NON-NLS-1$
synchronized ( lock ) {
lock.unlock();
lock.notifyAll();
}
System.out.println( "Producer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}

Solution
Place the call to java.lang.Object.wait() inside of the synchronized block.

public static void main( String[] args ){
Lock lock = new Lock();
final Consumer consumer = new Consumer( lock );
final Producer producer = new Producer( lock );

(new Thread( new Runnable() {
public void run() {
consumer.consume();
}
})).start();


(new Thread( new Runnable() {
public void run() {
producer.produce();
}
})).start();
}

public static final class Lock {
public Lock() {
super();
lock();
}
public boolean isAvailable() {
return available;
}
public void lock() {
available = false;
}
public void unlock() {
available = true;
}
private boolean available = false;
}

public static final class Consumer {
public Consumer( Lock lock ) {
this .lock = lock;
}

public void consume() {
System.out.println( "Consumer: consume was called" ); //$NON-NLS-1$
synchronized ( lock ) {
while ( !lock.isAvailable() ) {
System.out.println( "Consumer: waiting..." ); //$NON-NLS-1$
try {
lock.wait();
} catch (InterruptedException e) {}
}
}
System.out.println( "Consumer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}

public static final class Producer {
public Producer( Lock lock ) {
this .lock = lock;
}
public void produce() {
System.out.println( "Producer: produce was called" ); //$NON-NLS-1$
System.out.println( "Producer: unlocking..." ); //$NON-NLS-1$
synchronized ( lock ) {
lock.unlock();
lock.notifyAll();
}
System.out.println( "Producer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}


destroy Severe java.lang.Thread.destroy() method destroys the thread without releasing the monitors or doing a cleanup. Calling this method is likely to lead to synchronization and resource management issues.
Example


public static void main( String[] args ){
Lock lock = new Lock();
final Consumer consumer = new Consumer( lock );
final Producer producer = new Producer( lock );

(new Thread( new Runnable() {
public void run() {
consumer.consume();
}
})).start();


(new Thread( new Runnable() {
public void run() {
producer.produce();
}
})).start();
}

public static final class Lock {
public Lock() {
super();
lock();
}
public boolean isAvailable() {
return available;
}
public void lock() {
available = false;
}
public void unlock() {
available = true;
}
private boolean available = false;
}

public static final class Consumer {
public Consumer( Lock lock ) {
this .lock = lock;
}

public void consume() {
System.out.println( "Consumer: consume was called" ); //$NON-NLS-1$
synchronized ( lock ) {
while ( !lock.isAvailable() ) {
System.out.println( "Consumer: waiting..." ); //$NON-NLS-1$
try {
lock.wait();
} catch (InterruptedException e) {}
}
}
System.out.println( "Consumer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}

public static final class Producer {
public Producer( Lock lock ) {
this .lock = lock;
}
public void produce() {
System.out.println( "Producer: produce was called" ); //$NON-NLS-1$
synchronized ( lock ) {
Thread.currentThread().destroy();
}
System.out.println( "Producer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}


Solution
Do not call destroy(), rely on default thread termination.

public static void main( String[] args ){
Lock lock = new Lock();
final Consumer consumer = new Consumer( lock );
final Producer producer = new Producer( lock );

(new Thread( new Runnable() {
public void run() {
consumer.consume();
}
})).start();


(new Thread( new Runnable() {
public void run() {
producer.produce();
}
})).start();
}

public static final class Lock {
public Lock() {
super();
lock();
}
public boolean isAvailable() {
return available;
}
public void lock() {
available = false;
}
public void unlock() {
available = true;
}
private boolean available = false;
}

public static final class Consumer {
public Consumer( Lock lock ) {
this .lock = lock;
}

public void consume() {
System.out.println( "Consumer: consume was called" ); //$NON-NLS-1$
synchronized ( lock ) {
while ( !lock.isAvailable() ) {
System.out.println( "Consumer: waiting..." ); //$NON-NLS-1$
try {
lock.wait();
} catch (InterruptedException e) {}
}
}
System.out.println( "Consumer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}

public static final class Producer {
public Producer( Lock lock ) {
this .lock = lock;
}
public void produce() {
System.out.println( "Producer: produce was called" ); //$NON-NLS-1$
System.out.println( "Producer: unlocking..." ); //$NON-NLS-1$
synchronized ( lock ) {
lock.unlock();
lock.notifyAll();
}
System.out.println( "Producer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}


resume Severe The following is the extract from Java doc (copyright by Sun Microsystems): This method exists solely for use with suspend(), which has been deprecated because it is deadlock-prone.
Example

public static final Boolean lock = Boolean.TRUE;
public static boolean runCond = true;

public static void main( String[] args ) {
Runnable runnable = new Runnable() {
public void run() {
synchronized (lock){
while ( runCond ) {
System.out.println( "Hello World!" ); //$NON-NLS-1$
try { wait( 1000 ); } catch (InterruptedException e) {}
}
}
}
};
Thread thread = new Thread( runnable );
thread.start();
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
thread.suspend();
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
thread.resume();
runCond = false;
}

Solution
Remove the code that calls suspend/resume thread.
Use provided SuspendSafeRunnable.

public static abstract class SuspendSafeRunnable extends StopSafeRunnable {
public void doRun() {
checkForPause();
doWork();
}
public void suspend() {
synchronized ( lock ) {
suspended = true;
lock.notifyAll();
}
}
public void resume() {
synchronized ( lock ) {
suspended = false;
lock.notifyAll();
}
}
public boolean isPaused() {
return suspended;
}
protected abstract void doWork();

private void checkForPause() {
synchronized ( lock ) {
while ( suspended ) {
try {
lock.wait();
} catch (InterruptedException e) {}
}
}
}
private boolean suspended = false;
private Object lock = new Object();
}

public static void main( String[] args ) {
SuspendSafeRunnable runnable = new SuspendSafeRunnable() {
public void doWork() {
System.out.println( "Hello World!" ); //$NON-NLS-1$
try { Thread.sleep( 1000 ); } catch (InterruptedException e) {}
}
};
Thread thread = new Thread( runnable );
thread.start();
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
runnable.suspend();
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
runnable.resume();
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
runnable.stop();
}

stop Severe The following is the extract from Java doc (copyright by Sun Microsystems): This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior.
Example

public static final Boolean lock = Boolean.TRUE;

public static void main( String[] args ) {
Runnable runnable = new Runnable() {
public void run() {
synchronized (lock){
while ( true ) {
System.out.println( "Hello World!" ); //$NON-NLS-1$
try { wait( 1000 ); } catch (InterruptedException e) {}
}
}
}
};
Thread thread = new Thread( runnable );
thread.start();
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
thread.stop();
}

Solution
The following is the extract from Java doc (copyright by Sun Microsystems)
Many uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running.
The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. If the target thread waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait.
Use provided StopSafeRunnable.

public static abstract class StopSafeRunnable implements Runnable {
public final void run() {
while ( !stopped ) {
doRun();
}
}
public void stop() {
stopped = true;
}
public boolean isStopped() {
return stopped;
}
protected abstract void doRun();

private boolean stopped = false;
}

public static void main(String[] args) {
StopSafeRunnable runnable = new StopSafeRunnable() {
public void doRun() {
System.out.println( "Hello World" ); //$NON-NLS-1$
try { Thread.sleep( 1000 ); } catch (InterruptedException e) {}
}
};
Thread thread = new Thread( runnable );
thread.start();
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
runnable.stop();
}

suspend Severe The following is the extract from Java doc (copyright by Sun Microsystems): This method has been deprecated, as it is inherently deadlock-prone. If the target thread holds a lock on the monitor protecting a critical system resource when it is suspended, no thread can access this resource until the target thread is resumed. If the thread that would resume the target thread attempts to lock this monitor prior to calling resume, deadlock results. Such deadlocks typically manifest themselves as "frozen" processes.
Example

public static final Boolean lock = Boolean.TRUE;
public static boolean runCond = true;

public static void main( String[] args ) {
Runnable runnable = new Runnable() {
public void run() {
synchronized (lock){
while ( runCond ) {
System.out.println( "Hello World!" ); //$NON-NLS-1$
try { wait( 1000 ); } catch (InterruptedException e) {}
}
}
}
};
Thread thread = new Thread( runnable );
thread.start();
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
thread.suspend();
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
thread.resume();
runCond = false;
}
Solution
Remove the code that calls suspend/resume thread.
Use provided SuspendSafeRunnable.

public static abstract class SuspendSafeRunnable extends StopSafeRunnable {
public void doRun() {
checkForPause();
doWork();
}
public void suspend() {
synchronized ( lock ) {
suspended = true;
lock.notifyAll();
}
}
public void resume() {
synchronized ( lock ) {
suspended = false;
lock.notifyAll();
}
}
public boolean isPaused() {
return suspended;
}
protected abstract void doWork();

private void checkForPause() {
synchronized ( lock ) {
while ( suspended ) {
try {
lock.wait();
} catch (InterruptedException e) {}
}
}
}
private boolean suspended = false;
private Object lock = new Object();
}

public static void main( String[] args ) {
SuspendSafeRunnable runnable = new SuspendSafeRunnable() {
public void doWork() {
System.out.println( "Hello World!" ); //$NON-NLS-1$
try { Thread.sleep( 1000 ); } catch (InterruptedException e) {}
}
};
Thread thread = new Thread( runnable );
thread.start();
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
runnable.suspend();
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
runnable.resume();
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
runnable.stop();
}

overridesynchronizable Severe Synchronized methods use this as a lock to prevent other methods and blocks with the same lock from parallel execution. Overriding the synchronized method with a non-synchronized one introduces the potential for problems and data inconsistency in the base class.
Example

public static class Base {
public synchronized void setValue( int value ) {
try { Thread.sleep( 1000 ); } catch (InterruptedException e) {}
this .value = value;
}
public synchronized int getValue() {
return value;
}
protected int value = 0;
}

public static class Derived extends Base {
public int getValue() {
return this .value;
}

}

public static void main(String[] args) {
System.out.println( "Testing Base..." ); //$NON-NLS-1$
test( new Base() );
try { Thread.sleep( 5000 ); } catch (InterruptedException e) {}
System.out.println( "Testing Derived..." ); //$NON-NLS-1$
test( new Derived() );
}

private static void test( final Base base ) {
Runnable writer = new Runnable() {
public void run() {
System.out.println( "Writer set value " ); //$NON-NLS-1$
base.setValue( 1 );
}
};

Runnable reader = new Runnable() {
public void run() {
System.out.println( "Reader: " + base.getValue() ); //$NON-NLS-1$
}
};

(new Thread( writer ) ).start();
(new Thread( reader ) ).start();
}

Solution
Change the overriding method to be synchronized.

public static class Base {
public synchronized void setValue( int value ) {
try { Thread.sleep( 1000 ); } catch (InterruptedException e) {}
this .value = value;
}
public synchronized int getValue() {
return value;
}
protected int value = 0;
}

public static class Derived extends Base {
public synchronized int getValue() {
return this .value;
}

}

public static void main(String[] args) {
System.out.println( "Testing Base..." ); //$NON-NLS-1$
test( new Base() );
try { Thread.sleep( 5000 ); } catch (InterruptedException e) {}
System.out.println( "Testing Derived..." ); //$NON-NLS-1$
test( new Derived() );
}

private static void test( final Base base ) {
Runnable writer = new Runnable() {
public void run() {
System.out.println( "Writer set value " ); //$NON-NLS-1$
base.setValue( 1 );
}
};

Runnable reader = new Runnable() {
public void run() {
System.out.println( "Reader: " + base.getValue() ); //$NON-NLS-1$
}
};

(new Thread( writer ) ).start();
(new Thread( reader ) ).start();
}

RuleCastingPrimitives Warning Casting primitives to a lower precision may result in the information loss. Such casting indicates an incorrect choice of the data type or a calculation that ignores properties of the data that it operates on.
Example

public static void main (String[] args){
double x = 3.1;
int i = (int)x;
System.out.println(i);
}

Solution
Change the underlying data type to be lower precision.

public static void main (String[] args){
int i = 3;
System.out.println(i);
}

Solution
Update the calculation to operate on the higher precision data type.

public static void main (String[] args){
double x = 3.1;
System.out.println( x );
}

RuleCloneableOverrideClone Warning Implementing Cloneable without overriding clone() is confusing and unclear. By implementing Cloneable, the class signals that the default, shallow copy mechanism, is not sufficient, and that the class needs to perform additional operations in order to create a valid copy.
Example

public OverrideClone_Example() {
super();
elements = new int[ 1 ];
}

public void setElements( int value ) {
for ( int i = 0; i < elements.length; i++ ) {
elements[ i ] = value;
}
}

public void print() {
for ( int i = 0; i < elements.length; i++ ) {
System.out.println( elements[ i ] );
}
}

private int[] elements;

public static void main(String[] args){
OverrideClone_Example original = new OverrideClone_Example();
original.setElements( 1 );

OverrideClone_Example clone = null;
try {
clone = (OverrideClone_Example)original.clone();
System.out.println( "Clone before modification of original" ); //$NON-NLS-1$
clone.print();
original.setElements( 2 );
System.out.println( "Clone after modification of original" ); //$NON-NLS-1$
clone.print();
}catch ( CloneNotSupportedException e ) {
e.printStackTrace();
}
}

Solution
Remove the implements Cloneable declaration or implement the clone() properly.

public OverrideClone_Solution() {
super();
elements = new int[ 1 ];
}

public void setElements( int value ) {
for ( int i = 0; i < elements.length; i++ ) {
elements[ i ] = value;
}
}

public void print() {
for ( int i = 0; i < elements.length; i++ ) {
System.out.println( elements[ i ] );
}
}

public Object clone() throws CloneNotSupportedException {
OverrideClone_Solution clone = (OverrideClone_Solution)super .clone();
clone.elements = new int[ elements.length ];
for ( int i = 0; i < elements.length; i++ ) {
clone.elements[ i ] = elements[ i ];
}
return clone;
}

private int[] elements;

public static void main(String[] args){
OverrideClone_Solution original = new OverrideClone_Solution();
original.setElements( 1 );

OverrideClone_Solution clone = null;
try {
clone = (OverrideClone_Solution)original.clone();
System.out.println( "Clone before modification of original" ); //$NON-NLS-1$
clone.print();
original.setElements( 2 );
System.out.println( "Clone after modification of original" ); //$NON-NLS-1$
clone.print();
}
catch ( CloneNotSupportedException e ) {
e.printStackTrace();
}

}


RuleCloneableImplementCloneable Warning Overriding clone() without implementing Cloneable is confusing and unclear. By implementing Cloneable, the class signals that the default, shallow copy mechanism, is not sufficient, and that the class needs to perform additional operations in order to create a valid copy.
Example
public class ExampleClone {
public ExampleClone() {
super();
elements = new int[ 1 ];
}

public void setElements( int value ) {
for ( int i = 0; i < elements.length; i++ ) {
elements[ i ] = value;
}
}

public void print() {
for ( int i = 0; i < elements.length; i++ ) {
System.out.println( elements[ i ] );
}
}

public Object clone() throws CloneNotSupportedException {
ExampleClone clone = (ExampleClone)super .clone();
clone.elements = new int[ elements.length ];
for ( int i = 0; i < elements.length; i++ ) {
clone.elements[ i ] = elements[ i ];
}
return clone;
}

private int[] elements;
}

Solution
Use the implements Cloneable declaration or change the name of the clone() method.

public class ExampleClone implements Cloneable {

public ExampleClone() {
super();
elements = new int[ 1 ];
}

public void setElements( int value ) {
for ( int i = 0; i < elements.length; i++ ) {
elements[ i ] = value;
}
}

public void print() {
for ( int i = 0; i < elements.length; i++ ) {
System.out.println( elements[ i ] );
}
}

public Object clone() throws CloneNotSupportedException {
ExampleClone clone = (ExampleClone)super .clone();
clone.elements = new int[ elements.length ];
for ( int i = 0; i < elements.length; i++ ) {
clone.elements[ i ] = elements[ i ];
}
return clone;
}

private int[] elements;
}

RuleComparisonInstanceOfEquals Warning Using instanceof in the equals() of an object is critical in order to ensure that equals does not throw a ClassCastException and returns the correct value.
Example

public InstanceofEquals_Example( String str ) {
super();
this .str = str;
}

public String getString(){
return str;
}

public int hashCode() {
return str.hashCode();
}

public boolean equals(Object other){
return str.equals( ( (InstanceofEquals_Example)other ).getString() );
}

private String str;

Solution
Use instanceof in the equals() before casting.

public InstanceofEquals_Solution( String str ) {
super();
this .str = str;
}

public String getString(){
return str;
}

public int hashCode() {
return str.hashCode();
}

public boolean equals(Object other) {
return ( other instanceof InstanceofEquals_Solution) &&
str.equals( ( (InstanceofEquals_Solution)other ).getString() );
}

private String str;

RuleComparisonReferenceEquality Warning Operators == and != compare references of objects. In most cases, the two objects should be considered the same if they have the same state. It is better to use java.lang.Object.equals() for comparison, since this method allows for the implementer to make the object state comparison.
Example

public static void main( String[] args ){
Integer first = new Integer( 1 );
Integer second = new Integer( 1 );

System.out.println( first == second );
}

Solution
Use java.lang.Object.equals().

public static void main( String[] args ){
Integer first = new Integer( 1 );
Integer second = new Integer( 1 );

System.out.println( first.equals( second ) );
}

RuleExceptionsInstanceofCatch Warning Since Java supports multiple catch clauses in the try block, there is never a need to check for the instance of the exception in the catch clause. Catch clauses should be short, clear statements that deal directly with the specific exception that was thrown. Adding instanceof exception checks is likely to lead to non-standard, difficult to maintain code.
Example

public static class SomeException extends Exception{
public SomeException(String str, int value ){
super( str );
this .value = value;
}
public int getValue() {
return value;
}
private int value;
}

public static void createProblem() throws SomeException {
throw new SomeException( "Problem", 10 ); //$NON-NLS-1$
}

public static void main(String[] args){
try {
createProblem();
} catch ( Exception e ){
if ( e instanceof SomeException ) {
System.out.println( ((SomeException)e).getValue() );
} else {
System.out.println( e.getLocalizedMessage() );
e.printStackTrace();
}
}
}

Solution
Remove instanceof checks on exceptions and add dedicated catch clauses to the try/catch block.

public static class SomeException extends Exception{
public SomeException(String str, int value ){
super( str );
this .value = value;
}
public int getValue() {
return value;
}
private int value;
}

public static void createProblem() throws SomeException {
throw new SomeException( "Problem", 10 ); //$NON-NLS-1$
}

public static void main(String[] args){
try {
createProblem();
} catch ( SomeException e ){
System.out.println( ((SomeException)e).getValue() );
}
}

RuleLoopAssignLoopVariable Warning Assigning the for loop control variable in the body of the loop is likely to lead to an error. For loops already provide the default increment mechanism that should be followed. When the default increment mechanism does not apply, the for loop should be changed to a while or a do loop.
Example

public static void main( String[] args ) {
for ( int i = 0; i < args.length; i++ ) {
System.out.println( args[ i ] );
i = i + 1;
}
}


Solution
Move the assignment-to-control variable from inside of the for loop to the increment clause of the loop.

public static void main( String[] args ) {
for ( int i = 0; i < args.length; i = i + 2 ) {
System.out.println( args[ i ] );
}
}

Solution
Change the for loop to a while loop

public static void main( String[] args ) {
int i = 0;
while ( i < args.length ) {
System.out.println( args[ i ] );
i = i + 2;
}
}

RuleNullEnumeration Warning Returning null instead of empty Enumeration is error-prone in majority of cases. By Java convention, the client of the interface that returns Enumeration does not have to check for null, but should assume the empty enumeration that returns false in hasMoreElements(). Violating this convention is likely to result in null pointer exceptions.
Example

public NullEnumeration_Example() {
super();
}

public void addValue( Integer value ) {
if ( values == null ) {
values = new Vector(10);
}
values.add( value );
}

public Enumeration getValues() {
if ( values == null ) {
return null;
}
return values.elements();
}

private Vector values;

public static void main( String[] args ) {
NullEnumeration_Example example = new NullEnumeration_Example();
for ( Enumeration enum = example.getValues(); enum.hasMoreElements(); ) {
System.out.println( enum.nextElement() );
}
}

Solution
Return empty Enumeration instead of null.

public NullEnumeration_Solution() {
super();
}

public void addValue( Integer value ) {
if ( values == null ) {
values = new Vector(10);
}
values.add( value );
}

public Enumeration getValues() {
return ( values != null ) ? values.elements() : new Enumeration() {
public boolean hasMoreElements() {
return false;
}
public Object nextElement() {
throw new UnsupportedOperationException();
}
};
}

private Vector values;

public static void main( String[] args ) {
NullEnumeration_Example example = new NullEnumeration_Example();
for ( Enumeration enum = example.getValues(); enum.hasMoreElements(); ) {
System.out.println( enum.nextElement() );
}
}

RuleNullIterator Warning Returning null instead of empty Iterator is error-prone in majority of cases. By Java convention, the client of the interface that returns Iterator does not have to check for null, but should assume the empty Iterator that returns false in hasNext(). Violating this convention is likely to result in null pointer exceptions.
Example

public NullIterator_Example() {
super();
}

public void addValue( Integer value ) {
if ( values == null ) {
values = new ArrayList(10);
}
values.add( value );
}

public Iterator getValues() {
if ( values == null ) {
return null;
}
return values.iterator();
}

private List values;

public static void main( String[] args ) {
NullIterator_Example example = new NullIterator_Example();
for ( Iterator iter = example.getValues(); iter.hasNext(); ) {
System.out.println( iter.next() );
}
}

Solution
Return empty Iterator instead of null.

public NullIterator_Solution() {
super();
}

public void addValue( Integer value ) {
if ( values == null ) {
values = new ArrayList(10);
}
values.add( value );
}

public Iterator getValues() {
return ( values != null ) ? values.iterator() :
new Iterator() {
public boolean hasNext() {
return false;
}
public Object next() {
throw new UnsupportedOperationException();
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}


private List values;

public static void main( String[] args ) {
NullIterator_Example example = new NullIterator_Example();
for ( Iterator iter = example.getValues(); iter.hasNext(); ) {
System.out.println( iter.next() );
}
}

RulePortabilitySystemGetenv Warning The following is the extract from Java doc (copyright by Sun Microsystems): The preferred way to extract system-dependent information is the system properties of the java.lang.System.getProperty methods and the corresponding getTypeName methods of the Boolean, Integer, and Long primitive.
Example

public static void main(String[] args){
System.out.println( System.getenv("PATH") ); //$NON-NLS-1$
}

Solution
Use java.lang.System.getProperty()

public static void main(String[] args){
System.out.println( System.getProperty("PATH") ); //$NON-NLS-1$
}

RulePortabilityLineSeparators Warning Hard coding line separators as '\n' or '\r' makes the code non portable. In Java there is a system property called 'line.separator' specifically designed for portability.
Example

public static void main( String[] args) {
FileWriter fw = null;
try {
fw = new FileWriter( "LineSeparators.txt" ); //$NON-NLS-1$
fw.write( "Hello World!" ); //$NON-NLS-1$
fw.write("\n");//$NON-NLS-1$
}catch (Exception e){
e.printStackTrace();
} finally {
if ( fw != null ) {
try { fw.close(); } catch ( Exception e ) {}
}
}
}

Solution
Use System.getProperty( "line.separator" ) instead.

public static void main( String[] args) {
FileWriter fw = null;
try {
fw = new FileWriter( "LineSeparators.txt" ); //$NON-NLS-1$
fw.write( "Hello World!" ); //$NON-NLS-1$
fw.write( System.getProperty( "line.separator" ) ); //$NON-NLS-1$
}catch (Exception e){
e.printStackTrace();
} finally {
if ( fw != null ) {
try { fw.close(); } catch ( Exception e ) {}
}
}
}

RulePortabilityFileSeparator Warning Hard coding a file separator as '/' or '\' makes the code non portable. The java.io.File class contains a special field called 'separator' specifically designed for portability.
Example

public static void main(String[] args) {
if ( args.length > 2 ) {
File f = new File( args[ 0 ] + "/" + args[ 1 ] ); //$NON-NLS-1$
System.out.println( f.getAbsolutePath() );
}
}

Solution
Use java.io.File.separator instead.

public static void main(String[] args) {
if ( args.length > 2 ) {
File f = new File( args[ 0 ] + File.separator + args[ 1 ] );
System.out.println( f.getAbsolutePath() );
}
}

RuleSwitchBreak Warning If a break is missing in a case branch of a switch statement, the code continues by executing the next case branch. While there are situations when this is the intent, they are quite rare. More often, the intent is not to execute the following case but to break out of the current case branch. Putting the break at the end of each case branch makes code safer and more clear.
Example

public static void main(String[] args){
switch ( args.length ){
case 0:
System.out.println("No parameters"); //$NON-NLS-1$
case 1:
System.out.println("Only one parameter: args[0]"); //$NON-NLS-1$
default :
System.out.println("Parameters: "); //$NON-NLS-1$
for ( int i = 0, n = args.length; i < n; i ++){
System.out.println(args[i]);
}
}
}

Solution
Insert the break statement.

public static void main(String[] args){
switch ( args.length ){
case 0:
System.out.println("No parameters"); //$NON-NLS-1$
break ;
case 1:
System.out.println("Only one parameter: args[0]"); //$NON-NLS-1$
break ;
default :
System.out.println("Parameters: "); //$NON-NLS-1$
for ( int i = 0, n = args.length; i < n; i ++){
System.out.println(args[i]);
}
break ;
}
}

RuleCastingObjectDowncast Recommendation Returning java.lang.Object is unclear and error prone. The problem can manifest itself as the runtime ClassCastException. In order to avoid this exception, the users of the interface need to read (and often re-read) the documentation and maybe even look into the details of the implementation.
Example

public ObjectDowncast_Example( String str ) {
super();
this .str = str;
}

public Object getString(){
return str;
}

private String str;

public static void main(String[] args){
ObjectDowncast_Example example = new ObjectDowncast_Example("Hello World!"); //$NON-NLS-1$
String str = (String)example.getString();
System.out.println( str );
}

Solution
Change the method to return the actual data type instead of java.lang.Object.
If the method returns objects of types that do not share a common interface or a class, create the new interface or class and encapsulate the object in it.

public ObjectDowncast_Solution( String str ) {
super();
this .str = str;
}

public String getString(){
return str;
}

private String str;

public static void main(String[] args){
ObjectDowncast_Solution example = new ObjectDowncast_Solution("Hello World!"); //$NON-NLS-1$
String str = example.getString();
System.out.println( str );
}

RuleComparisonPlaceConstants Recommendation Placing constants on the left side of equals() eliminates the need for extra checking and reduces incidences of null pointer exceptions.
Example

public static void main( String[] args ) {
for ( int i = 0; i < args.length; i++ ) {
if ( args[ i ].equals( "Hello World!" ) ) { //$NON-NLS-1$
System.out.println( i );
}
}
}

Solution
Change the equals () expression to have the constant on the left side.

public static void main( String[] args ) {
for ( int i = 0; i < args.length; i++ ) {
if ( "Hello World!".equals( args[ i ] ) ) { //$NON-NLS-1$
System.out.println( i );
}
}
}

RuleConditionalTernary Recommendation Using an if/else statement instead of a ternary operator makes code longer than necessary. A ternary operator makes the code more compact, while preserving the clarity of the if/else statement.
Example

public static void main( String[] args ) {
ternaryVariableAssignment( args );
ternaryReturn( args );
}

public static void ternaryVariableAssignment( String[] args ) {
int j = 0;
for ( int i = 0; i < args.length; i++ ) {
if ( i > 5 ) {
j = i;
} else {
j = 10;
}
}
}

public static boolean ternaryReturn( String[] args ) {
if ( args.length > 5 ) {
return true;
} else {
return false;
}
}

Solution
Use a ternary operator instead of an if/else statement.

public static void main( String[] args ) {
ternaryVariableAssignment( args );
ternaryReturn( args );
}

public static void ternaryVariableAssignment( String[] args ) {
int j = 0;
for ( int i = 0; i < args.length; i++ ) {
j = (i > 5) ? i : 10;
}
}

public static boolean ternaryReturn( String[] args ) {
return (args.length > 5) ? true : false;
}

RuleConditionalNegationIfCondition Recommendation Negation in if/else conditions makes the code more confusing. Since if/else branches have statements for cases when the condition is either true or false, there is no need to use negation.
Example

public static void main( String[] args ) {
for ( int i = 0; i < args.length; i++ ) {
if ( ! Character.isDigit(args[i].charAt(0))) {
System.out.println("Not a digit");
} else {
System.out.println("A digit");
}
}
}

Solution
  1. Remove the negation
  2. Switch if and else parts

public static void main( String[] args ) {
for ( int i = 0; i < args.length; i++ ) {
if (Character.isDigit(args[i].charAt(0))) {
System.out.println("A digit");
} else {
System.out.println("Not a digit");
}
}
}


RuleConstructorsAbstractMethods Recommendation Calling an abstract method in the object constructor of an abstract class is problematic because its subclass may not have been properly initialized. Such calls may result in NullPointerException or an incorrect object state.
Example

public static abstract class Base implements Comparable {
public Base( Object other ) {
super();
System.out.println( compareTo( other ) );
}
}

public static final class Derived extends Base {
public Derived( String str, Object other ) {
super( other );
this .str = str;
}

public int compareTo( Object other ) {
// str is null
return str.compareTo( other.toString() );
}
private String str;

}

public static void main( String[] args ) {
Derived derived = new Derived( "Hello World!", "Hello World!" ); //$NON-NLS-1$ //$NON-NLS-2$
}

Solution
Remove the call to abstract method from the constructor.

public static abstract class Base implements Comparable {
public Base() {}
}

public static final class Derived extends Base {
public Derived( String str ) {
super();
this .str = str;
}

public int compareTo( Object other ) {
return str.compareTo( other.toString() );
}

private String str;
}

public static void main( String[] args ) {
Derived derived = new Derived( "Hello World!" ); //$NON-NLS-1$
System.out.println( derived.compareTo( "Hello World!" ) ); //$NON-NLS-1$
}

RuleConstructorsOverridableMethods Recommendation Calling an overridable method in an object constructor is problematic because the subclass may not have been properly initialized. Such calls may result in NullPointerException or an incorrect object state.
Example

public static class Base {

public Base( Integer value1, Integer value2 ) {
super();
this .value1 = value1;
this .value3 = getThirdValue();
this .value2 = value2;
}
protected Integer getThirdValue() {
return value1;
}
protected Integer value1;
protected Integer value2;
protected Integer value3;
}

public static class Derived extends Base {
public Derived( Integer value1, Integer value2 ) {
super( value1, value2 );
}
protected Integer getThirdValue() {
// value2 is null
return new Integer( value2.intValue() * 10 );
}
}

public static void main( String[] args ) {
Derived derived = new Derived( new Integer( 1 ), new Integer( 2 ) );
}


Solution
Avoid complex computations in constructors, use constructors only to initialize the fields of an object.

public static class Base {
public Base( Integer value1, Integer value2 ) {
this .value1 = value1;
this .value2 = value2;
}
public void init() {
value3 = getThirdValue();
}
protected Integer getThirdValue() {
return value1;
}
protected Integer value1;
protected Integer value2;
protected Integer value3;
}

public static class Derived extends Base {
public Derived( Integer value1, Integer value2 ) {
super( value1, value2 );
}
protected Integer getThirdValue() {
return new Integer( value2.intValue() * 10 );
}
}

public static void main( String[] args ) {
Derived derived = new Derived( new Integer( 1 ), new Integer( 2 ) );
derived.init();
}

RuleDeclarationCArrayStyle Recommendation The C-style array declaration is uncommon and archaic in Java. Avoid it because most Java programmers are not familiar with it.
Example

public static void main( String[] args ) {
String copy[] = new String[ args.length ];
for ( int i = 0; i < args.length; i++ ) {
copy[ i ] = args[ i ];
}
}

Solution
Use the Java standard for declaring arrays.

public static void main( String[] args ) {
String[] copy = new String[ args.length ];
for ( int i = 0; i < args.length; i++ ) {
copy[ i ] = args[ i ];
}
}

RuleDeclarationMultipleDeclaration Recommendation Declaring several variables in the same statement makes the code unclear. Such declaration leads to cumbersome initialization and may increase the time needed to maintain the code.
Example

public static void main( String[] args ) {
String var1 = null, var2 = null;
var1 = args[ 0 ];
var2 = args[ 1 ];
}

private int field1, field2;

Solution
Split the declaration into separate declarations.

public static void main( String[] args ) {
String var1 = null;
String var2 = null;
var1 = args[ 0 ];
var2 = args[ 1 ];
}

private int field1;
private int field2;

RuleDeclarationMixedDeclaration Recommendation Declaring basic and array variables in the same statement makes the code harder to comprehend. Such declaration leads to cumbersome initialization and may increase the time needed to maintain the code.
Example

public static void main( String[] args ) {
String notClear1 = null, notClear2[] = null;
notClear1 = args[ 0 ];
notClear2[ 0 ] = args[ 1 ];
}

Solution
Split the declaration of basic and array variables.

public static void main( String[] args ) {
String notClear1 = null;
String[] notClear2 = null;
notClear1 = args[ 0 ];
notClear2[ 0 ] = args[ 1 ];
}

RuleDeclarationDeclareConstants Recommendation Hard coding string literals is problematic for readability and globalization. To improve the performance of the code and to ensure that it is easy to read and make globalization compliant, avoid declaring explicit string literals, especially duplicate ones.
Example

public static void main(String[] args){
System.out.println( "Hello" ); //$NON-NLS-1$
System.out.println( "Bye" ); //$NON-NLS-1$
System.out.println( "Hello" ); //$NON-NLS-1$
}

Solution
Declare constant
  1. Declare constant with a meaningful name to represent the string literal.
  2. Replace all occurences of the string literal with references to declared constant.

public static void main(String[] args) {
System.out.println( HELLO );
System.out.println( BYE );
System.out.println( HELLO );
}

private static final String HELLO = "Hello"; //$NON-NLS-1$
private static final String BYE = "Bye"; //$NON-NLS-1$

RuleDeclarationInterfaceConstants Recommendation Interfaces in Java provide a mechanism for behavioral inheritance without implementation inheritance. While it is possible to declare constants in an interface and then extend this interface, this is not recommended. Constants should be declared in an interface or a class to which they logically belong. All other classes and interfaces should then refer to the constant declarations.
Example

public interface ICommonParsingConstants {
public static final int IF_TOKEN = 1;
public static final int WHILE_TOKEN = 2;
public static final String END_OF_LINE = "\n"; //$NON-NLS-1$
}

public class Parser implements ICommonParsingConstants {
public void processToken( int iToken ) {
if ( iToken == IF_TOKEN ) {
System.out.println( "if" ); //$NON-NLS-1$
} else if ( iToken == WHILE_TOKEN ) {
System.out.println( "while" ); //$NON-NLS-1$
}
}
}

public class Tokenizer implements ICommonParsingConstants {
public String getToken( String str ) {
return ( END_OF_LINE.equals( str ) ? "" : str ); //$NON-NLS-1$
}
}

Solution
  1. Move each constant to the interface or to the class to which it logically belongs.
  2. Remove the empty interface.

public class Parser {

public static final int IF_TOKEN = 1;
public static final int WHILE_TOKEN = 2;

public void processToken( int iToken ) {
if ( iToken == IF_TOKEN ) {
System.out.println( "if" ); //$NON-NLS-1$
} else if ( iToken == WHILE_TOKEN ) {
System.out.println( "while" ); //$NON-NLS-1$
}
}
}

public class Tokenizer {
public static final String END_OF_LINE = "\n"; //$NON-NLS-1$

public String getToken( String str ) {
return ( END_OF_LINE.equals( str ) ? "" : str ); //$NON-NLS-1$
}
}

RuleExceptionsSpecificExceptions Recommendation For clarity it is better to maintain the complete list of thrown exceptions in the throws clause.
Example


public class SpecificException extends Exception {

public SpecificException() {
super();
}
}


public class Example {
public void compute(Object subject) throws SpecificException {
if (subject == null){
throw new SpecificException();
}
//...
}

public void declaresException(Object o) throws Exception {
compute(o);
}
}

Solution
Declare all checked exceptions in the throws clause.


public class SpecificException extends Exception {
public SpecificException() {
super();
}
}

public class Solution {
public void compute(Object subject) throws SpecificException {
if (subject == null) {
throw new SpecificException();
}
//...
}

public void declaresException(Object o) throws SpecificException {
compute(o);
}
}


RuleExceptionsCatchGeneric Recommendation Creating broad catch clauses that handle generic exceptions such as java.lang.Exception or java.lang.Throwable exceptions may make it difficult to correct the problem. Since exceptions in Java are designed as regular classes, it is better to create and throw a specific type of an exception and to have a dedicated catch clause for each exception.
Example

public static class Loader {
public void load() throws UnsupportedOperationException, ClassNotFoundException {}
}


public static void main(String[] args) {
Loader loader = new Loader();
try {
loader.load();
} catch ( Exception e ) {
e.printStackTrace();
}
}

Solution
Create a dedicated catch clause for each exception that is declared in the throws clause.

public static class Loader {
public void load() throws UnsupportedOperationException, ClassNotFoundException {}
}


public static void main(String[] args) {
Loader loader = new Loader();
try {
loader.load();
} catch ( UnsupportedOperationException e1 ) {
System.out.println( "load is not implemented" ); //$NON-NLS-1$
} catch ( ClassNotFoundException e2 ) {
System.out.println( "No class " + e2.getMessage() ); //$NON-NLS-1$
}
}

RuleExceptionsExtendError Recommendation java.lang.Error is a runtime exception, primarily meant to be extended and used for signaling runtime problems encountered by the Java environment. The runtime exceptions are unchecked, that is the compiler will not require the user of the interface to handle it. Generally, it is preferable to create the checked exception instead of the unchecked ones.
Example

public static class ErrorSubclass extends Error{
public ErrorSubclass( String s ){
super(s);
}
}

public class Example {
public void run() {
throw new ErrorSubclass( "Problem" ); //$NON-NLS-1$
}
}

Solution
Extend java.lang.Exception.

public static class ExceptionSubclass extends Exception {
public ExceptionSubclass( String s ){
super(s);
}
}

public class Example {
public void run() throws ExceptionSubclass {
throw new ExceptionSubclass( "Problem" ); //$NON-NLS-1$
}
}

RuleExceptionsExtendRuntimeException Recommendation java.lang.RuntimeException is a runtime exception, primarily meant to be extended and used for signaling runtime problems encountered by the Java environment. The runtime exceptions are unchecked, that is the compiler will not require the user of the interface to handle it. Generally, it is preferable to create the checked exception instead of the unchecked ones.
Example

public static class RuntimeExceptionSubclass extends RuntimeException {
public RuntimeExceptionSubclass( String s ){
super(s);
}
}

public class Example {
public void run() {
throw new RuntimeExceptionSubclass( "Problem" ); //$NON-NLS-1$
}
}

Solution
Extend java.lang.Exception.

public static class ExceptionSubclass extends Exception {
public ExceptionSubclass( String s ){
super(s);
}
}

public class Example {
public void run() throws ExceptionSubclass {
throw new ExceptionSubclass( "Problem" ); //$NON-NLS-1$
}
}

RuleExceptionsExtendThrowable Recommendation java.lang.Throwable is a common base class for both checked and unchecked exceptions in Java. This class is not meant to be extended directly. It is preferable to create the checked exceptionthat descends from java.lang.Exception.
Example

public static class ThrowableSubclass extends Throwable {
public ThrowableSubclass( String s ){
super(s);
}
}

public class Example {
public void run() throws ThrowableSubclass {
throw new ThrowableSubclass( "Problem" ); //$NON-NLS-1$
}
}

Solution
Extend java.lang.Exception.

public static class ExceptionSubclass extends Exception {
public ExceptionSubclass( String s ){
super(s);
}
}

public class Example {
public void run() throws ExceptionSubclass {
throw new ExceptionSubclass( "Problem" ); //$NON-NLS-1$
}
}

RuleExceptionsThrowError Recommendation java.lang.Error is a runtime exception, primarily meant to be extended and used for signaling runtime problems encountered by the Java environment. The runtime exceptions are unchecked, that is the compiler will not require the user of the interface to handle it. Generally, it is preferable to throw checked exceptions instead of the unchecked ones.
Example

public class Example {
public void run() {
throw new Error( "Problem" ); //$NON-NLS-1$
}
}

Solution
  1. Extend the java.lang.Exception.
  2. Change the throws clause to use this new exception.

public static class ExceptionSubclass extends Exception {
public ExceptionSubclass( String s ){
super(s);
}
}

public class Example {
public void run() throws ExceptionSubclass {
throw new ExceptionSubclass( "Problem" ); //$NON-NLS-1$
}
}


RuleExceptionsThrowException Recommendation java.lang.Exception is a generic checked exception in Java. Since exceptions in Java are designed as regular classes, it is better to create and throw specific sub classes of this generic class and to have a dedicated catch clause for each exception.
Example

public class Example {
public void run() throws Exception {
throw new Exception( "Problem" ); //$NON-NLS-1$
}
}


Solution
Create the specific subclass of java.lang.Exception.

public static class ExceptionSubclass extends Exception {
public ExceptionSubclass( String s ){
super(s);
}
}

public class Example {
public void run() throws ExceptionSubclass {
throw new ExceptionSubclass( "Problem" ); //$NON-NLS-1$
}
}

RuleExceptionsThrowThrowable Recommendation java.lang.Throwable is a common base class for both checked and unchecked exceptions in Java. This class is not meant to be used directly in the throws clause. It is preferable to create and use specific checked exceptions thfrom java.lang.Exception.
Example

public class Example {
public void run() throws Throwable {
throw new Throwable( "Problem" ); //$NON-NLS-1$
}
}

Solution
Create specific subclass of java.lang.Exception.

public static class ExceptionSubclass extends Exception {
public ExceptionSubclass( String s ){
super(s);
}
}

public class Example {
public void run() throws ExceptionSubclass {
throw new ExceptionSubclass( "Problem" ); //$NON-NLS-1$
}
}

RuleInitializationInitializeStaticFields Recommendation Uninitialzed static fields may lead to problems such as NullPointerException. Also, when a field is not explicitely initialized, someone reading the code may not know the default value and may have difficulty understanding the code.
Example

public interface IHandler {
public void process( Object o );
}

public static void registerHandler( Class c, IHandler handler ) {
handlers.put( c, handler );
}

public static IHandler getHandler( Class c ) {
return (IHandler)handlers.get( c );
}

private InitializeStaticFields_Example() {
super();
}

private static Map handlers;

public static void main(String[] args){
IHandler handler = new IHandler() {
public void process( Object o ) {
System.out.println( String.valueOf( o ) );
}
};
InitializeStaticFields_Example.registerHandler( Boolean.class, handler );
InitializeStaticFields_Example.getHandler( Boolean.class ).process( Boolean.TRUE );
}

Solution
Always initilize static fields.

public interface IHandler {
public void process( Object o );
}

public static void registerHandler( Class c, IHandler handler ) {
handlers.put( c, handler );
}

public static IHandler getHandler( Class c ) {
return (IHandler)handlers.get( c );
}

private InitializeStaticFields_Solution() {
super();
}

private static Map handlers = new HashMap(10);

public static void main(String[] args){
IHandler handler = new IHandler() {
public void process( Object o ) {
System.out.println( String.valueOf( o ) );
}
};
InitializeStaticFields_Solution.registerHandler( Boolean.class, handler );
InitializeStaticFields_Solution.getHandler( Boolean.class ).process( Boolean.TRUE );
}

RuleInitializationChainingAssignments Recommendation Chaining assignment operators introduces the potential for errors and makes the code unclear. The code is more robust and self-explanatory if the assignments are separated.
Example

public static void main( String[] args ) {
int x = 0;
int y = 0;
x = y = 10;
System.out.println( x + " " + y ); //$NON-NLS-1$
}

Solution
Assign the variables in separate statements.

public static void main( String[] args ) {
int x = 0;
int y = 0;
x = 10;
y = 10;
System.out.println( x + " " + y ); //$NON-NLS-1$
}

RuleInitializationAssigningMethodParameter Recommendation Changing the value of a method parameter alters its original intent and makes the code unclear.
Example

public static void main( String[] args ) {
loop( Integer.parseInt( args[ 0 ] ) );
}

private static void loop( int iMax ) {
iMax = Math.max( iMax, 20 );
for ( int i = 0; i < iMax; ) {
System.out.println( i );
}
}

Solution
Introduce another variable instead of changing the value of a method parameter.

public static void main( String[] args ) {
loop( Integer.parseInt( args[ 0 ] ) );
}

private static void loop( int iMax ) {
int iBoundedMax = Math.max( iMax, 20 );
for ( int i = 0; i < iBoundedMax; ) {
System.out.println( i );
}
}

RuleLoopNoConditionForLoop Recommendation A for loop without a condition may lead to an infinite loop. Such for loops are also more difficult to understand and maintain.
Example

public static void main( String[] args ) {
for ( int i = 0; ; i++ ) {
System.out.println( args[ i ] );
if ( i < args.length ) {
break ;
}
}
}

Solution
Insert a condition into the for loop.

public static void main( String[] args ) {
for ( int i = 0; i < args.length; i++ ) {
System.out.println( args[ i ] );
}
}

RuleLoopNoInitIncrForLoop Recommendation A for loop without an initializer and an incrementor is misleading and error-prone. Besides hiding the intend, the loop may lead to 'infinite loop' problems.
Example

public static void main( String[] args ) {
int i = 0;
for ( ; i < args.length ; ) {
System.out.println( args[ i ] );
i++;
}
}

Solution
Replace the for loop with a while loop.

public static void main( String[] args ) {
int i = 0;
while ( i < args.length ) {
System.out.println( args[ i ] );
i++;
}
}

RuleLoopContinueStatement Recommendation Continue statements add additional, unnecessary complexity to the body of a loop. Continue statements typically occur in long loops with non-trivial logic. Such loops need to be refactored into smaller, more clear calculations. After performing the refactoring, it will be possible to replace the continue statement with an if statement without complicating the code.
Example

public static void main( String[] args ) {
for ( int i = 0; i < args.length; i++ ) {
if ( i < 5 ) {
continue ;
}
System.out.println( args[ i ] );
}
}

Solution
  1. While continue is part of a long loop, refactor the loop using Extract Method refactoring
  2. Negate the condition before the continue statement
  3. Move the code below the continue statement to inside of the if block

public static void main( String[] args ) {
for ( int i = 0; i < args.length; i++ ) {
if ( i >= 5 ) {
System.out.println( args[ i ] );
}
}
}

RuleReflectionGetDeclaredField Recommendation Java reflection facilities are designed for generic processing of class content. For example, the reflection is used by Java Beans framework to enable generic inspection of properties of Java Beans. The reflection is not meant to circumvent the standard java field or method access. Thus, calling getDeclaredField() with the hard coded name of the field is not recommended.
Example

public GetDeclaredField_Example() {
super();
}

public void setValue( int value ) {
this .value = value;
}

public int getValue() {
return value;
}

private int value;

public static void main(String[] args){
try {
Field field = GetDeclaredField_Example.class.getDeclaredField( "value" ); //$NON-NLS-1$
GetDeclaredField_Example obj = new GetDeclaredField_Example();
field.set( obj, new Integer( 1 ) );
System.out.println( obj.getValue() );
} catch (SecurityException e) {
System.out.println( "Can't access field 'value'" ); //$NON-NLS-1$
} catch (NoSuchFieldException e) {
System.out.println( "No field 'value'" ); //$NON-NLS-1$
} catch (IllegalArgumentException e) {
System.out.println( e.getMessage() );
} catch (IllegalAccessException e) {
System.out.println( "Can't access private field 'value'" ); //$NON-NLS-1$
}
}

Solution
Use direct field access instead of getDeclaredField() with the hard coded name of the field.

public GetDeclaredField_Solution() {
super();
}

public void setValue( int value ) {
this .value = value;
}

public int getValue() {
return value;
}

private int value;

public static void main(String[] args){
GetDeclaredField_Example obj = new GetDeclaredField_Example();
obj.setValue( 1 );
System.out.println( obj.getValue() );
}

RuleReflectionGetDeclaredMethod Recommendation Java reflection facilities are designed for generic processing of class content. For example, the reflection is used by Java Beans framework to enable generic inspection of properties of Java Beans. The reflection is not meant to circumvent the standard java field or method access. Thus, calling getDeclaredMethod() with the hard coded name of the method is not desirable.
Example

public GetDeclaredMethod_Example() {
super();
}

public void setValue( int value ) {
this .value = value;
}

public int getValue() {
return value;
}

private int value;

public static void main(String[] args){
try {
Method method = GetDeclaredMethod_Example.class.getDeclaredMethod( "getValue", new Class[] { Void.class } ); //$NON-NLS-1$
GetDeclaredMethod_Example obj = new GetDeclaredMethod_Example();
method.invoke( obj, new Object[] { new Integer( 1 ) } );
System.out.println( obj.getValue() );
} catch (IllegalAccessException e) {
System.out.println( "Can't access private method 'getValue'" ); //$NON-NLS-1$
} catch (InvocationTargetException e) {
System.out.println( "Problem calling method" ); //$NON-NLS-1$
} catch (NoSuchMethodException e) {
System.out.println( "No method getValue" ); //$NON-NLS-1$
}

}

Solution
Use direct method call instead of getDeclaredMethod() with the hard coded name of the method.

public GetDeclaredMethod_Solution() {
super();
}

public void setValue( int value ) {
this .value = value;
}

public int getValue() {
return value;
}

private int value;

public static void main(String[] args) {
GetDeclaredMethod_Example obj = new GetDeclaredMethod_Example();
obj.setValue( 1 );
System.out.println( obj.getValue() );
}


RuleReflectionGetField Recommendation Java reflection facilities are designed for generic processing of class content. For example, the reflection is used by Java Beans framework to enable generic inspection of properties of Java Beans. The reflection is not meant to circumvent the standard java field or method access. Thus, calling getField() with the hard coded name of the field is not desirable.
Example

public GetField_Example() {
super();
}

public void setValue( int value ) {
this .value = value;
}

public int getValue() {
return value;
}

private int value;

public static void main(String[] args){
try {
Field field = GetField_Example.class.getField( "value" ); //$NON-NLS-1$
GetField_Example obj = new GetField_Example();
field.set( obj, new Integer( 1 ) );
System.out.println( obj.getValue() );
} catch (SecurityException e) {
System.out.println( "Can't access field 'value'" ); //$NON-NLS-1$
} catch (NoSuchFieldException e) {
System.out.println( "No field 'value'" ); //$NON-NLS-1$
} catch (IllegalArgumentException e) {
System.out.println( e.getMessage() );
} catch (IllegalAccessException e) {
System.out.println( "Can't access private field 'value'" ); //$NON-NLS-1$
}
}

Solution
Use direct field access instead of getField() with the hard coded name of the field.

public GetField_Solution() {
super();
}

public void setValue( int value ) {
this .value = value;
}

public int getValue() {
return value;
}

private int value;

public static void main(String[] args){
GetField_Solution obj = new GetField_Solution();
obj.setValue( 1 );
System.out.println( obj.getValue() );
}

RuleReflectionGetMethod Recommendation Java reflection facilities are designed for generic processing of class content. For example, the reflection is used by Java Beans framework to enable generic inspection of properties of Java Beans. The reflection is not meant to circumvent the standard java field or method access. Thus, calling getMethod() with the hard coded name of the method is not desirable.
Example

public GetMethod_Example() {
super();
}

public void setValue( int value ) {
this .value = value;
}

public int getValue() {
return value;
}

private int value;

public static void main(String[] args){
try {
Method method = GetMethod_Example.class.getMethod( "getValue", new Class[] { Void.class } ); //$NON-NLS-1$
GetMethod_Example obj = new GetMethod_Example();
method.invoke( obj, new Object[] { new Integer( 1 ) } );
System.out.println( obj.getValue() );
} catch (IllegalAccessException e) {
System.out.println( "Can't access private method 'getValue'" ); //$NON-NLS-1$
} catch (InvocationTargetException e) {
System.out.println( "Problem calling method" ); //$NON-NLS-1$
} catch (NoSuchMethodException e) {
System.out.println( "No method getValue" ); //$NON-NLS-1$
}

}

Solution
Use direct method call instead of getMethod with the hard coded name of the method.

public GetMethod_Solution() {
super();
}

public void setValue( int value ) {
this .value = value;
}

public int getValue() {
return value;
}

private int value;

public static void main(String[] args) {
GetMethod_Solution obj = new GetMethod_Solution();
obj.setValue( 1 );
System.out.println( obj.getValue() );
}


RuleSerializationSerialVersionUID Recommendation The serialVersionUID field is used by Java serialization to ensure correct deserialization of old objects when the underlying class is altered. Failing to declare the serialVersionUID inside of a serializable class will result in the IOException when attempting to load old instances of this class.
Example

public class SerialVersionUID implements Serializable {

public SerialVersionUID() {
super();
}

public String getString(){
return field;
}

public void setString(String field){
this .field = field;
}

private String field;

}


Solution
Declare static final serialVersionUID field.


public class SerialVersionUID implements Serializable {

public SerialVersionUID() {
super();
}

public String getString(){
return field;
}

public void setString(String field){
this .field = field;
}

private String field;

static final long serialVersionUID = 123;

}

RuleSerializationTransientField Recommendation The transient keyword is used in Java to denote the non-serializable fields inside of serializable classes. Using this keyword inside of non-serializable classes makes the code unclear and cluttered.
Example


public static final class SomeType {}

public class SerializableField implements Serializable {
public SerializableField( String str ) {
super();
this .str = str;
nonser = new SomeType();
}

private String str;
private SomeType nonser;

private static final long serialVersionUID = 123;
}


Solution
Make the field type serializable.

public static final class SomeType implements Serializable {}

public class SerializableField() implements Serializable {

public SerializableField( String str ) {
super();
this .str = str;
nonser = new SomeType();
}

private String str;
private SomeType nonser;

private static final long serialVersionUID = 123;
}

Solution
Declare the field transient.

public static final class SomeType {}

public class SerializableField implements Serializable {

public SerializableField( String str ) {
super();
this .str = str;
nonser = new SomeType();
}

private String str;
private transient SomeType nonser;

private static final long serialVersionUID = 123;


}

RuleStatementSurroundWithBraces Recommendation An unsurrounded if or loop statement introduces ambiguity and the possibility of an error into the code. For example, if a line below the statement is removed, then the next line below it becomes part of the statement, which may not be the intent. Also, statements without curly braces rely on indentation to communicate the meaning. It is better to be explicit and demonstrate the intent by surrounding all such statements with curly braces.
Example

public static void main( String[] args ) {
surroundIf( args );
surroundLoop( args );
}

private static void surroundIf(String[] args) {
if ( args.length == 0 )
System.out.println( "No arguments" ); //$NON-NLS-1$
else
System.out.println( args.length + " arguments"); //$NON-NLS-1$
System.out.println( args[ 0 ] );
}

private static void surroundLoop( String[] args ) {
for ( int i = 0; i < args.length; i++ )
System.out.println(args[i]);
System.out.println( "Done" ); //$NON-NLS-1$
}

Solution
Surround if and loop statements with curly braces.
RuleStatementEmptyStatement Recommendation An empty statement is an extraneous piece of code. Such statements make code more difficult to understand and maintain. Empty statements typically arise as a result of accidental code deletions.
Example

public static void main( String[] args ) {
emptyIf( args );
emptyLoop( args );
}

private static void emptyIf( String[] args ) {
if ( args.length == 0 ){
}else {
for ( int i = 0; i < args.length; i++ ) {
if ( i > 0 );
System.out.println( args[ i ] );
}
}
}

private static void emptyLoop( String[] args ) {
int i = 0;
while ( i < args.length );
System.out.println( args[ i++ ] );
for ( int j = 0; j < args.length; j++ ){}
}

Solution
Enclude the statements below into the loop or if statement.


public static void main( String[] args ) {
emptyIf( args );
emptyLoop( args );
}

private static void emptyIf( String[] args ) {
if ( args.length > 0 ){
for ( int i = 0; i < args.length; i++ ) {
if ( i > 1 ) {
System.out.println( args[ i ] );
}
}
}
}

private static void emptyLoop( String[] args ) {
int i = 0;
while ( i < args.length ){
System.out.println( args[ i++ ] );
}
for ( int j = 0; j < args.length; j++ ){
System.out.println( args[ j++ ] );
}
}


RuleSwitchDefaultLabel Recommendation A missing default label in a switch statement makes the code incomplete because the intended behavior is not clear. Providing the default label results in more explicit and robust code.
Example

public static final int YESTERDAY = 0;
public static final int TODAY = 1;
public static final int TOMORROW = 2;

public static void main( String[] args ) {
int dateType = Integer.parseInt( args[ 0 ] );

Calendar calendar = Calendar.getInstance();
switch ( dateType ) {
case 0:
calendar.add( Calendar.DATE, -1 );
break ;
case 1:
break ;
case 2:
calendar.add( Calendar.DATE, 1 );
break ;
}

System.out.println( calendar.getTime() );
}

Solution
Add the default label to the switch statement.

public static final int YESTERDAY = 0;
public static final int TODAY = 1;
public static final int TOMORROW = 2;

public static void main( String[] args ) {
int dateType = Integer.parseInt( args[ 0 ] );

Calendar calendar = Calendar.getInstance();
switch ( dateType ) {
case 0:
calendar.add( Calendar.DATE, -1 );
break ;
case 1:
break ;
case 2:
calendar.add( Calendar.DATE, 1 );
break ;
default :
break ;
}

System.out.println( calendar.getTime() );
}

RuleSwitchBranch Recommendation The switch statement is meant to be used to avoid a lot of nested if/else constructs. However, when there are just two choices, using a switch statement is unnecessary and unclear.
Example

public static void main(String[] args){
switch ( args.length ) {
case 0:
System.out.println("No parameters"); //$NON-NLS-1$
break ;
default :
System.out.println("Parameters: "); //$NON-NLS-1$
for ( int i = 0, n = args.length; i < n; i ++){
System.out.println(args[i]);
}
break ;
}
}

Solution
Use if/else instead.

public static void main(String[] args){
if ( args.length == 0 ) {
System.out.println("No Paramaters");
} else {
System.out.println("Parameters: "); //$NON-NLS-1$
for ( int i = 0, n = args.length; i < n; i ++){
System.out.println(args[i]);
}
}
}


yield Recommendation Thread.yield() is meant to suspend the execution of the current thread and let the other active threads run. Yield is equivalent to Thread.sleep( 0 ). Even though the yield() is guaranteed to work, there is no guarantee that another thread will not be suspended again. This is because the task intended by yield() call may not be fully accomplished before the control is returned to the yielding thread. When designing threading behavior in complex, large-scale programs it is not recommended to use yield to ensure the order of thread execution. The lock-based wait()/notify() approach is preferred instead.
Example

public static void main( String[] args ){
Data data = new Data();
final Consumer consumer = new Consumer( data );
final Producer producer = new Producer( data );

(new Thread( new Runnable() {
public void run() {
consumer.consume();
}
})).start();


(new Thread( new Runnable() {
public void run() {
producer.produce();
}
})).start();
}

public static final class Data {
public Data() {
super();
}
public int getValue() {
return value;
}
public void setValue( int value ) {
this .value = value;
}
private int value = 0;
}

public static final class Consumer {
public Consumer( Data data ) {
this .data = data;
}

public void consume() {
System.out.println( "Consumer: consume was called" ); //$NON-NLS-1$
System.out.println( "Consumer: yielding..." ); //$NON-NLS-1$
Thread.yield();
System.out.println( "Consumer: value is " + data.getValue() ); //$NON-NLS-1$
System.out.println( "Consumer: exiting" ); //$NON-NLS-1$
}

private Data data;
}

public static final class Producer {
public Producer( Data data ) {
this .data = data;
}
public void produce() {
System.out.println( "Producer: produce was called" ); //$NON-NLS-1$
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
data.setValue( 1 );System.out.println( "Producer: exiting" ); //$NON-NLS-1$
}
private Data data;
}

Solution
Use wait()/notify() instead of yield().

public static void main( String[] args ){
Data data = new Data();
Lock lock = new Lock();
final Consumer consumer = new Consumer( data, lock );
final Producer producer = new Producer( data, lock );

(new Thread( new Runnable() {
public void run() {
consumer.consume();
}
})).start();


(new Thread( new Runnable() {
public void run() {
producer.produce();
}
})).start();
}

public static final class Data {
public Data() {
super();
}
public int getValue() {
return value;
}
public void setValue( int value ) {
this .value = value;
}
private int value = 0;
}

public static final class Lock {
public Lock() {
super();
lock();
}
public boolean isAvailable() {
return available;
}
public void lock() {
available = false;
}
public void unlock() {
available = true;
}
private boolean available = false;
}

public static final class Consumer {
public Consumer( Data data, Lock lock ) {
this .data = data;
this .lock = lock;
}

public void consume() {
System.out.println( "Consumer: consume was called" ); //$NON-NLS-1$
System.out.println( "Consumer: waiting..." ); //$NON-NLS-1$
synchronized ( lock ) {
try {
lock.wait();
} catch (InterruptedException e) {}
}
System.out.println( "Consumer: value is " + data.getValue() ); //$NON-NLS-1$
System.out.println( "Consumer: exiting" ); //$NON-NLS-1$
}

private Data data;
private Lock lock;
}

public static final class Producer {
public Producer( Data data, Lock lock ) {
this .data = data;
this .lock = lock;
}
public void produce() {
System.out.println( "Producer: produce was called" ); //$NON-NLS-1$
synchronized ( lock ) {
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
data.setValue( 1 );System.out.println( "Producer: exiting" ); //$NON-NLS-1$
lock.unlock();
lock.notifyAll();
}
}
private Data data;
private Lock lock;
}


extendthread Recommendation Extending Thread vs. implementing Runnable problem is an example of the Inheritance vs. Delegation Principle. In most cases, delegation is preferred to inheritance. Here as well, there is no good reason to extend Thread class. Instead, it is cleaner to implement Runnable interface and instantiate Thread to run it.
Example

public static class ICThread extends Thread {
public void run() {
System.out.println( System.currentTimeMillis() );
}
}

public static void main( String[] args ) {
(new ICThread()).start();
}

Solution
Implement Runnable instead of extending Thread.

public static class ICRunnable implements Runnable {
public void run() {
System.out.println( System.currentTimeMillis() );
}
}

public static void main( String[] args ) {
(new Thread( new ICRunnable() )).start();
}

synchronizedthis Recommendation Synchronization problems are difficult to identify and debug, so it is critical to consider what exactly is being locked and why. Creating separate locks to protect different data sets is a good practice that will lead to improved performance and clarity. Using this as a lock is not recommended because it is also used as an implicit lock when the method is declared synchronized.
Example

public int getNumber() {
synchronized ( this ) {
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
return number;
}
}

public String getString() {
synchronized ( this ) {
return str;
}
}

private String str = "Hello world!"; //$NON-NLS-1$
private int number = 10;

public static void main( String[] args ) {
final SynchronizedThis_Example data = new SynchronizedThis_Example();
Runnable numberReader = new Runnable() {
public void run() {
System.out.println( "Getting number..." ); //$NON-NLS-1$
System.out.println( data.getNumber() );
}
};
Runnable stringReader = new Runnable() {
public void run() {
System.out.println( "Getting string..." ); //$NON-NLS-1$
System.out.println( data.getString() );
}
};

(new Thread( numberReader ) ).start();
(new Thread( stringReader ) ).start();
}

Solution
Declare an explicit separate lock to protect different data sets.


public int getNumber() {
synchronized ( numberLock ) {
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
return number;
}
}

public String getString() {
synchronized ( stringLock ) {
return str;
}
}

private String str = "Hello world!"; //$NON-NLS-1$
private int number = 10;
private Object numberLock = new Object();
private Object stringLock = new Object();

public static void main( String[] args ) {
final SynchronizedThis_Solution data = new SynchronizedThis_Solution();
Runnable numberReader = new Runnable() {
public void run() {
System.out.println( "Getting number..." ); //$NON-NLS-1$
System.out.println( data.getNumber() );
}
};
Runnable stringReader = new Runnable() {
public void run() {
System.out.println( "Getting string..." ); //$NON-NLS-1$
System.out.println( data.getString() );
}
};

(new Thread( numberReader ) ).start();
(new Thread( stringReader ) ).start();
}


notifyall Recommendation The difference between java.lang.Object.notify() and java.lang.Object.notifyAll() is that the first method tells JVM to inform the first thread that is waiting on a lock, while the second tells JVM to inform all the threads that are waiting on a lock. Since the number of waiting threads is often difficult to anticipate, it is recommended to call notifyAll() instead of notify().
Example

public static void main( String[] args ){
Lock lock = new Lock();
final Consumer consumer1 = new Consumer( lock, 1 );
final Consumer consumer2 = new Consumer( lock, 2 );
final Producer producer = new Producer( lock );

(new Thread( new Runnable() {
public void run() {
consumer1.consume();
}
})).start();

(new Thread( new Runnable() {
public void run() {
consumer2.consume();
}
})).start();

(new Thread( new Runnable() {
public void run() {
producer.produce();
}
})).start();
}

public static final class Lock {
public Lock() {
super();
lock();
}
public boolean isAvailable() {
return available;
}
public void lock() {
available = false;
}
public void unlock() {
available = true;
}
private boolean available = false;
}

public static final class Consumer {
public Consumer( Lock lock, int id ) {
this .lock = lock;
this .id = id;
}

public void consume() {
System.out.println( "Consumer " + id + ": consume was called" ); //$NON-NLS-1$ //$NON-NLS-2$
synchronized ( lock ) {
while ( !lock.isAvailable() ) {
System.out.println( "Consumer" + id + ": waiting..." ); //$NON-NLS-1$ //$NON-NLS-2$
try {
lock.wait();
} catch (InterruptedException e) {}
}
}
System.out.println( "Consumer" + id + ": exiting" ); //$NON-NLS-1$ //$NON-NLS-2$
}

private Lock lock;
private int id;
}

public static final class Producer {
public Producer( Lock lock ) {
this .lock = lock;
}
public void produce() {
System.out.println( "Producer: produce was called" ); //$NON-NLS-1$
System.out.println( "Producer: unlocking..." ); //$NON-NLS-1$
synchronized ( lock ) {
lock.unlock();
lock.notify();
}
System.out.println( "Producer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}



Solution
Call notifyAll() instead of notify()

public static void main( String[] args ){
Lock lock = new Lock();
final Consumer consumer1 = new Consumer( lock, 1 );
final Consumer consumer2 = new Consumer( lock, 2 );
final Producer producer = new Producer( lock );

(new Thread( new Runnable() {
public void run() {
consumer1.consume();
}
})).start();

(new Thread( new Runnable() {
public void run() {
consumer2.consume();
}
})).start();

(new Thread( new Runnable() {
public void run() {
producer.produce();
}
})).start();
}

public static final class Lock {
public Lock() {
super();
lock();
}
public boolean isAvailable() {
return available;
}
public void lock() {
available = false;
}
public void unlock() {
available = true;
}
private boolean available = false;
}

public static final class Consumer {
public Consumer( Lock lock, int id ) {
this .lock = lock;
this .id = id;
}

public void consume() {
System.out.println( "Consumer " + id + ": consume was called" ); //$NON-NLS-1$ //$NON-NLS-2$
synchronized ( lock ) {
while ( !lock.isAvailable() ) {
System.out.println( "Consumer" + id + ": waiting..." ); //$NON-NLS-1$ //$NON-NLS-2$
try {
lock.wait();
} catch (InterruptedException e) {}
}
}
System.out.println( "Consumer" + id + ": exiting" ); //$NON-NLS-1$ //$NON-NLS-2$
}

private Lock lock;
private int id;
}

public static final class Producer {
public Producer( Lock lock ) {
this .lock = lock;
}
public void produce() {
System.out.println( "Producer: produce was called" ); //$NON-NLS-1$
System.out.println( "Producer: unlocking..." ); //$NON-NLS-1$
synchronized ( lock ) {
lock.unlock();
lock.notifyAll();
}
System.out.println( "Producer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}


waitoutsideloop Recommendation The call to wait() suspends the execution of the calling thread until another thread notifies it that the intended state of the program is achieved. The wait() should occur based on the termination condition. It is highly recommended that the wait() call is made inside of the while loop, because another thread may invoke notify even if the condition on which the current thread is waiting is not met
Example

public static void main( String[] args ){
Lock lock = new Lock();
final Consumer consumer1 = new Consumer( lock, 1 );
final Consumer consumer2 = new Consumer( lock, 2 );
final Producer producer = new Producer( lock );

(new Thread( new Runnable() {
public void run() {
consumer1.consume();
}
})).start();

(new Thread( new Runnable() {
public void run() {
consumer2.consume();
}
})).start();

(new Thread( new Runnable() {
public void run() {
producer.produce();
}
})).start();
}

public static final class Lock {
public Lock() {
super();
lock();
}
public boolean isAvailable() {
return available;
}
public void lock() {
available = false;
}
public void unlock() {
available = true;
}
private boolean available = false;
}

public static final class Consumer {
public Consumer( Lock lock, int id ) {
this .lock = lock;
this .id = id;
}

public void consume() {
System.out.println( "Consumer " + id + ": consume was called" ); //$NON-NLS-1$ //$NON-NLS-2$
if ( !lock.isAvailable() ) {
System.out.println( "Consumer" + id + ": waiting..." ); //$NON-NLS-1$ //$NON-NLS-2$
synchronized ( lock ) {
try {
lock.wait();
} catch (InterruptedException e) {}
}
}
System.out.println( "Consumer" + id + ": exiting" ); //$NON-NLS-1$ //$NON-NLS-2$
}

private Lock lock;
private int id;
}

public static final class Producer {
public Producer( Lock lock ) {
this .lock = lock;
}
public void produce() {
System.out.println( "Producer: produce was called" ); //$NON-NLS-1$
synchronized ( lock ) {
lock.notifyAll();
}
synchronized ( lock ) {
System.out.println( "Producer: unlocking..." ); //$NON-NLS-1$
lock.unlock();
lock.notifyAll();
}
System.out.println( "Producer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}

Solution
Place wait() inside of a while loop.

public static void main( String[] args ){
Lock lock = new Lock();
final Consumer consumer1 = new Consumer( lock, 1 );
final Consumer consumer2 = new Consumer( lock, 2 );
final Producer producer = new Producer( lock );

(new Thread( new Runnable() {
public void run() {
consumer1.consume();
}
})).start();

(new Thread( new Runnable() {
public void run() {
consumer2.consume();
}
})).start();

(new Thread( new Runnable() {
public void run() {
producer.produce();
}
})).start();
}

public static final class Lock {
public Lock() {
super();
lock();
}
public boolean isAvailable() {
return available;
}
public void lock() {
available = false;
}
public void unlock() {
available = true;
}
private boolean available = false;
}

public static final class Consumer {
public Consumer( Lock lock, int id ) {
this .lock = lock;
this .id = id;
}

public void consume() {
System.out.println( "Consumer " + id + ": consume was called" ); //$NON-NLS-1$ //$NON-NLS-2$
synchronized ( lock ) {
while ( !lock.isAvailable() ) {
System.out.println( "Consumer" + id + ": waiting..." ); //$NON-NLS-1$ //$NON-NLS-2$
try {
lock.wait();
} catch (InterruptedException e) {}
}
}
System.out.println( "Consumer" + id + ": exiting" ); //$NON-NLS-1$ //$NON-NLS-2$
}

private Lock lock;
private int id;
}

public static final class Producer {
public Producer( Lock lock ) {
this .lock = lock;
}
public void produce() {
System.out.println( "Producer: produce was called" ); //$NON-NLS-1$
synchronized ( lock ) {
lock.notifyAll();
}
synchronized ( lock ) {
System.out.println( "Producer: unlocking..." ); //$NON-NLS-1$
lock.unlock();
lock.notifyAll();
}
System.out.println( "Producer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}


synchronizedmethod Recommendation Synchronized method implicitly uses 'this' as a lock to prevent other methods and blocks with the same lock from parallel execution. There are several reasons why this is undesirable. Most important is that since synchronized blocks are computationally expensive, it is desirable to place as less code as possible inside of these blocks. If the method that is declared as synchronized is operating on more data that needs to be protected then such method is unnecessarily expensive. Another reason is that some programmers are not aware that 'this' is used as a lock when method is declared synchronized, so it is better to be explicit
Example

public synchronized int getNumber() {
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
return number;
}

public synchronized String getString() {
return str;
}

private String str = "Hello world!"; //$NON-NLS-1$
private int number = 10;

public static void main( String[] args ) {
final SynchronizedMethod_Example data = new SynchronizedMethod_Example();
Runnable numberReader = new Runnable() {
public void run() {
System.out.println( "Getting number..." ); //$NON-NLS-1$
System.out.println( data.getNumber() );
}
};
Runnable stringReader = new Runnable() {
public void run() {
System.out.println( "Getting string..." ); //$NON-NLS-1$
System.out.println( data.getString() );
}
};

(new Thread( numberReader ) ).start();
(new Thread( stringReader ) ).start();
}

Solution
Create synchronized block inside of the method that only locks necessary statements.

public int getNumber() {
synchronized ( numberLock ) {
try { Thread.sleep( 3000 ); } catch (InterruptedException e) {}
return number;
}
}

public String getString() {
synchronized ( stringLock ) {
return str;
}
}

private String str = "Hello world!"; //$NON-NLS-1$
private int number = 10;
private Object numberLock = new Object();
private Object stringLock = new Object();

public static void main( String[] args ) {
final SynchronizedMethod_Solution data = new SynchronizedMethod_Solution();
Runnable numberReader = new Runnable() {
public void run() {
System.out.println( "Getting number..." ); //$NON-NLS-1$
System.out.println( data.getNumber() );
}
};
Runnable stringReader = new Runnable() {
public void run() {
System.out.println( "Getting string..." ); //$NON-NLS-1$
System.out.println( data.getString() );
}
};

(new Thread( numberReader ) ).start();
(new Thread( stringReader ) ).start();
}

whilesleep Recommendation The sleep() call causes the currently executing thread to cease execution for the specified number of milliseconds. The thread does not, however, loose the ownership of any of its monitors (locks). Calling sleep inside of the while loop is known as a busy-wait, since it does not allow other threads to operate on the shared data.
Example

public static void main( String[] args ){
Lock lock = new Lock();
final Consumer consumer = new Consumer( lock );
final Producer producer = new Producer( lock );

(new Thread( new Runnable() {
public void run() {
consumer.consume();
}
})).start();


(new Thread( new Runnable() {
public void run() {
producer.produce();
}
})).start();
}

public static final class Lock {
public Lock() {
super();
lock();
}
public boolean isAvailable() {
return available;
}
public void lock() {
available = false;
}
public void unlock() {
available = true;
}
private boolean available = false;
}

public static final class Consumer {
public Consumer( Lock lock ) {
this .lock = lock;
}

public void consume() {
System.out.println( "Consumer: consume was called" ); //$NON-NLS-1$
while ( !lock.isAvailable() ) {
System.out.println( "Consumer: sleeping..." ); //$NON-NLS-1$
try { Thread.sleep( 1000 ); } catch (InterruptedException e) {}
}
System.out.println( "Consumer: exiting" ); //$NON-NLS-1$
}

private Lock lock;
}

public static final class Producer {
public Producer( Lock lock ) {
this .lock = lock;
}
public void produce() {
System.out.println( "Producer: produce was called" ); //$NON-NLS-1$
try { Thread.sleep( 5000 ); } catch (InterruptedException e) {}
System.out.println( "Producer: unlocking..." ); //$NON-NLS-1$
lock.unlock();
System.out.println( "Producer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}


Solution
Change while()/sleep() to wait()/notify().

public static void main( String[] args ){
Lock lock = new Lock();
final Consumer consumer = new Consumer( lock );
final Producer producer = new Producer( lock );

(new Thread( new Runnable() {
public void run() {
consumer.consume();
}
})).start();


(new Thread( new Runnable() {
public void run() {
producer.produce();
}
})).start();
}

public static final class Lock {
public Lock() {
super();
lock();
}
public boolean isAvailable() {
return available;
}
public void lock() {
available = false;
}
public void unlock() {
available = true;
}
private boolean available = false;
}

public static final class Consumer {
public Consumer( Lock lock ) {
this .lock = lock;
}

public void consume() {
System.out.println( "Consumer: consume was called" ); //$NON-NLS-1$
synchronized ( lock ) {
while ( !lock.isAvailable() ) {
System.out.println( "Consumer: waiting..." ); //$NON-NLS-1$
try {
lock.wait();
} catch (InterruptedException e) {}
}
}
System.out.println( "Consumer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}

public static final class Producer {
public Producer( Lock lock ) {
this .lock = lock;
}
public void produce() {
System.out.println( "Producer: produce was called" ); //$NON-NLS-1$
System.out.println( "Producer: unlocking..." ); //$NON-NLS-1$
synchronized ( lock ) {
lock.unlock();
lock.notifyAll();
}
System.out.println( "Producer: exiting" ); //$NON-NLS-1$
}
private Lock lock;
}