title: using enum constants obtained through reflection
body: <p>I have a program which obtains an Enum value via reflection (any Enum is allowed), and I want to do something with it by wrapping it in a generic class that takes an Enum as its type parameter. I am not sure how to properly call the constructor, however. The only way I can get it to work is to use a raw type.</p>
  
  <p>(<strong>clarification:</strong> My real program is complicated, and looks up the enum classname from a user-provided file at runtime. My real program's wrapper class has additional state and methods that cannot be accomplished with an enum, so I'm not just doing this for academic sake. I wrote the example program below to illustrate the issue. It may look contrived, but it's supposed to be for illustrative purposes.)</p>
  
  <p>Can anyone help me fix the line</p>
  
  <pre><code>EnumWrapper&lt;?&gt; ewrapped = new EnumWrapper(e);
  </code></pre>
  
  <p>below so it has a less evil warning? </p>
  
  <p>The program works as expected (prints out stack traces of 3 caught exceptions for enum constants not found, otherwise prints lists of wrapped enums), but I make it a habit never to use raw types, and don't know how to fix this case.</p>
  
  <pre><code>import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;
  
  public class GenericEnum2 {
  
      enum Bird { OWL, EAGLE, HAWK };
      enum Mammal { LION, TIGER, BEAR };
  
      static class EnumWrapper&lt;E extends Enum&lt;E&gt;&gt;
      {
          final private E value;
  
          public EnumWrapper(E value) { this.value = value; }
          public E getEnum() { return this.value; }
          @Override public String toString() { return "wrapped "+value.toString(); }
  
          static public &lt;E extends Enum&lt;E&gt;&gt; EnumWrapper&lt;E&gt; wrap(E e) {
              return new EnumWrapper&lt;E&gt;(e);
          }
      }
  
      public static void main(String[] args) {
          List&lt;EnumWrapper&lt;?&gt;&gt; list = new ArrayList&lt;EnumWrapper&lt;?&gt;&gt;();
          list.add(EnumWrapper.wrap(Bird.OWL));
          list.add(EnumWrapper.wrap(Bird.EAGLE));
          list.add(EnumWrapper.wrap(Bird.HAWK));
          list.add(EnumWrapper.wrap(Mammal.LION));
          list.add(EnumWrapper.wrap(Mammal.TIGER));
          list.add(EnumWrapper.wrap(Mammal.BEAR));        
          System.out.println(list);
  
          list.clear();
          for (String s : Arrays.asList(
                  "Bird.OWL", 
                  "Bird.HAWK",
                  "Bird.FULVOUS_WHISTLING_DUCK",
                  "Mammal.LION", 
                  "Mammal.BEAR",
                  "Mammal.WARTHOG",
                  "Computer.COMMODORE_64"
                  ))
          {
              String className = GenericEnum2.class.getCanonicalName()+"$"+s;
              try
              {
                  Enum&lt;?&gt; e = getEnum(className);
  
                  // EnumWrapper&lt;?&gt; ewrapped0 = EnumWrapper.wrap(e);
                  /*
                   * Bound mismatch: The generic method wrap(E) of type 
                   * GenericEnum2.EnumWrapper&lt;E&gt; is not applicable for 
                   * the arguments (Enum&lt;capture#2-of ?&gt;). The inferred 
                   * type Enum&lt;capture#2-of ?&gt; is not a valid substitute for 
                   * the bounded parameter &lt;E extends Enum&lt;E&gt;&gt;
                   */
  
                  // EnumWrapper&lt;?&gt; ewrapped0 = new EnumWrapper&lt;?&gt;(e);
                  // Cannot instantiate the type GenericEnum2.EnumWrapper&lt;?&gt;
  
                  EnumWrapper&lt;?&gt; ewrapped = new EnumWrapper(e);
                  // this works but gives me the warning of "EnumWrapper" being a raw type
  
                  list.add(ewrapped);
              }
              catch (IllegalArgumentException e)
              {
                  e.printStackTrace();
              }
              catch (ClassNotFoundException e) {
                  e.printStackTrace();
              }
          }
          System.out.println(list);
      }
  
      static public Enum&lt;?&gt; getEnum(String enumFullName) throws IllegalArgumentException, ClassNotFoundException
      {
          String[] x = enumFullName.split("\\.(?=[^\\.]+$)");
          if (x.length == 2)
          {
              String enumClassName = x[0];
              String enumName = x[1];
              @SuppressWarnings("unchecked")
              final Class&lt;Enum&gt; cl = (Class&lt;Enum&gt;)Class.forName(enumClassName);
              if (cl.isEnum())
              {
                  @SuppressWarnings("unchecked") 
                  final Enum result = Enum.valueOf(cl, enumName);
                  return result; 
              }
              else
                  throw new IllegalArgumentException("Class is not an enum: "+enumClassName);
          }
          return null;
      }
  }
  </code></pre>
  
  <hr>
  
  <p>edit: updated getEnum() per OrangeDog's suggestions:</p>
  
  <pre><code>static public Enum&lt;?&gt; getEnum(String enumFullName) throws IllegalArgumentException, ClassNotFoundException
      {
          String[] x = enumFullName.split("\\.(?=[^\\.]+$)");
          if (x.length == 2)
          {
              String enumClassName = x[0];
              String enumName = x[1];
              final Class&lt;?&gt; cl = Class.forName(enumClassName);
              if (cl.isEnum())
              {
                  for (Object o : cl.getEnumConstants())
                  {
                      Enum&lt;?&gt; e = (Enum&lt;?&gt;)o;
                      if (enumName.equals(e.name()))
                          return e;
                  }
              }
              else
                  throw new IllegalArgumentException("Class is not an enum: "+enumClassName);
          }
          return null;
      }
  }
  </code></pre>