代码之家  ›  专栏  ›  技术社区  ›  guerda

与泛型和类斗争

  •  3
  • guerda  · 技术社区  · 15 年前

    class Father {
        ...
    }
    
    class Child1 extends Father {
        ...
    }
    
    class Child2 extends Father {
        ...
    }
    
    public class TestClass {
        private static Class<? extends Father>[] myNiceClasses = new Class<? extends Father>[] {
            Child1.class,
            Child2.class
        }
    }
    

    确实如此 工作编译器抱怨如下:

    Cannot create a generic array of Class<? extends Father>
    

    如果我将(有故障的)阵列线更改为

    private static Class<Father>[] myNiceClasses = new Class<Father>[] {
    

    出现相同的错误消息,但也添加了此消息:

    Type mismatch: cannot convert from Class<Child1> to Class<Father>
    

    唯一有效的版本是这一行:

    private static Class<?>[] myNiceClasses = new Class<?>[] {
    

    此解决方案并不令人满意,因为您无法如此轻松地进行转换。

    6 回复  |  直到 15 年前
        1
  •  8
  •   amit    15 年前

    这是因为java不支持泛型数组创建。泛型最适合集合。因此,您可以使用ArrayList解决您的问题:

            ArrayList<Class<? extends Father>> myNiceClasses = new ArrayList<Class<? extends Father>>();
            myNiceClasses.add(Child1.class);
            myNiceClasses.add(Child2.class);
    
        2
  •  4
  •   Zarkonnen    15 年前

    private static Class<? extends Father>[] myNiceClasses =
            (Class<? extends Father>[]) new Class<?>[] {};
    
        3
  •  2
  •   quant_dev    15 年前
        4
  •  1
  •   skaffman    15 年前

    泛型和数组是最好避免的组合。编译器不希望您创建泛型数组,这是Java泛型是语言的附加组件这一事实的产物,有时您可以看到连接。另一个例子是异常,您也不能将它们与泛型组合。

    我建议在这种情况下避免使用数组。改为使用通用列表。

        5
  •  1
  •   jqno    15 年前

    这是由于所谓的类型擦除。Java编译器在编译过程中擦除所有通用信息。(这是因为泛型是该语言的后期添加,Sun决定不修改JVM,以实现向后兼容性。这意味着该语言知道泛型,但JVM不知道。)

    Class .

    总而言之:泛型和数组不能混合使用。

        6
  •  0
  •   Zarkonnen    15 年前

    或者,正如amit.dev所说,您可能需要使用一个列表。在这种情况下,假设myNiceClasses字段是一个常量,您可以使用 Collections.unmodifiableList 要确保列表不能更改,请执行以下操作:

    private static final List<? extends Father> myNiceClasses;
    static {
        ArrayList<? extends Father> l = new ArrayList<? extends Father>();
        l.add(Child1.class);
        l.add(Child2.class);
        myNiceClasses = Collections.unmodifiableList(l);
    }
    

    它相当冗长,但具有完全恒定的优点,因此更容易推理。