Anonymous vs named inner classes? - best practices?

33,975

Solution 1

One advantage of anonymous inner classes is that no one can ever use it anywhere else, whereas a named inner class can be used (if only by the class that created it if made private). It's a small distinction, but it does mean that you can protect an inner class from being accidentally used elsewhere.

Also, using the anonymous inner class gives anyone reading your code a head's up - "this class is being used just here and nowhere else." If you see a named inner class, someone might think it'd be used in multiple places in the class.

They are very similar, so neither point is a game-changer. I just think it helps for clarity if you use anonymous inner classes for one-offs, and named inner classes when it's used multiple times within the class.

Solution 2

(Counter point to Daniel Lew)

One disadvantage of anonymous inner classes is that no one can ever use it anywhere else, whereas a named inner class can be used (if only by the class that created it if made private). It's a small distinction, but it does mean that you can help ensure that an inner class is not accidentally recreated elsewhere.

Also, using the anonymous inner class gives anyone reading your code a harder time as they then have to parse this class that came out of nowhere. Using a named inner class you are able to organize the source more.

I have seen cases where there are two (or more) anonymous inner classes with the exact same code. In GUIs especially (where you may have multiple controls performing the same action) this can crop up (and I am talking production code, not code that my students have written).

The readability issue goes both ways, some people find anonymous inner classes better as it lets you see what is going on in once place, others find it a distraction. That part comes down to personal preference.

Also making an class static is more efficient, if you are declaring an anonymous inner class in an instance then there will be more overhead, which, if you don't need access to the instance variables, is wasteful (but probably not worth worrying about until it presents as a problem).

My personal preference is to use non-anonymous classes as they allow for more flexibility when the code is modified later.

Solution 3

Why do you need to subclass it? If it's just to override an existing virtual method, I think an anonymous inner class is okay. If you're adding extra functionality, I'd use a named class. I'd make it a nested class though (i.e. with the static modifier) - I find them easier to reason about :)

Solution 4

Do the simplest thing that could possibly work: Use the anonymous inner class.

If you later find that you need a broader scope, then refactor the code to support this.

(You would do the same with variables -- putting them in the most specific scope. It makes sense to do the same with other source assets.)

Solution 5

Anonymous inner classes are hard to debug in Eclipse (thats what I use). You will not be able to look at variable values/inject values by simply right clicking.

Share:
33,975

Related videos on Youtube

Joe Attardi
Author by

Joe Attardi

Updated on February 28, 2020

Comments

  • Joe Attardi
    Joe Attardi about 4 years

    I have a class, let's call it LineGraph, that renders a line graph. I need to subclass it, but the derived class is only used in one place and is coupled to the class that uses it. So I am using an inner class.

    I see two ways to do this:

    Anonymous inner class

    public class Gui {
        LineGraph graph = new LineGraph() {
            // extra functionality here.
        };
    }
    

    Named inner class

    public class Gui {
        MyLineGraph graph = new MyLineGraph();
    
        private class MyLineGraph extends LineGraph {
            // extra functionality here.
        }
    }
    

    I am not a fan of anonymous inner classes, because frankly I just think it looks really ugly. But in the case of a subclass that's only used in one place, is a named inner class overkill? What is the accepted practice?

  • Jon Skeet
    Jon Skeet about 15 years
    There are plenty of times where two options will work but one is more readable and maintainable than another. I think it makes a lot of sense to ask for other people's opinions when in doubt about the best way to go.
  • Tim Frey
    Tim Frey about 15 years
    +1 Good points, but remember classes can be defined inside functions, too. This limits their scope and can be a good hint they they have a very localized use.
  • Joe Attardi
    Joe Attardi about 15 years
    This is what I find ugly about the anonymous inner classes. You are reading through the code, and suddenly there is this class definition smack in the middle of a bunch of fields.
  • Joe Attardi
    Joe Attardi about 15 years
    My example was somewhat simplified. In the real code, it overrides 5 (non-abstract) methods.
  • Jon Skeet
    Jon Skeet about 15 years
    That sounds like enough to make it worth making into a named class. I like my anonymous classes to be small.
  • MarioRicalde
    MarioRicalde about 15 years
    agreed. I generally only use anonymous classes if they're really simple. Any more than one small function definition and I'll make it a normal inner class (static if possible). Just easier to read that way.
  • Jacek Szymański
    Jacek Szymański about 15 years
    Looks like you should not use inheritance but make LineGraph an interface and use a different implementation (maybe delegating to your now base class).
  • janetsmith
    janetsmith almost 15 years
    I always have problem aligning the code inside anonymous class. No matter how hard I try, the code still looks ugly :D
  • Someone Somewhere
    Someone Somewhere almost 11 years
    I agree - I find code hard to read/debug if there are lots of anonymous inner classes. Instead of declaring anonymous inner classes within multiple functions (YUCK!), I find that it's much better practice to dedicate sections of the file to named inner classes, i.e. the bottom of the file.
  • QAMAR
    QAMAR about 9 years
    what if i do public MyInterface myInterfaceVariable = new MyInterface(){ public void myMethod(){ print("HI") } }; Now i can use myInterfaceVariable object anywhere in that class