tags:

views:

287

answers:

8

I've read elsewhere that a static anonymous class doesn't make sense - that all anonymous classes should be tied to an instance of the enclosing type. But the compiler let's you do it. Here's an example:

class Test {

    /*
     * What's the difference at between
     * Test.likeThis and Test.likeThat?        
     */

    // This is obviously okay:
    private static final class LikeThat {
        @Override
        public String toString() { return "hello!"; }    
    }
    public static Object likeThat = new LikeThat();

    // What about this - is it really any different? 
    public static Object likeThis = new Object() {
        @Override
        public String toString() { return "hello!"; }
    };
}

What's going on here?

+5  A: 

I see nothing wrong with static anonymous classes

Maurice Perry
+1  A: 

Seems perfectly legitimate to me. Since the anonymous class is static it won't have a reference to any enclosing class, but there should be no evil consequences from that.

Well, other than being a hidden singleton object, that's pretty evil.

Greg Hewgill
Singleton objects are not evil if they are stateless.
Stephen C
+4  A: 

Like anything in any language you should just consider why you're doing it. If you've got alot of these instances then I'd question the design decisions, but it doesn't necessarily means it's a pattern that should never be followed.

And of course, always consider the testability of the class and whether you can provide a test double if the need arises

MrWiggles
+1 - agreed, if you're seeing a lot of statics your codebase is going to be brittle and you're not really leveraging the power of OO that comes with the concept of an instance.
Nick Holt
+1  A: 

I don't think they have no sense. If you don't need reference to enclosing object then it's better to leave it static. Later it can evolve in separate class with ease.

Wide-spread enum idiom (pre Java 5) used similar approach with anonymous static inheritors of enum class. Probably, now it is better stick to Java 5 enum for this case.

If you are able to find adequate real-world application for anonymous static classes - why not to use them?

Rorick
+1 for pointing out you can always make it a named class later.
David Moles
+1  A: 

I do this all the time. It's especially handy for special-case implementations of utility interfaces, e.g.:

/** A holder for {@link Thing}s. */
public interface ThingsHolder {

 /** A {@link ThingsHolder} with nothing in it. */
 public static final ThingsHolder EMPTY_HOLDER = new ThingsHolder() {
  @Override
  public Iterable<Thing> getThings() {
   return Collections.emptySet();
  }
 };

 /** Provides some things. */
 Iterable<Thing> getThings();
}

You could create a private static inner class called EmptyHolder, and maybe in some cases that would make the code more readable, but there's no reason you have to do it.

David Moles
+2  A: 

From the Java Language Specification, section 8.1.3:

An instance of an inner class I whose declaration occurs in a static context has no lexically enclosing instances. However, if I is immediately declared within a static method or static initializer then I does have an enclosing block, which is the innermost block statement lexically enclosing the declaration of I.

Your anonymous class (the one likeThis is an instance of) occurs in a static context, so it is not tied to an enclosing instance. However, it seems that it can refer to final variables of its enclosing block (see the rest of section 8.1.3, they give an example).

Btw, your wording is a bit deceptive, you're actually referring to a static instance of an anonymous class (it's the instance that's static, not the class).

Olivier
A: 

Of course they are not. I always use static nested classes, unless I need the implicit association to the enclosing object.

In java terminology nested class := a class which is declared within another class (or interface). Inner classes are those nested classes which have an associated instance from the enclosing class. (Nonstatic member classes, local classes, anonymous classes).

The implicit association can prevent garbage collection sometimes.

A: 

These can be very convenient because of possibility to make circular references:

class A
{ 
    public static final A _1 = new A() {
        public A foo()
        {
            return _2;
        }
    };

    public static final A _2 = new A() {
        public A foo()
        {
            return _1;
        }
    };
}

Creation of several objects which are holding references to each other can be very awkward without usage of anonymous classes.

Dmitriy Matveev