Friday, May 16, 2014

I Code Java : A Blog on Java Generics and Methods






This blog is inspired by the book “Effective Java” by Joshua Bloch. It is quintessential step to write good methods since these methods are exposed as APIs to other set of classes and packages.

Why should we all use Java methods?

  • For reusable code
  • For top down programming
  • To create conceptual units


Guidelines for writing a good Java method?

  • Whenever a method is exposed to an outside entity, we cannot make assumptions for the type of arguments which would be sent when the method is invoked.
  • Firstly if there is an operation performed over the arguments, we must assert for null ability. 
  • There are many ways in which we could make it null safe. We could use documentation, annotations or explicit null checks in the method. 
  • Documentation using JavaDocs is necessary but not sufficient. 
  • Annotations helps to preserve the sanity of the method but still results in runtime validation exceptions. 
  • Explicit null checks when done properly help in avoiding any runtime errors. Using all the above 3 ways in conjunction with each other is a good practice.

Ex:


/** Checks the equality of the given input arguments. 

* @args obj1      Object  1st argument
* @args obj2      Object  2nd argument
* @returns Boolean True if both are equals, False if not equal

**/
Boolean isEqual(Object obj1, Object obj2) {

                if (obj1 == null && obj2 == null)
                                return true;
                if (obj1 == null || obj2 == null)
                                return false;
                if (obj1.getClass() != obj2.getClass())
                                return false;
                return obj1.equals(obj2);
}


Specify the type of parameters as precise as possible. If the type of the argument can be subclasses, the method needs to ensure type safety.

Guidelines for using Java Generics

Generics is been a boon to java developers since its introduction in Java 1.6. Generics brings in a lot of freedom and abstraction to the developer. Consider the example below.


Abstract Class Shape {
}
Class Polygon extends Shape {
                int sides;
}
Class Pentagon extends Polygon {
                public Polygon (int sides) {
                                this.sides = sides;
                }
}
Class Circle extends Shape {
                int radius;
}
// Incorrect Way
Boolean getNumberOfEdges( <? extends Shape> foo){
                // business Logic
}
// Correct way
Boolean getNumberOfEdges( <? Extends Polygon> foo){
                // business logic
}
In the above example, we have restricted the type of object to anything of type Polygon as we expect instances of Polygon only to have edges. Whereas this is not guaranteed for all classes which extend the parent class Shape.

To end on a funny note!


















References:
[1] : http://uet.vnu.edu.vn/~chauttm/e-books/java/Effective.Java.2nd.Edition.May.2008.3000th.Release.pdf
[2] : http://java.dzone.com/articles/5-things-you-should-know-about-java-generics
[3] : http://www.tutorialspoint.com/java/java_methods.htm
[4] : http://www.leepoint.net/JavaBasics/methods/method-commentary/methcom-purpose.html

1 comment:

  1. One of the good thing in your post is the guidelines that you have provided for writing good Java methods which I feel many programmer dont follow.I will try to follow the guidelines you have mentioned

    ReplyDelete