Sunday, November 22, 2009

Array of Generic Type

I was asked why one cannot create an array of generic type, which means this line cannot compile:


// the below doesn't compile
ArrayList<Integer>[] arrayOfLists = new ArrayList<Integer>[7];


The compiler doesn't like the creation part, on the right, while the declaration alone, on the left, goes fine. This issue is widly discussed, e.g. nicely described here.

There are many ideas why it is forbidden and many suggestions for workarounds. But the nice colleague who asked me this question liked the most the workaround I suggested him, which is very simple.

I started by asking why he needs this.

And he explained that he needs to manage some info for 7 days a week:


// the below doesn't compile
ArrayList<SomeInfo>[] weeklyInfo = new ArrayList<SomeInfo>[7];


I suggested to create two new classes, DailyInfo and WeeklyInfo:


class DailyInfo {
    private ArrayList<SomeInfo> dailyInfo = new ArrayList<SomeInfo>();
    ...
}

class WeeklyInfo {
    private DailyInfo[] dailyInfo = new DailyInfo[7];
    ...
}


In most cases this would be the right object oriented approach, which by the way solves the problem of array of generic type.

Wednesday, October 7, 2009

m and n have switched on my keyboard...

The letters 'm' and 'n' have been switched. I type 'm' and it comes out as 'n'. I remember something about a virus so I run my anti-virus (no result) and search the web (some results).

       Cone om! I’n beconimg imsame!

It's so annoying. Maybe someone is fooling around with me.

A quick glance at another keyboard: it's not that 'm' types 'n' -- the keys themselves changed places... each sits at the other one's location. A quick pull of the keys, stucking them again back into their right position and everything is great!

After a short investigation it appears that my 6 years old son, who is using my computer for playing, accidentally popped out the 'm' and 'n', then put them again in place quickly before I'll notice. Well, almost in place... He didn't intentinally planned for giving me a hoax, though it came out quite a good one for his age.

Wednesday, September 23, 2009

Auto-unboxing hazard -- the three states of Boolean: TRUE, FALSE, and...

What do you say about the following code:

boolean isActive = (Boolean) pageContext.getAttribute(IS_ACTIVE);
if(isActive) {
// dosomething
}

If you are worried about the casting to Boolean in case where attribute IS_ACTIVE doesn't exist, don't worry, it's OK to cast null to any type, null stays null.

So, is it OK?

Well, no. The problem is with the auto-unboxing to primitive type boolean, which throws NullPointerException if the Boolean is null. Which is a bit hidden from the programmer who might miss this hazard when writing the code.

How should we fix it?

Is the following a decent fix:

Boolean isActive = (Boolean) pageContext.getAttribute(IS_ACTIVE);
if(isActive) {
// dosomething
}

If you ask "what's the fix?" - we turned the variable isActive to be Boolean rather than boolean. Which should eliminate any NullPointerException on the first line! But only in order to pass the exact same NullPointerException into the 'if'...

So, what about:

Boolean isActive = (Boolean) pageContext.getAttribute(IS_ACTIVE);
if(isActive.booleanValue()) {
// dosomething
}

Yes, you are right, same NullPointerException. Maybe now even more explicit.

We could go with:

Boolean isActive = (Boolean) pageContext.getAttribute(IS_ACTIVE);
if(isActive != null && isActive) {
// dosomething
}

But I believe this looks better:

Boolean isActive = (Boolean) pageContext.getAttribute(IS_ACTIVE);
if(Boolean.TRUE.equals(isActive)) {
// dosomething
}