12 Replies Latest reply on Feb 9, 2009 4:18 PM by 807588

    Differenc between Class and Enum

    807588
      Hi,

      why is it possible to define a class inside a method but not en enum, like in the following code:
      public class Java {
           
           public static void method() {
                class MyClass {
                     
                }
                
                enum MyEnum {
                     A, B, C;
                }
           }
      
      }
      I have no answer...

      Greetings,
      Martin

      Edited by: Mkrueger on Feb 8, 2009 1:52 AM
        • 2. Re: Differenc between Class and Enum
          807588
          deleted

          Edited by: Encephalopathic on Feb 8, 2009 2:39 AM
          • 3. Re: Differenc between Class and Enum
            darrylburke
            From the Java Language Specifications: [_8.9 Enums_|http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.9]
            Nested enum types are implicitly static.

            This implies that it is impossible to define a local enum, or to define an enum in an inner class.

            db
            • 4. Re: Differenc between Class and Enum
              807588
              An interesting discussion here.
              • 5. Re: Differenc between Class and Enum
                800308
                Can you really create a named class inside a method? If so, Why? Please does anyone have an example where this is used effectively? It just seems very strange.

                Cheers. Keith.
                • 6. Re: Differenc between Class and Enum
                  807588
                  What would you do with an enum that exists only inside your method?
                  • 7. Re: Differenc between Class and Enum
                    800308
                    Well pickle me gran'mother.
                    package forums;
                    
                    public class NamedClassDefinedWithinMethodTest
                    {
                      public static int staticMethod() {
                        class MyClass {
                          int a = 1;
                        }
                        return new MyClass().a;
                      }
                    
                      public int instanceMethod(final int x) {
                        class MyClass {
                          int a = x;
                        }
                        return new MyClass().a;
                      }
                    
                      public static void main(String[] args) {
                        try {
                          System.out.println(NamedClassDefinedWithinMethodTest.staticMethod());
                          System.out.println(new NamedClassDefinedWithinMethodTest().instanceMethod(2));
                        } catch (Exception e) {
                          e.printStackTrace();
                        }
                      }
                    
                    }
                    Still can't see where you'd use it though... maybe for listener implementations where (for some reason) you needed to keep a reference to the listener outside of the notifying component.

                    Anyone?

                    Cheers. Keith.
                    • 8. Re: Differenc between Class and Enum
                      jwenting
                      For classes (not enums) you might use it as a way to make somewhat more readable code in factories.
                      Define the implementation classes as inner classes and return those from static factory methods.

                      Of course those inner classes would have to implement a public interface.

                      Still serves no purpose except readability of the code, but that alone might be worth it (of course having the inner classes at class level instead of method level is probably better still).
                      public static Intf intfFactory(int kind) {
                        class Impl1 implements Intf {
                        }
                        class Impl2 implements Intf {
                        }
                        class Impl3 implements Intf {
                        }
                      
                        switch (kind) { 
                          case 1 : return new Impl1();
                          case 2 : return new Impl2();
                          default: return new Impl3();
                        }
                      }
                      • 9. Re: Differenc between Class and Enum
                        807588
                        corlettk wrote:
                        Can you really create a named class inside a method? If so, Why? Please does anyone have an example where this is used effectively? It just seems very strange.
                        I've used them. The advantage of a named local class over an anonymous one is that they can define their own methods that can be accessed from the method in which it's defined, rather than just the methods of an existing interface.

                        One use might be when you need some kind of accumulator. For example if you want to get the mean and standard deviation of a set of numbers obtained during multiple loops in the method. You can define a local class (and an instance of same) with an addValue method and a series of getters to fetch results.

                        Of course you could have used an inner class, but if the entire use of the class is inside the method, the inside the method is a logical place to define it. And, of course, you get access to local final variables and parameters that way.
                        • 10. Re: Differenc between Class and Enum
                          807588
                          malcolmmc wrote:
                          >
                          I've used them. The advantage of a named local class over an anonymous one is that they can define their own methods that can be accessed from the method in which it's defined, rather than just the methods of an existing interface.
                          Heh, heh, Notice that type capture (?) allows me to use an anonymous implementation of Closure instead of naming it.
                          import java.util.*;
                          
                          interface Closure<T> {
                              void call(T it);
                          }
                          
                          public class Each {
                              public static <T, F extends Closure<T>> F each(Iterable<T> col, F clo) {
                                  for(T t : col) {
                                      clo.call(t);
                                  }
                                  return clo;
                              }
                          
                              public static void main(String[] args) {
                                  List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
                                  int result = each(list, new Closure<Integer>(){
                                      int sum;
                                      public void call(Integer it) {sum += it;}
                                  }).sum;
                                  System.out.println(result);
                              }
                          }
                          • 11. Re: Differenc between Class and Enum
                            abillconsl
                            DLJ,

                            That's pretty slick ... the part I like best is this:
                            int result = each(list, new Closure<Integer>(){
                                        int sum;
                                        public void call(Integer it) {sum += it;}
                                    }).sum;  // <<<this
                            I did not know you could use dot notation in this way.
                            • 12. Re: Differenc between Class and Enum
                              807588
                              abillconsl wrote:
                              DLJ,

                              That's pretty slick ... the part I like best is this:
                              int result = each(list, new Closure<Integer>(){
                              int sum;
                              public void call(Integer it) {sum += it;}
                              }).sum;  // <<<this
                              I did not know you could use dot notation in this way.
                              Really? My code is cluttered but that bit of syntax is the same as:
                              Point f() {...}
                              
                              void g() {
                                  int xcoord = f().x;
                              }
                              What I think is cool about that code is that it the compiler (better: Java's type system) is sophisticated enough to deduce that the return type of each() is not Closure<Integer> -- in which case we can't assess added members like the field sum -- but the given (unnamed) subtype of Closure<Integer>.

                              You can only go so far with this trick, but I enjoy it for what it's worth.