Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Tuesday, 15 September 2009

Covariant Return Types in Java 5

Covariant return types are one of the newly added features in Java 5. Using covariant return types, an overridden method in a derived class can return a type derived from the type returned by the base-class method.

For example in the Java versions prior to Java 5, the following would have thrown a compile time error.

class Vehicle
{
Vehicle myFunc(){return this;}
}

class Car extends Vehicle
{
// myFunc() returns Car, which is a subclass of Vehicle
Car myFunc(){return this;}
public void printMe(){ System.out.println("I am a Car");}
}

public class Covariant {

public static void main(String args[]) 
{
Car car = new Car();
car.myFunc().printMe();
}
}

CompileTime Error: The return type is incompatible with Vehicle.myFunc()

Prior to Java 1.5, to remove this error you had to make 2 changes.

1. Change the return type of derived class myFunc() to Vehicle and
2. Downcast Object being returned by car.myFunc() to Car

Java 5 lets you get away with that and makes the above code work just fine.

Wednesday, 20 May 2009

Java Tips - Always Override toString()

I am sure all of us at some point in time of our software development career, would have done an SOP on an object, expecting to see an interpretable string value but were displayed a string, which could not add much to our understanding.

Though java.lang.Object provides a default implementation of toString() method, I dont think its really informative. The returned string consists of the class name followed by an @ sign and an unsigned hexadecimal representation of the hash code, for example, Employee@235b92.

Actually The contract for the toString() method says that the returning string sould be concise, easily readable and also all the subclasses should override it. Though it can be argued that Employee@235b92 is concise and small enough to read, but it certainly is not very informative.

Joshua Bloch suggests to override toString() method so that a suitable string interpretation of your object can be returned. Providing a good string implementation makes your class much more pleasant to use. Overriding toString() appropriately not only is beneficial to instances of your class, but it is also useful for the objects containing instances of your class. For example if you want to print the contents of a hashmap containing instances of your class, I am sure anyday you would prefer to see a Employee@BillGates_CTO over Employee@235b92.

Ideally, the toString() method should contain all the interesting information about the object. But if the object is really large it might not be possible to include all the information in returning string. In that case you can make it return something which provides a small summary of the object.

I know that you are not really familiar with this approach and might not find it a value adding practice but I would still recommend that you start using it and I am sure that soon you would start appreciating it's benefits.

Friday, 24 April 2009

Array Access Evaluation Order in Java

Consider the java program written below and then guess its output.
public class ArrayEvaluationOrder {
public static void main(String[] args) 
{

int[] aryA = { 10, 20, 30, 40, 50, 60 };
int[] aryB = { 1, 2, 3, 4, 5, 6 };

System.out.println(aryA[(aryA=aryB)[4]]); //1
System.out.println(aryA[(aryA=aryA)[4]]); //2
System.out.println(aryA[(aryA=aryB)[3]]); //3
}
}
The output is:
60
6
5

If you are scratching your head, let me be of some assistance and explain the reason behind this.

As per Array Access Evaluation Order in java, in case of an array access, the expression to the left of the brackets is fully evaluated before any part of the expression within the brackets is evaluated.

For example consider the following line of code:
System.out.println(aryA[(aryA=aryB)[4]]); 
The expression aryA is fully evaluated before the expression (aryA=aryB)[4] is evaluated. This means that the original value of aryA is fetched and remembered while the expression (aryA=aryB)[4] i.e. 5 is evaluated.

Since aryA still remembers its original value aryA[5] returns 60. But after the execution of this line, aryA and aryB both would be pointing to array pointed to by aryB.

I would leave figuring out the rest of the output to you.
 
Technology