Java泛型和数组类型,不是你想的(例如来自泛型类型的数组)

时间:2012-05-02 23:43:21

标签: java generics

我试图指定一个泛型类必须是一个数组,或者更好的是一个原始数组。到目前为止,这是我的工作:

interface Foo<T> {
  void process( T data );
}

public class Moo implements Foo<int[]> {
  void process( int[] data ) {
     // do stuff here
  }
}

这是完全有效的Java代码并且有效,因为原始数组扩展了Object。请注意,这个问题与我一直在寻找的所有其他Java数组通用问题完全不同。在那种情况下,人们希望用泛型类型创建一个数组。

问题是类型T可以是扩展Object的任何东西。我想要的是做一些事情:

<T extends ONLY ARRAYS>

<T extends ONLY PRIMITIVE ARRAYS>.

这可能吗?

编辑:最终目标是在传入的数组类型上添加编译时检查。现在可以传入任何旧对象,它将编译得很好。只有在抛出类转换异常时才会在运行时发现错误。事实上,这是Java中泛型的全部要点,以增加更强大的编译时类型检查。

4 个答案:

答案 0 :(得分:10)

你不能这样做。没有类可以扩展数组,因此永远不会有满足泛型参数T extends Object[]的类型。 (除了Object[]本身,但你不会使用泛型。)

你能做的是这样的事情:

public interface Foo<T extends Number> {
    public void process(T[] data);
}

但是你可能会遇到拳击的性能问题。

答案 1 :(得分:8)

在Java中,类型参数only可以被子类型关系约束,并且所有数组are ObjectClonable和{{1}的唯一常见超类型}。最接近的是约束到Serializable,这是具有非基本组件类型的所有数组的超类型,或者可能是Object[],它是Number[]的超类型,{ {1}},...

即使Java确实支持这样的约束,你会如何对该数组做任何有用的事情?您无法读取单个元素,因为您无法声明变量来保存结果,也无法写入单独的元素,因为您无法写下可分配给数组元素的表达式。

那就是说,我将类型变量绑定到组件类型,而不是数组类型:

Integer[]

因为您可以引用Long[]知道interface Foo<T extends Whatever> { void process(T[] data ); } ,但知道T[]并不能直接引用组件类型。

编辑:Jeffrey正确地指出数组类型不能在类型边界中使用,即T不能编译,所以你必须遵循我的声明T extends Object[]的建议并使用{{1引用数组类型。

答案 2 :(得分:1)

没有办法。没有“有趣的”接口,也没有任何超类型,但基元数组存在对象:

public class SOTEST {    
    public static void main(String[] args) throws Exception {
        int[] arr = new int[] {};
        Class c = arr.getClass();
        for(Class clazz:c.getInterfaces()) {
            System.out.println(clazz.getName());
        }

        System.out.println(c.getSuperclass().toString());
    }
}

答案 3 :(得分:-3)

X的数组没有类型层次结构。 Integer []不是Number []的子类。

要获得所需内容,请使用数组组件类型作为类型参数T,并将参数和返回类型声明为T的数组。