tags:

views:

1509

answers:

5
+4  Q: 

Java: Local Enums

Today, I found myself coding something like this ...

public class LocalEnums {

    public LocalEnums() {
    }

    public void foo() {
     enum LocalEnum {
      A,B,C
     };

     // ....
     // class LocalClass { }

    }
}

and I was kind of surprised when the compiler reported an error on the local enum:

The member enum LocalEnum cannot be local

Why can't enums be declared local like classes?

I found this very useful in certain situations. In the case I was working, the rest of the code didn't need to know anything about the enum.

Is there any structural/design conflict that explains why this is not possible or could this be a future feature of Java?

+9  A: 

Enums are static nested classes because they define static member variables (the enum values), and this is disallowed for inner classes: http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.3

As a comment: if your methods are large enough that they require their own enums, then it's a strong sign that you need refactoring.

Edit: I was looking through the JLS for more detail on the restrictions of static nested classes, and didn't find it (although it's probably there, hidden under a different topic). From a pure implementation perspective, there's no reason that this couldn't be done. So I suspect that it was a language philosophy issue: it shouldn't be done, therefore won't be supported. But I wasn't there, so that's pure speculation.

kdgregory
kdgregory, my method don't have to be that large to use the *power* of enums... Enums can simplify/clarify your code. So refactoring may not be an issue here.
bruno conde
+4  A: 

I rarely find myself writing any types within a method, unless it's an anonymous inner class. You can, however, write nested enums:

public class NestedEnum
{
    private enum MyEnum
    {
        X, Y, Z
    }

    public void foo()
    {
    }
}

I don't think I'd really want to read a method which declared a new type within it - do you have any concrete reason for wanting to declare it inside the method instead of just as a nested type? I can see the "no other methods need to know" argument, but I think a comment can sort that out and still leave more readable code.

Jon Skeet
Jon, I don't often write local classes as well. But, In C# you can have something like var v = new {Prop = "Hello!!!"}; and that can be useful in certain situations. You can *approximate* this behavior with a local class in Java. So, if classes, why not enums?
bruno conde
A: 

http://mindprod.com/jgloss/enum.html gives a good description of java enums - as previously mentioned, enums are defined as static so they can't be declared as locals

Peter
+1  A: 

It's weird because the java inner class definition says that compile-time constants can be declared static, and a member of a Enum is clearly compile-time constant, plus enum is a static class, suposedly...

Documentation:

8.1.3 Inner Classes and Enclosing Instances

(...) Inner classes may not declare static members, unless they are compile-time constant fields.

class Outer{
    class Inner extends HasStatic{
     static final int x = 3;   // ok - compile-time constant
     static int y = 4;    // compile-time error, an inner class
    }
    static class NestedButNotInner{
     static int z = 5;    // ok, not an inner class
    }
    interface NeverInner{}    // interfaces are never inner
}
Franco
A: 
  1. "Nested enum types are implicitly static." 8.9 Enums

  2. It is reasonable to infer that nested enum types implicitly contain the static access modifier.

  3. "It is a compile-time error if a local class declaration contains any one of the following access modifiers: public, protected, private, or static."14.3 14.3 Local Class Declarations
emory