我试图指定一个泛型类必须是一个数组,或者更好的是一个原始数组。到目前为止,这是我的工作:
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中泛型的全部要点,以增加更强大的编译时类型检查。
答案 0 :(得分:10)
你不能这样做。没有类可以扩展数组,因此永远不会有满足泛型参数T extends Object[]
的类型。 (除了Object[]
本身,但你不会使用泛型。)
你能做的是这样的事情:
public interface Foo<T extends Number> {
public void process(T[] data);
}
但是你可能会遇到拳击的性能问题。
答案 1 :(得分:8)
在Java中,类型参数only可以被子类型关系约束,并且所有数组are Object
,Clonable
和{{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的数组。