Multi-author java tips blog

I’m toying with the idea of a multi-author Java tips blog, and am looking for possible contributors. If there is sufficient interest, I’ll be able to setup a subdomain to host the blog.

Please do contact me at redemption at codefront.net should you be interested. This is (what I foresee) a good opportunity to share your experience and expertise with the Java community via the informal weblog medium.

UPDATE: I’ve setup a subdomain at http://javatips.codefront.net/.

Java Tip #2: Static factory methods vs. constructors

Factory methods are simply methods that instantiate objects. Some factory methods in the Java 2 API that you would likely have used are the getInstance() and valueOf() methods. getInstance() is the conventional instantiation method in singletons, while valueOf() are often type-conversion methods, like in String.valueOf(int i).

Providing a static factory method instead of a public constructor has both advantages and disadvantages, which will be discussed at length in the rest of this entry.

Static factory methods have names
A class can have only a single constructor with a given signature, which is a restriction in cases where a class needs to be able to be instantiated using identical parameter lists. In cases like this, you can replace constructors with static factory methods with more intuitive names that highlight their differences.

Static factory methods can improve performance
This is because static factory methods do not have to actually instantiate new objects each time they are invoked. This is what allows for the Singleton pattern, where a single instance is returned. It also allows instances to be cached within the object in cases where object instantiation is expensive (like for the case of instantiation of fields from a database) or frequently done.

Static factory methods can return a subtype of their return type
This allows for interfaces to be returned by static factory methods, which is best exemplified in the Collections Framework. Needless to say, forcing a client to refer to the returned object by its interface rather than its actual class is a good practice.

Also, the class of the object returned can be private (non-public), so there is a degree of encapsulation where the private class can be modified without impacting clients of the API (possibly for bug-fixing or improvements, or just plain maintainence). The private classes can also vary depending on the parameters to the static factory, so long as they are subtypes of the return type, allowing for greater flexibility.

Classes without public or protected constructors cannot be subclassed
This is an unavoidable fact, so classes designed for inheritance must have at least 1 public constructor to be able to be subclassed.

The verdict? Use static factory methods for a more intuitive API, to improve performance via object-caching, to implement singletons, in interface-based frameworks, and to return objects of private classes. Use constructors in classes designed for inheritance (there shouldn’t be many of these) and for greater visibility in API documentation (since they appear in a separate table in standard Javadocs).

Java Tip #1: Defensive copies

Something that could easily be missed when programming in Java is inadvertently exposing the internals of a supposedly encapsulated field to clients of your class. Consider the following naive implementation of a rectangle class that disallows negative dimensions:

public final class MyRectangle {
private final Dimension dim;

public MyRectangle(Dimension dim) {
if( dim.height < 0 || dim.width < 0 ) {
throw new IllegalArgumentException("Dimensions cannot be negative");
}

this.dim = dim;
}

public int getArea() {
return dim.height * dim.weight;
}
}

A cursory glance may seem indicate that the class should be immutable and no negative dimensions, and thus no negative areas, are possible. Not true. Consider this bit of code that uses the MyRectangle class:

Dimension dim = new Dimension(2, 3);
MyRectangle rect = new MyRectangle(dim);
dim.setSize(-3, 4); // modifies rect's internal Dimension field!

This is possible because Dimension is a mutable class! Therefore, it is important to make a defensive copy of each parameter to the constructor that is mutable. We can fix the MyRectangle class by changing it’s constructor like so:

public MyRectangle(Dimension dim) {
this.dim = new Dimension(dim); // make defensive copy

if( dim.height < 0 || dim.width < 0 ) {
throw new IllegalArgumentException("Dimensions cannot be negative");
}
}
Notice how a copy of the Dimension parameter is made, so that the client has no reference (and thus no access) to the internal dim field of the MyRectangle object. The same has to be done in the case where accessors return mutable fields - make sure to return defensive copies. The rule is never to directly return the internal field to a client class - always create a defensive copy and return that instead, so that there is no handle into the object internals.