Shallow Clone

A typical way of cloning an object is to use super.clone() to shallow-clone it, then modifying/cloning any members to create a complete clone.

Extra care must be taken if the original contains members that reference back to itself, e.g.


public class Model implements Cloneable {
  private PropertyChangeSupport support;
  private String name;

  public Model(String name) {
    support= new PropertyChangeSupport(this);
    this.name = name;
  }

  public void setName(String newName) {
    String oldName = this.name;
    this.name = newName;
    support.firePropertyChange("name", oldName, this.name);
  }
}

When this object is cloned the support member variable still references the original object (due to Object’s direct member assignment), thus the listeners would receive a wrong reference.

To fix this, implement a custom clone() method to take care of it. Make sure a new instance is created for it. If you simply change the reference inside the PropertyChangeSupport object, it will screw up the original object instead.


  public Object clone() {
    Model clonedModel = (Model)super.clone();
    clonedModel.support = new PropertyChangeSupport(clonedModel);
    return clonedModel;
  }

An Array of a List of Strings

I needed to create an Array of a List of Strings (actual problem anonymized). With generics I declared the variable:


List[] typedListArray;

Then I proceeded to create it.


typedListArray = new List[4]; // compile error

I needed to create the array first, like how I create new int[4];. But no matter how I moved the syntax, it wouldn’t compile. Read the JLS and searched the web, and finally found this explanation. It was not even a solution.

The reason the creation was disallowed was due to type erasure. Java’s implementation of generics only applies at compile time to ensure that the correct types are used. During runtime, the type information is erased. By creating a concrete parameterized array type, the runtime is unable to ensure that the correct items are added to the list. It is therefore senseless to allow the creation. The ways “around” it were to live with the warning, or to suppress it with annotations.

Then why allow the declaration?

Constructor Design

2 colleagues were in a “heated” argument over a design of constructors, which needed to have some form of the following parameters:

  • int code, String name, Serializable objParam
  • int code, String name, String xmlParam

The 3rd param could be either a String representing XML for an object, or a Serializable object. Both of them agreed there would be trouble differentiating between the two parameters, since Strings are serializable as well, and sometimes clients may want a String to be the Serializable param instead of XML.

To me it’s a non-issue, since the compiler is smart enough to use the String constructor if 3rd parameter was a String, and use the Serializable if I explicitly cast the String into Serializable (if I remember my signature-matching facts correctly).

One of them strongly pushed for a single constructor with 4 parameters, and passing in null for either the 3rd or 4th one. He argued this resolves ambiguity, as well as too many combinations of constructors available.

The other wishes to remove the optional 3rd parameter and use only 2 parameters. The 3rd parameter would be achieved using set methods.

Debate ensued, each bringing up points to support their views, such as cleanliness of API, ease of use, danger of forgetting to set the parameters, more parameters added next time. I wasn’t actually in the debate, I just happened to be the 3rd party in their chat window.

After a long while I suggested using static creational methods to differentiate between the 2 constructors. Something like Class.createXXXType() and Class.createYYYType() which I felt would be clear which “constructor” to refer to, non-ambiguity as well as stability of the instance created.

They didn’t take it very well too, and I left my suggestion as it is. There’s still no conclusion yet, they are still hesitating to call for a design review for this small matter.

Loop antipattern

Consider the following snippet:

boolean left = true;
int m = 0;
while (m < 2400) {
  System.out.println(left ? "left" : "right");
  left = !left;
  m++;
}

could be improved as:

for (int m=0;m<2400;m++) {
  System.out.println(m%2==0 ? "left" : "right");
}

The antipattern to be recognized here are:

  1. The number of iterations was known at compile-time. This is a hint to use for loops. Whiles are used when the number of iterations are unknown. Although it is possible to write it as a while loop, a for loop makes your intention concise, and less error-prone (such as forgetting to increment).
  2. Modulus can be used for "cycles". In this case it was a 2-item cycle, therefore a ternary operator was used. A cycle with more items can also be used by using an array to reference the items, then use array[m%array.length] to index the cycle item.

Disclaimer: Although the code was actually written (not by me), it is not meant to shame or blame. It is to be taken as a lesson for sharing and improvement.

Static methods in Inner classes

Hit this seldom seen compilation error while writing inner classes.


public class OuterClass {
	public class InnerClass {
		public static void InnerStaticMethod() {
		}
	}
}

This is what the compiler said:

The method InnerStaticMethod cannot be declared static; static methods can only be declared in a static or top level type

Java don’t like inner classes to have static methods, unless the inner class is static. A static inner class means you can instantiate the inner class without an enclosing outer class instance. One quick way to fix this situation is below, but note that you lose access to the outer class instance variables. InnerClass may also be instantiated without an OuterClass by new OuterClass.InnerClass(). Of course this can be prevented by limiting the access of the inner class.


public class OuterClass {
	public static class InnerClass {
		public static void InnerStaticMethod() {
		}
	}
}

Similarly, when the inner class is non-static, static member variables are not allowed. But static finals are permissible.

Breaking nested for loops

Not a question so common, but one that everyone will hit along the path of coding: breaking out of a nested for loop. A normal break will just take you out of the inner for loop.


System.out.println("before");
for (int i=0;i<3;i++) {
  for (int j=0;j<3;j++) {
    System.out.println("inside inner loop");
    break;
  }
  System.out.println("after inner loop"); // this will be printed
}
System.out.println("after everything");

To break out of the outer loop directly, label the outer loop using a... label. Then specify the label of the loop you'd like to break out of. You can name the label anything, as long as it's unique within its scope. It also works if you have higher levels of nesting -- by labelling the correct for loops you'll be able to break out of it correctly.


System.out.println("before");
outer: for (int i=0;i<3;i++) {
  for (int j=0;j<3;j++) {
    System.out.println("inside inner loop");
    break outer;
  }
  System.out.println("after inner loop"); // this won't be printed
}
System.out.println("after everything");

Java Virtual Hosting

I had a client recently who wanted a functional website built. By functional I meant he cared more about the features of his site than the design. Due to the site requirements and manpower issues on my side I initially recommended a Java web host. However as I started out in search of one, I soon realize that it was more challenging than I perceived.

Firstly, there were few Java web hosts. Despite being free to implement, there were many more PHP and ASP web hosts. Several blogs reasoned that there was difficulty supporting it, such as sharing JVM instances and Tomcat restarting.

Secondly, many of those Java web hosts I found did not come cheap. Due to the abovementioned reason those that do support it charge higher for it. There were some that were cheap, but those had shared instances or did not really know how to maintain a servlet engine. Some don’t allow restarts.

Thirdly, there isn’t that much demand in Java virtual hosting. This also added to the cost factor. Projects small enough will usually go for PHP or alternative technologies that are easier to implement, manage and have cheaper virtual hosting solutions. Projects big enough to use Java would have purchased their own boxes to deal with it.

Given these factors I would probably switch the project to PHP or not take it at all than to risk an unstable deployment.

Autoboxing

In Java SE 5, autoboxing was introduced to automatically convert between primitives and primitive wrappers. Primitives means basic types such as int, short, long, etc. Corresponding wrappers are Integer, Short, Long, and… nope, no Etc. To understand this, let’s look at the interaction between primitive and their wrappers before SE 5.


int originalInt = 3;

// convert primitive 3 to wrapper
Integer intWrapper = new Integer(originalInt);

// convert wrapper to primitive
int intPrimitive = intWrapper.intValue();

// store primitive in ArrayList
ArrayList list = new ArrayList();
list.add(new Integer(3));

// retrieve primitive in ArrayList
Integer wrapped = (Integer)list.get(0);
int unwrapped = wrapped.intValue();

// short-cut to retrieve primitive, less readable
int fastUnwrap = ((Integer)list.get(0)).intValue();

As shown above, a common usage of wrappers is when you need to store primitives as Objects. The ArrayList accepts an Object to be added, so it cannot add an int directly. However, we can make use of an Integer wrapper to put the number into the ArrayList, and take it out subsequently.

With SE 5, Java automatically generates necessary code to convert between primitives and wrappers during compilation. Let’s look at the new way with Autoboxing.


int originalInt = 3;

// convert primitive 3 to wrapper - Java will auto-convert
Integer intWrapper = originalInt;

// convert wrapper to primitive - Java will auto-convert
int intPrimitive = intWrapper;

// store primitive in ArrayList - generics added
ArrayList list = new ArrayList();
list.add(3);

// retrieve primitive in ArrayList
int unwrapped = list.get(0);

As you can see, all the scenarios have been simplified. Adding generics allows direct adding and retrieval of primitive types without any casting or wrapping. Despite being a useful convenient feature, programmers who pick up SE 5 directly without knowledge of the old way may not understand the rationale or even find it confusing (especially the ArrayList). Comparing and understanding the differences between the above code snippets will help in understanding Autoboxing.

Sending PDF for download

Symptom: When sending a PDF for download to IE, the error message appears:

There was an error opening this document. The file could not be found.

Cache-Control has been set to no-cache. Firefox works fine.

Cause: Unknown, IE specific problem with cache handling.

Solution: Set expiry date to trick browser that content expired. [1]


response.setHeader("Expires", "0");
response.setHeader("Pragma", "cache");
response.setHeader("Cache-Control", "private");

[1] http://drupal.org/node/18179