Monday, May 26, 2008

Daemon threads in Java

Threads that work in the background to support the runtime environment are called daemon threads. For example, the clock handler thread, the idle thread, the screen updater thread, and the garbage collector thread are all daemon threads. The virtual machine exits whenever all non-daemon threads have completed.

public final void setDaemon(boolean isDaemon)
public final boolean isDaemon()

By default a thread you create is not a daemon thread. All the user applications are generally started off as non-daemon threads. However you can use the setDaemon(true) method to turn it into one.

Thursday, May 22, 2008

Covariant return type

A covariant return type means changing a method's return type when overriding it in a subclass. Covariant return types were allowed in the Java language since the release of JDK5.0. I will try to illustrate the use of covariant return type using the following example.

class A
{
public List test()
{
return null;
}
}
class B extends A
{
public ArrayList test()
{
return new ArrayList();
}
}
Here we can see that the return type of the method test() in subclass B is the subclass of the return type of method test() in the superclass A.

Wednesday, May 21, 2008

Contract between the subclass and superclass

The following is an excerpt from the book 'The Java FAQ' .. "An API (application programming interface) establishes a contract of intent, not just of form or interpretation. To borrow terminology from linguistics and philosophy, an API contract involves both extension and intension: the boundaries of the current state of the world (extension) as well as the intended boundaries for other possible states of the world (intension: possible future implementations). In object-oriented programming, a common source of "possible future implementations" is subclassing from an existing class in an API.
A method defines a contract for any subclass method that would override it; it constrains possible implementations that a subclass could provide. In Java, the bare minimum contract for a method's inputs and outputs is the following:

* A method's parameter list is fixed; an overriding method in a subclass must declare precisely the same number and types of arguments.
* A method's return type is fixed; an overriding method in a subclass must declare precisely the same return type.
* The set of checked exceptions a method can throw (the method's declared exception classes and all their subclasses) establishes an upper bound. An overriding method in a subclass cannot throw any checked exceptions outside of that; it can, however, throw fewer exception types, or even none at all.

Note that the contract on exceptions concerns only checked exceptions; errors and runtime exceptions (that is, Error, RuntimeException, and their subclasses) are always permitted.
If a method, such as Object's toString method, is declared as throwing no checked exceptions, any overriding method you define must live within those bounds. You cannot define your own subclass of Exception and have your toString method throw that. In such a case, if you really need some exception to be thrown, you can resort to a subclass of RuntimeException, which is not checked or constrained by the compiler."

This description basically covers all the rules that a subclass must follow when overriding a method from superclass.

Tuesday, May 20, 2008

What does a constructor do?

The constructor helps initializing the state of the object. So initially the implicit or the defined no-argument constructor of the super class is called so that the parent gets initialized in a proper manner.


One more restriction that is being imposed when a constructor is being defined is that call to any explicit super class constructor must be the first statement of all the constructors. So this might sound like a weird restriction at first but this rule guarantees the parent object to be in a valid state before the child object gets operational. This would help in avoiding the situations like this :


class Date{
public Date(){ date = setDate... }
String date;
}

// what if?
class DateViewer extends Date{
public DateViewer(){
System.out.println("The Date: " + date);
super();
}
}

Another thing that must be kept in mind while dealing with the constructors is that once you define a non-default constructor with non-zero arguments then and there the implicit constructor's definition inserted is removed from the code. So now if you have two classes X and Y such that
class Y
{
Y(int x,int y)
{

}
}

class X extends Y
{

}

Now this will result in a compilation error in the class X..Because the JVM tries to call the super() method while initializing the child object but since there is not implicit constructor for the parent class, this results in a error. Also see this amusing thread on sun forum:

http://forum.java.sun.com/thread.jspa?threadID=731805&start=0&tstart=0

Tuesday, May 13, 2008

About null in Java

In Java(tm), "null" is not a keyword, but a special literal of the null type. It can be cast to any reference type, but not to any primitive type such as int or boolean. The null literal doesn't necessarily have value zero. And it is impossible to cast to the null type or declare a variable of this type.

Friday, May 9, 2008

Implementation of a multithreaded singleton in Java


package yn.graph;

/**
* @author ny
*
*/
public class MultithreadedSingleton {
private static final MultithreadedSingleton singleton = new MultithreadedSingleton();

private MultithreadedSingleton() {
synchronized (MultithreadedSingleton.class) {
//initialize the variables
}
}

public static MultithreadedSingleton getSingleton() {
return singleton;
}

private static class TestMultithreadedSingleton implements Runnable {
@Override
public void run() {
MultithreadedSingleton sgt = getSingleton();
System.out.println(sgt);
}
}

/**
* @param args
*/
public static void main(String[] args) {
new Thread(new TestMultithreadedSingleton()).start();
new Thread(new TestMultithreadedSingleton()).start();
new Thread(new TestMultithreadedSingleton()).start();
new Thread(new TestMultithreadedSingleton()).start();
new Thread(new TestMultithreadedSingleton()).start();
}
}