Java7
Posts tagged java code convention
Writing Java Codes For Maintenance
Mar 22nd
Lets look at a real life example piece of code.
private long getDetailsSum2(BIBFileEntry entry, String paddedAmount) {
return
Long.parseLong(entry.get...().substring(2, 4)) +
Long.parseLong(entry.get...().substring(2)) +
Long.parseLong(entry.get...().substring(2, 4)) +
Long.parseLong(entry.get...().substring(6, 8)) +
Long.parseLong(entry.get...().substring(10)) +
Long.parseLong(entry.get...().substring(1)) +
Long.parseLong(paddedAmount.substring(2, 4)) +
Long.parseLong(paddedAmount.substring(6, 8)) +
Long.parseLong(paddedAmount.substring(10));
}
This piece of code adds together multiple Long values, each converted from a string literal. There is no bounds checking, so any if these may cause a null pointer or number format exception, which is alright (legal) .. One day, the service fails and complains with a number format exception.
Caused by: java.lang.NumberFormatException: For input string: "7 "
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Long.parseLong(Long.java:419)
Yet there is no place you may set your breakpoint to inspect which of the lines is the one that is causing you a number format exception because all the compiler determines the next line by the semi-colon token ( ; ) terminator.
[Short Primer] How the compiler interprets your codes To the extend, if you have written this piece of code:
int sum = (1 + 1) +
(2 + 1) +
(3 + 1);
The compiler sees it no differently from:
int sum = (1 + 1) + (2 + 1) + (3 + 1);
Therefore, in the earlier example, setting a breakpoint in the line “(2 + 1) +” has no effect.
The solution, break your concatenation such that you may step through using your compiler line by line.
private long getDetailsSum1(BIBFileEntry entry, String paddedAmount) {
Long details[];
details = new Long[9];
details[0] = Long.parseLong(entry.get...()).substring(0, 2);
details[1] = Long.parseLong(entry.get...().substring(0, 2));
details[2] = Long.parseLong(entry.get...().substring(0, 2));
details[3] = Long.parseLong(entry.get...()).substring(4, 6));
details[4] = Long.parseLong(entry.get...().substring(8, 10));
details[5] = Long.parseLong(entry.get...().substring(0, 1));
details[6] = Long.parseLong(paddedAmount.substring(0, 2));
details[7] = Long.parseLong(paddedAmount.substring(4, 6));
details[8] = Long.parseLong(paddedAmount.substring(8, 10));
return details[0] + details[1] + details[2] + details[3] + details[4] + details[5] + details[6] + details[7] + details[8];
}
Revision History March 23, 2011 – More brevity and example on how the compiler interprets code.
Use Sun Java Packaging Convention, please. :P
Jan 3rd
Not because we were instructed to, or for maintainability sake (although it is also), but when it means trouble (big one) not doing so, is the focal point of this discussion today. Failing to adhere to the standard convention could result in drastic and sometimes fatal code refactoring and a whole range of unit testings and fixing aftermaths.
Why is it that the Sun Java code convention dictate us or even to come up with the idea to use our organization’s internet namespace and sometimes together with unique project names?
Consider this case study:
You are in team A working on the “Singapore Bus Timetable Management System”. (A bespoke system that manages bus timetable!)
Gary is in team B working on the “Trans Temesek Singapore Bus Management System”. (Also a Singapore company, besides the point actually.)
Now, both you and Gary wrote a Calendar utility class called MyCalendar.java and both placed it in the package production.utils. Both calendar utility classes does different things, your utility class mingles with Juliet calendar, and Gary’s utility class mingles with a little Juliet calendar and more Gregorian calendar, coincidentally. After code review, the project architect decided to reuse both calendar utility classes for future projects.
Thats where the problem starts.
Now, supposing that team C decides to use both calendar utility class, your MyCalendar.java and Gary’s MyCalendar.java. Both utility classes are packaged under the same namespace production.utils. How would team C be able to use both from within the same class in project C?
This simply does not work!
import production.utils;
public class TeamC{
public static void main(String args[]){
// use Gary's calendar
MyCalendar.getDate();
// use your calendar
MyCalendar.getDate();
}
This does not work either because the Java compiler is unable to differential and determine which MyCalendar implementation to link.
public class TeamC{
public static void main(String args[]){
// use Gary's calendar
production.utils.MyCalendar.getDate();
// use your calendar
production.utils.MyCalendar.getDate();
}
How to solve this problem?
- Use Sun Java Code Convention for Packaging
Gary’s MyCalendar.java packaged under the sg.java.projectA.utils namespace
package sg.java.projectA.utils;
/**
* @Author Me
*/
public class MyCalendar{
public static String getDate(){
...
}
}
Gary’s MyCalendar.java packaged under the sg.java.projectB.utils namespace
package sg.java.projectB.utils;
/**
* @Author Gary
*/
public class MyCalendar{
public static String getDate(){
...
}
}
So team C, when trying to reference both MyCalendar utility class may do so like:
Note that you may not do an import for both classes using the import statement tho, and must reference their fully qualified name in the code.
public class TeamC{
public static void main(String args[]){
// using your calendar utility class
sg.java.projectA.utils.MyCalendar.getDate();
// using Gary's calendar utility class
sg.java.projectB.utils.MyCalendar.gerDate();
}
}
(I have commonly seen Microsoft .NET import statements to be like use namespace bean; use namespace utils; and i assume such convention either do not exist, existed late, or makes no sense to enforce in the .NET paradigm, can someone from .NET share this with us please?)