我试图指定泛型类必须是一个数组,或者更好的是原始数组。 到目前为止,这就是我的工作:
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);
}
但是,您可能会遇到拳击的性能问题。
参数只能受子类型关系的约束,所有数组中唯一常见的超类型是 Object
、Clonable
和 Serializable
。你能得到的最接近的就是约束到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 的数组。