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



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

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中泛型的全部意义所在,以添加更强大的编译时类型检查。

你不能

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

你可以做的是这样的:

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

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

在 Java 中,类型

参数只能受子类型关系的约束,所有数组中唯一常见的超类型是 ObjectClonableSerializable。你能得到的最接近的就是约束到Object[],这是所有具有非基元组件类型的数组的超类型,或者可能约束到Number[],这是Integer[]的超类型,Long[],...

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

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

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

因为可以参考T[]知道T,但知道T extends Object[]并不能直接让你参考组件类型。

编辑:Jeffrey正确地指出数组类型不能在类型边界中使用,即 <T extends Whatever[]> 不会编译,所以你一定要遵循我声明<T extends Whatever>的建议,并使用T[]来引用数组类型。

不行。 没有"有趣"的接口,也没有任何超类型,但 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());
    }
}

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

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

最新更新