Friday, August 20, 2010

Java Common Mistakes (Part 1)

1. Returning Null, a method which returns a collection or an array,
Null should never be returned from a method returning a collection or an array. Instead return a empty array (a static final empty array) or one of the empty collections (e.g. Collections.EMPTY_LIST assuming the client should not be modifying the collection).

2. Unnecessary use of thread safety of StringBuffer
Use StringBuilder rather then StringBuffer, unless synchronization is required. StringBuilder is not thread safe, and therefore avoids the synchronization overhead of StringBuffer.

3. Not taking advantage of ‘toString()’
Overriding toString() method gives you a cheap way to provide human-readable labels for objects in output.

Bad:
System.out.println("Author: "+person.getName());

Good:
class Person {
...
public String toString() {
return this.getName();
}
}
...
System.out.println("Author: "+person);

4. Instatiation of immutable objects
Creating new instances of immutable primitive type wrappers (such as Number subclasses and Booleans) wastes the memory and time needed for allocating new objects. Static valueOf() method works much faster than a constructor and saves the memory, as it caches frequently used instances.

Bad:
Integer i = new Integer(0);
Boolean b = new Boolean(true);

Good:
Integer i = Integer.valueOf(0);
Boolean b = Boolean.valueOf(true); // or Boolean.TRUE

5. Unbuffered I/O
Reading and writing I/O streams byte-by-byte is too expensive, as every read()/write() call refers to the underlying native (JNI) I/O subsystem. Usage of buffered streams reduces the number of native calls and improves I/O performance considerably.

Bad:
InputStream in = new FileInputStream(f); int b; while ((b = in.read()) != -1) {     ... }
Good:
InputStream in = new BufferedInputStream(new FileInputStream(f));
...


6. ‘equals()’ does not check for null argument

If you override equals() method in your class, always check if an argument is null. If a null value is passed, equals() must unconditionally return false (no NullPointerException should be thrown!).

Bad:
class Person {
...
public boolean equals(Object o) {
return (o instanceof Person) &&
this.getName().equals(((Person)o).getName());
}
...
}

Good:
class Person {
...
public boolean equals(Object o) {
return (o != null) &&
(o instanceof Person) &&
this.getName().equals(((Person)o).getName());
}
...
}

class Person {



public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Person))
return false;

Person that = (Person)o;
….

7. ‘equals()’ is overridden while ‘hashCode()’ is not
If you override equals() in your class, always provide a custom implementation of hashCode() that returns the same hash code value for two or more equal objects:

a.equals(b) ? a.hashCode() == b.hashCode()

This is, in fact, a general contract defined by Java API Specification. Violation of this rule (which is likely the case if equals() method is overridden while hashCode() is inherited from Object) may cause numerous bugs and unexpected behaviours.

Note that the reverse rule: two or more unequal objects must have different hash codes, or

!a.equals(b) ? a.hashCode() != b.hashCode()


8. Difference between == and .Equals() Method

Value Type: == and .Equals() methods compare two objects by value.

Ex: int a = 5; int b = 5;

Console.WriteLine(a==b); Output: true
Console.writeLine(a.Equals(b)); Output: true

Reference Type: == performs an identity comparison, i.e. it will only return true if both references point to the same object.

While Equals() method is expected to perform a value comparison.

Ex: StringBuilder s1 = new StringBuilder(“Yup”);

StringBuilder s2 = new StringBuilder(“Yup”);

Console.WriteLine(s1==s2); Output : false

Console.WriteLine(s1.Equals(s2)); Output: true

In above example, s1 and s2 are different objects hence “==” returns false, but they are equivalent hence “Equals()” method returns true.

Note: There is an exception of this rule, i.e. when you use “==” operator with string class it compares value rather than identity.

When To use:

For value comparison, with Value Tyep use “==” operator and use “Equals()” method while performing value comparison with Reference Type.


1 comment:

  1. Just amazing! Loved your post. Please continue posting! Best wishes.

    ReplyDelete