Monday, November 4, 2013

A handy hack for getting around Java type erasure

Once a Java class is compiled, any generic information is lost. Meaning that an ArrayList of Cars at runtime becomes an ArrayList and the fact that it stores Cars is lost.

There is a way around it, if you have access to the class or object that contains that ArrayList.

Lets take a simple domain object that contains a list : 
public class Domain {

 private List myList = new ArrayList();

 // Access methods removed
 
}
This class contains the list we want to inspect, the maguffin we're searching for. If we run that class through this inspector :
public class TypeInspector {

 public void inspect(Class clazz) {
  for(Field field : clazz.getDeclaredFields()) {
   if(isCollection(field)) {
    inspectType(field);
   } 
  }
 }
 
 private void inspectType(Field field) {
  String rawType = field.getGenericType().toString();
         rawType = rawType.substring(rawType.indexOf('<') + 1);
         rawType = rawType.substring(0, rawType.length() - 1);
           
         try {
   System.out.println(Class.forName(rawType));
  } catch (ClassNotFoundException e) {
   System.out.println("Couldnt find "+ rawType);
  }
 }

 private boolean isCollection(Field field) {
  return Collection.class.isAssignableFrom(field.getType());
 }
}

This inspector can retrieve the generic type from the field in the class that contains it. Parse the String description of the generic type to remove the ArrayList details which will give us our Maguffin.

Monday, July 22, 2013

A simple way to avoid a lot of null pointers

This is something I see all the time and a slight code change can remove a lot of null pointer exceptions.

public class NullExample {

 private static final Integer ZERO = 0;
 
 public static void main(String args[]) {
  
  //Bad Way
  System.out.println("1 -> " + checkEqualToZeroPoor(1));
  System.out.println("0 -> " + checkEqualToZeroPoor(0));
  try {
   checkEqualToZeroPoor(null);
  } catch(NullPointerException e) {
   System.out.println("Null throws an exception");
  }
  
  // Good Way
  System.out.println("1 -> " + checkEqualToZeroGood(1));
  System.out.println("0 -> " + checkEqualToZeroGood(0));
  try {
   System.out.println("Null -> " + checkEqualToZeroGood(null));
  } catch(NullPointerException e) {
   System.out.println("This should never be reached");
  }
 }
 
 public static boolean checkEqualToZeroPoor(Integer value) {
  // A null pointer exception will be thrown
  return value.equals(ZERO);
 }
 
 public static boolean checkEqualToZeroGood(Integer value) {
  // Should return false on null
  return ZERO.equals(value);
 }
}

In the 'poor' example, the parameter's .equals method is being used to check equality with our static value. By switching these two we can ensure that the object on which the .equals method is always initialized and never null.

Granted, this example ignores the third case, which gives the same result as the better method but is not advisable.


// Worse way
System.out.println("1 -> " + (1 == ZERO));
System.out.println("0 -> " + (0 == ZERO));
System.out.println("null -> " + (null == ZERO));

While this might seem incredibly basic, it still happens on a daily basis




Monday, July 15, 2013

The Broken Window Theory

The 'Broken Window' is a theory in criminology regarding urban disorder and vandalism

Quoted from wikipedia :
Consider a building with a few broken windows. If the windows are not repaired, the tendency is for vandals to break a few more windows. Eventually, they may even break into the building, and if it's unoccupied, perhaps become squatters or light fires inside.
This translates very well to  software development, as soon as minor smells are introduced, these 'Broken Windows' start to multiply until there is massive backlog of neglect that need to be fixed. 

Quoted from Coding Horror:
Don't leave "broken windows" (bad designs, wrong decisions, or poor code) unrepaired. Fix each one as soon as it is discovered. If there is insufficient time to fix it properly, then board it up. Perhaps you can comment out the offending code, or display a "Not Implemented" message, or substitute dummy data instead. Take some action to prevent further damage and to show that you're on top of the situation.We've seen clean, functional systems deteriorate pretty quickly once windows start breaking. There are other factors that can contribute to software rot, and we'll touch on some of them elsewhere, but neglect accelerates the rot faster than any other factor.
 Places I stole the quotes from :
http://www.codinghorror.com/blog/2005/06/the-broken-window-theory.html
http://en.wikipedia.org/wiki/Broken_windows_theory

Friday, July 12, 2013

How clean is your code?

A big part of programming anything is that its readable to the next person who comes along and reads it. Remember that code is read far more times than its written.

Lets take a fairly well known problem as an example. The FizzBuzz problem :

Write a program that prints the numbers from 1 to 100. But for multiples of three print "Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz".

And a basic implementation of the solution :

public class FizzBangDirty {

public static void main(String[] args) {
for(int i=1; i< 101; i++) {
System.out.print(i + " ");
if(i % 3 == 0){
System.out.print("Fizz");
}
if(i % 5 == 0){
System.out.print("Buzz");
}
System.out.print("\n");
}
}
}

The solution in it self doesn't  read particularly well. 

  • The main method is 9 lines long, arguably too long
  • At no point does the method state what its doing, only how it's doing it. 

How about a cleaner solution :

public class FizzBangDirty {

private static final int START_VALUE = 1;
private static final int END_VALUE = 100;
public static void main(String[] args) {
for(int i=START_VALUE; i<= END_VALUE; i++) {
printCurrentValue(i);
printFizzBang(i);
}
}

private static void printFizzBang(int i) {
printFizz(i);
printBang(i);
printNewLine();
}

private static void printBang(int i) {
if(multipleOfFive(i)){
System.out.print("Buzz");
}
}
private static void printFizz(int i) {
if(multipleOfThree(i)){
System.out.print("Fizz");
}
}
private static void printCurrentValue(int i) {
System.out.print(i + " ");
}

private static void printNewLine() {
System.out.print("\n");
}

private static boolean multipleOfThree(int i) {
return i % 3 == 0;
}

private static boolean multipleOfFive(int i) {
return i % 5 == 0;
}
}

The cleaner solution has a few downsides :
  • Its twice as long.
  • Throws reuse out the window.

What it lacks in brevity, its makes up for in explicitly explaining what its intention is for each line of code, not just what its trying to accomplish.

Noteworthy points :
  • The for loop explicitly states what is being done on each value in the loop
  • The conditions in every if() are a method call, it allows the line to read like an English sentence, giving it far more meaning. So 'if(multipleOfFive(i))' reads simply as 'if multiple by 5' . It also allows the code to be written in the language that descrbed it in the first place.
  • No method is longer than 3 lines long.
  • There is only 1 public method. Implying that there is only 1 important part of this solution. The rest are just supporting, and can be ignored until necessary to pay closer attention to them.