title: Access type of a generic in Java
body: <p>I am trying to create a generic <code>Identifier</code> class which I would be able to use as follows:</p>
  
  <pre><code>public class TestGenericIdentifier {
      public static void main(String[] args) {
          Identifier&lt;Car&gt; carId = new Identifier&lt;&gt;(Car.IdentifierType.LICENSE_PLATE, "123 XYZ");
          Identifier&lt;Person&gt; personId = new Identifier&lt;&gt;(Person.IdentifierType.SOCIAL_SECURITY, "123456");
          System.out.println(carId);
          System.out.println(personId);
      }
  }
  </code></pre>
  
  <p>To get there, I started by creating an <code>Identifiable</code> interface:</p>
  
  <pre><code>public interface Identifiable&lt;T extends Enum&gt; {}
  </code></pre>
  
  <p>The idea being that a class that implements <code>Identifiable</code> needs to provide an enum <code>T</code> in its declaration which is the type of the first parameter of the <code>Identifier</code> constructor:</p>
  
  <pre><code>public class Identifier&lt;E extends Identifiable&lt;T&gt;&gt; { //does not compile
      public Identifier(T type, String value) {
          //some code
      }
  }
  </code></pre>
  
  <p>Now the code above does not compile as I can only use <code>Identifiable</code> (no parameter <code>T</code>) on the first line. If it worked I would be able to write the following two classes:</p>
  
  <pre><code>public class Car implements Identifiable&lt;Car.IdentifierType&gt;{
  
      public enum IdentifierType {
          SERIAL_NUMBER,
          LICENSE_PLATE;
      }
  }
  
  public class Person implements Identifiable&lt;Person.IdentifierType&gt; {
  
      public enum IdentifierType {
          DATABASE_ID,
          SOCIAL_SECURITY;
      }
  }
  </code></pre>
  
  <p>Is there a way to do that using generics?
  <br>
  EDIT <br>
  One way is to compromise conciseness and keep compile-time type checking by doing:</p>
  
  <pre><code>public class Identifier&lt;T extends Enum&gt; {
  
      public Identifier(T type, String value) {
      }
  }
  </code></pre>
  
  <p>and the main function becomes:</p>
  
  <pre><code>Identifier&lt;Car.IdentifierType&gt; carId = new Identifier&lt;&gt;(Car.IdentifierType.LICENSE_PLATE, "123 XYZ");
  Identifier&lt;Person.IdentifierType&gt; personId = new Identifier&lt;&gt;(Person.IdentifierType.SOCIAL_SECURITY, "123456");
  </code></pre>