2014-01-24 65 views
1

考虑下面的代码...Java泛型类型

public class Test { 

    public interface I {} 
    public enum E1 implements I {M, N} 
    public enum E2 implements I {O, P} 
    public static class A<T extends Enum<T> & I> { 
     void test() { 
      // how to print the enum constants here ? 
      System.out.println("... "); 
     } 
    } 

    public static class B extends A<E2> {} 

    public static void main(final String[] args) { 
     A<E1> a = new A<E1>(); 
     B b = new B(); 

     a.test(); 
     b.test(); 
    } 
} 

如何访问testT类?例如如何打印枚举常量?

+1

这可能有所帮助:http://stackoverflow.com/questions/1626901/java-enums-list-enumerated-values-from-a-class-extends-enum –

+0

为什么你需要能够列出值对于枚举,无论如何? – AJMansfield

+0

@AJMansfield LOL! :-) – thelost

回答

1

不幸的是,案例A的那些通用信息在运行时不可用。您必须使用type token模式。在情况B,您可以使用“黑客”来获得常量:

void test() { 
     Type superclass = this.getClass().getGenericSuperclass(); 
     if (ParameterizedType.class.isAssignableFrom(superclass.getClass())) { 
      ParameterizedType genericSuperclass = (ParameterizedType) superclass; 
      Class enumClass = (Class) genericSuperclass.getActualTypeArguments()[0]; 
      for (Object o : enumClass.getEnumConstants()) { 
       System.out.println(o); 
      } 
     } 
    } 
+0

获取java.lang.Class不能转换为java.lang.reflect.ParameterizedType – thelost

+0

我已经添加了类型检查(它抛出了类案例) –

+0

谢谢!我怎么能用另一个'C'来扩展'B'?即。冒泡enum – thelost

-1

是否有必要创建一个类型参数化类型,然后不使用参数化类型?使用参数化类型并查看javadoc的java.lang.Class,实现起来很简单,这里有一种方法可以实现。

public class Test { 

    public interface I { } 
    public enum E1 implements I {M, N} 
    public enum E2 implements I {O, P} 
    public static class A<T extends Enum<T> & I> { 
     void test(Class<T> ct) { 
      for(T t: ct.getEnumConstants()) { 
       System.out.println("... " + t); 
      } 
     } 
    } 

    public static class B extends A<E2> {} 

    public static void main(final String[] args) { 
     A<E1> a = new A<E1>(); 
     B b = new B(); 

     System.out.println("Using E1"); 
     a.test(E1.class); 
     System.out.println("Using E2"); 
     b.test(E2.class); 
    } 
} 

输出

Using E1 
... M 
... N 
Using E2 
... O 
... P 
+0

那么,为什么我会做'新的A ()'然后'a.test(E1.class);'? – thelost

+1

第一个是一个类型参数,第二个是方法参数。当你做'新的A ()'''''''''''''''''''''''''''''''不能像''a.test(E2.class)''''调用'a.test'我建议拿一本关于仿制药的书来帮助你速度,Java泛型和集合是一个好的开始。 如果你已经投下我的答案,你能向我解释为什么?我想知道答案只是“我不明白你所编码的东西”,或者是对我来说可能有用的东西。 – Bhaskar

+0

问题是我不想再次指定类,但是从类型 – thelost

1

这是有益的考虑如何编写程序不使用泛型。任何可以用泛型编写的程序都可以通过简单地删除类型参数并在适当位置插入类型转换为没有泛型的等效程序。 (在类的元数据中忽略一些类似于泛型的东西,这里与此无关。)这称为类型擦除

public class Test { 

    public interface I {} 
    public enum E1 implements I {M, N} 
    public enum E2 implements I {O, P} 
    public static class A { 
     void test() { 
      // how to print the enum constants here ? 
      System.out.println("... "); 
     } 
    } 

    public static class B extends A {} 

    public static void main(final String[] args) { 
     A a = new A(); 
     B b = new B(); 

     a.test(); 
     b.test(); 
    } 
} 

如果您的程序不能在没有泛型的情况下编写,也不能使用泛型编写。