Java - 为什么要将数组声明为接口类型?

8
这段内容来自马克·韦斯教授在他的书《Java数据结构和算法分析》中。
public class BinaryHeap<AnyType extends Comparable<? super AnyType>>{
    private void enlargeArray( int newSize ){
        AnyType [] old = array;
        array = (AnyType []) new Comparable[ newSize ];
        for( int i = 0; i < old.length; i++ )
        array[ i ] = old[ i ];        
    }
}

我想知道为什么我们要使用接口 Comparable 声明数组,因为我们需要将 Comparable[] 转换成 AnyType[]?这背后有什么设计理念吗?


3
由于您无法创建类型为 AnyType[] 的数组。 - JB Nizet
1
@user2357112 这并不完全错误。编译器会生成一个未经检查的转型警告,但是当你必须将泛型类型的对象存储在数组中时,你实际上没有更好的选择。只要这个数组是私有的且不被暴露,这样做是可以接受的。 - JB Nizet
1
他们还没有 :-) - JB Nizet
1
@JBNizet:是的,没有显式“Class”对象,你无法避免未经检查的转换,但最好在元素上执行未经检查的转换(这些元素实际上预期具有要转换为的类型),而不是数组(它绝对不是你将要转换的类型)。 - user2357112
1
@LewBloch:Arrays.copyOf 调用确实返回一个真正的 T[]。我认为 (T[]) 强制转换是不必要的。 - user2357112
显示剩余11条评论
2个回答

4
设计"哲学"是你不能实例化一个类型参数的数组,因此你必须用合法的类型来实例化数组。该方法所知道的唯一可用的合法类型是ObjectComparable的数组,后者对类型捕获更多的知识。
允许将类型参数向下转换为数组,并且返回类型必须是这个,因此需要向下转换。
这是必要的"哲学"。

1
你可以将类型参数向下转换为数组 - 你只有在这种情况下才“允许”,因为这些转换是未经检查的,Java没有必要的信息来阻止你。 - user2357112
你可以这样做,也就是说程序可以编译和运行。 - Lew Bloch

0

我相信AnyType是一个泛型。在Java中,您无法创建泛型数组。为了解决这个问题,他实例化了一个Comparables(一个接口)数组,然后将其强制转换为泛型数组。

如果您查看这个“如何创建泛型数组”问题,其中一个人提供了初始化对象数组,然后将其类型转换为所需泛型数组的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接