17

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

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

4 回答 4

10

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

你可以做的是这样的:

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

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

于 2012-05-02T23:50:15.303 回答
8

在 Java 中,类型参数只能受子类型关系的约束,所有数组的唯一共同超类型 Object,ClonableSerializable。你能得到的最接近的是约束到Object[],它是所有具有非原始组件类型的数组的超类型,或者可能约束到 ,它是, , ...Number[]的超类型Integer[]Long[]

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

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

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

因为你可以引用known ,但知道 aT[]并不能直接让你引用组件类型。TT extends Object[]

编辑:Jeffrey 正确地指出数组类型不能用于类型边界,即<T extends Whatever[]>不能编译,所以你必须遵循我的声明<T extends Whatever>和使用T[]来引用数组类型的建议。

于 2012-05-03T00:30:51.277 回答
1

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

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());
    }
}
于 2012-05-02T23:58:06.940 回答
-3

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

为了得到你想要的,使用数组组件类型作为你的类型参数 T,并将参数和返回类型声明为 T 的数组。

于 2012-05-04T02:48:33.477 回答