title: Why can't I access static final members from a dedicated enum value in Java
body: <p>I was wondering why, while it's perfectly valid to do the following in Java</p>
  
  <pre><code>public enum Test {
     VALUE1() {
        public static final String CONST_RELATED_TO_VALUE1 = "constant";
        public static final String OTHER_CONST_RELATED_TO_VALUE1 = "constant";
     },
     VALUE2() {
        public static final String CONST_RELATED_TO_VALUE2 = "constant";
     },
     VALUE3;
  }
  </code></pre>
  
  <p>accessing the constants as one would expect using <code>Test.VALUE1.CONST_RELATED_TO_VALUE1</code> does not work.</p>
  
  <p>Now I understand, <code>VALUE1</code>, <code>VALUE2</code> etc. are actually all generally seen as static final instance of type <code>Test</code> and hence don't have those fields, but the information should theoretically available at compile time, which can easily be verified running a <a href="http://goo.gl/sqj6pk" rel="nofollow noreferrer">little test</a> </p>
  
  <pre><code>     // print types and static members
       for (Object o: Test.values()) {
          System.out.println(o.toString() + ": " + o.getClass());
          for (Field field : o.getClass().getDeclaredFields()) {
              if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
                  System.out.println("\t" + field);
              }
          }             
       }
  </code></pre>
  
  <p>which results in the following output</p>
  
  <pre><code>VALUE1: class Test$1                                                                                                                                                                               
          public static final java.lang.String Test$1.CONST_RELATED_TO_VALUE1                                                                                                                
          public static final java.lang.String Test$1.OTHER_CONST_RELATED_TO_VALUE1                                                                                                          
  VALUE2: class Test$2                                                                                                                                                                               
          public static final java.lang.String Test$2.CONST_RELATED_TO_VALUE2                                                                                                                
  VALUE3: class Test                                                                                                                                                                                 
          public static final Test Test.VALUE1                                                                                                                                    
          public static final Test Test.VALUE2                                                                                                                                    
          public static final Test Test.VALUE3                                                                                                                                    
          private static final Test[] Test.$VALUES
  </code></pre>
  
  <p>It's clear that we actually have proper dedicated sub-classes at runtime for <code>VALUE1</code> and <code>VALUE2</code>. But it also looks like the reason we lose the concrete type information about <code>VALUE1</code> and <code>VALUE2</code> is the way the compiler generates the static enum values for the base enum class <code>Test</code> as used by <code>VALUE3</code>: All members are of type <code>Test</code> and the concrete types are discarded.</p>
  
  <p>However, it seems to me that if the compiler simply kept those types like so</p>
  
  <pre><code>        public static final Test$1 Test.VALUE1                                                                                                                                    
          public static final Test$2 Test.VALUE2                                                                                                                                    
          public static final Test Test.VALUE3                                                                                                                                    
  </code></pre>
  
  <p>all surrounding code would still work. In addition we could also do what I tried initially and access <code>CONST_RELATED_TO_VALUE1</code> through <code>Test.VALUE1</code>, which is now clearly an instance of type <code>Test$1</code> and not just <code>Test</code> and while it should be generally avoided, it seems in this case perfectly fine to access that static member through an instance.</p>
  
  <p>Now as many people correctly pointed out, using anonymous classes to the left is not valid Java code and probably also for the compiler not allowed without some major specification change. However, this could easily be solved by using named inner classes, so we would have</p>
  
  <pre><code>        public static final Test.Value1 Test.VALUE1                                                                                                                                    
          public static final Test.Value2 Test.VALUE2                                                                                                                                    
          public static final Test Test.VALUE3                                                                                                                                    
  </code></pre>
  
  <p>This even provides an added benefit for debugging that the inner sub class name clearly maps to the corresponding enum value.</p>
  
  <p>Now I understand there would have to be some minor changes, but going from anonymous to named classes and not throwing away the types seems like a small change and this looks like quite a nice feature to have, without an easy way to emulate it using overridden members or something.</p>
  
  <p>So I was wondering why this wasn't implemented like this except time? Am I missing something crucial here that would prevent the compiler from doing this (either regarding implementation complexity or type system impossibilities) was it just not implemented to keep it simpler, because there was no time or something along those lines?</p>
  
  <p>(I'm mainly looking for reasons why it was decided to implement it like this from a compiler/typesystem point of view, not for practical alternatives to this, as there are definitely a couple, though it still seems like a nice pattern to have)</p>