findbugs is objecting to anonymous inner class

Steve Atkinson picture Steve Atkinson · Feb 24, 2014 · Viewed 16.5k times · Source

This code:

Set<Map.Entry<String, SSGSession>> theSet =  new TreeSet<Map.Entry<String, SSGSession>>(new Comparator<Map.Entry<String, SSGSession>>() {

        @Override
        public int compare(final Map.Entry<String, SSGSession> e1, final Map.Entry<String, SSGSession> e2) {
            return e2.getValue().getStartTime().compareTo(e1.getValue().getStartTime());
        }
    }));

triggers a violation in Sonar, tripping the findbugs rule "SIC_INNER_SHOULD_BE_STATIC_ANON" which has the description:

This class is an inner class, but does not use its embedded reference to the object which created it. This reference makes the instances of the class larger, and may keep the reference to the creator object alive longer than necessary. If possible, the class should be made into a static inner class. Since anonymous inner classes cannot be marked as static, doing this will require refactoring the inner class so that it is a named inner class.

Really? Isn't this very nit-picky? Should I really refactor a one line method in an anonymous inner class to save the cost of an extra reference ? In this case, there's no possibility of it holding the reference longer than necessary.

I don't mind doing it as our strongly enforced coding standards are "zero sonar violations" but I'm strongly tempted to argue the case for a //NOSONAR here, as imho extracting a one line method to a static inner makes the code slightly harder to grok.

What do the java purists think?

Answer

hyde picture hyde · Feb 24, 2014

Converting comments to answer, first of all I could be persuaded that having this as anonymous inner class can be justified, even if there's a clear technical reason for being nit-picky about this.

Still, I would say: Follow the rules you have set. Rules create consistency, and when all the code is written the same way, the code base is easier to understand as a whole. If some rule is bad, disable it everywhere.

When there is an exception, there's also need to explain why there's exception: an extra mental burden for someone reading the code, an extra item to discuss in code review, etc. Only disable rules in individual cases if you can argue it is somehow an exceptional case.

Also, I'm not sure doing it as static class would be less understandable, even if it adds a bit more boilerplate (and sorry if below is not 100% correct code, my Java is a bit rusty, feel free to suggest edit):

Set<Map.Entry<String, SSGSession>> theSet 
    = new TreeSet<Map.Entry<String, SSGSession>>(new SSGSessionStartTimeComparator());

And then somewhere else in the file, together with other static classes:

static class SSGSessionStartTimeComparator extends Comparator<Map.Entry<String, SSGSession>>() {
    @Override
    public int compare(final Map.Entry<String, SSGSession> e1, final Map.Entry<String, SSGSession> e2) {
        return e2.getValue().getStartTime().compareTo(e1.getValue().getStartTime());
    }
}