Anti-pattern: An anti-pattern (or antipattern) is a common response to a recurring problem that is usually ineffective and risks being highly counterproductive. The term, coined in 1995 by Andrew Koenig, was inspired by a book, Design Patterns, in which the authors highlighted a number of design patterns in software development that they considered to be highly reliable and effective. — source http://en.wikipedia.org/wiki/Anti-pattern
Here at Schuberg we spend quite some time going through bugs reports from automated scanners, you have probably seen the mails coming by on the ML. As part of our work we have encountered a number of problems that keep on popping up in the code base. So here is my first attempt to clarify why a certain pattern is wrong and hopefully help developers to avoid this. So first up is the equality operator, ==. This operator is commonly used in many languages to compare if two items are equal. The trick with this operator in java is to know exactly what you are comparing, because it matters. Consider this piece of code: public class App { public static void main(String[] args) { int a = 1; int b = 1; if (a == b) { System.out.println("Equal!"); } else { System.out.println("Different!"); } } } The expected outcome is “Equal!” and indeed it prints just that. Now consider the following code: public class App { public static void main(String[] args) { Integer a = new Integer(1); Integer b = new Integer(1); if (a == b) { System.out.println("Equal!"); } else { System.out.println("Different!"); } } } The result of running this bit of code is “Different!”. With == you are telling the java compiler to compare the two variables. The variable are references to Objects, so it will do exactly what you tell it to do, compare the two object references. As you give it two different objects, the result willl be “Different!”. The correct way of comparing the contents of two objects is to use the equals method. Consider the following piece of code: public class App { public static void main(String[] args) { Integer a = new Integer(1); Integer b = new Integer(1); if (a.equals(b)) { System.out.println("Equal!"); } else { System.out.println("Different!"); } } } This will again be “Equals!”. Why is this often a problem? There are a lot or reasons why these bugs came to exist in CloudStack (or any other project). For example somebody might cause this bug by changing the return type of a function from long to Long. The first one is a primitive which can be compared with == and the second one is an Object which might result in another comparison than you intended. Findbugs will catch these types of comparisons and warn you for them. See commit d1efdca50622a0b67ae1a286aad3297b1c748e9e for an example. Oh and what does this print? public class App { public static void main(String[] args) { Integer a = 1; Integer b = 1; if (a.equals(b)) { System.out.println("Equal!"); } else { System.out.println("Different!"); } } } Surprise!, it prints “Equals!”. This is a boxed integer and java keeps a pool of these so internally the object is cached and both a and b get the same objects assigned to them by the internal boxing logic. Just never rely on this! It only works in specific cases and is implementation specific per JVM vendor and JVM version. Cheers, Hugo P.S. If you have another anti pattern feel free to post em in this thread.