有可能为Java数组提供接口吗



假设我们希望在接口中有一个返回数组的方法,如下所示:

interface A {
B[] findAllB();
}

但是数组是非常低级的,并且是明确实现的。它们的实现是最终的,不能更改,就像最终类一样。如果此接口中的返回类型已经是数组,则不可能返回除数组之外的任何其他内容。因此,最好避免将数组作为返回类型,因为这限制了实现类返回其想要返回的任何内容的自由度。因此,我们决定使用java.util.List:

interface A {
List<B> findAllB();
}

但是当实现这个接口时,我们可能非常方便地返回一个实际的数组,理论上它确实实现了List接口(例如,addremove抛出UnsupportedOperationExceptions(:

class AImpl implements A {
List<B> findAllB() {
B[] array = ...;
...
return array; // does not work
}
}

但这不起作用,因为不能返回B[]而不是List<B>

我想知道底层Java数组是否实现了一个接口(或者是否有可能有一个接口(,或者换句话说,返回一个数组来代替它是安全的。

如果这是可能的,java.util.List也可以扩展它,这样我们就可以在窗帘后面交换地返回数组或列表。

我已经怀疑这是不可能的,但在计算机的世界里,任何事情都是可能的,谁知道呢。

你可以这样做。在实现接口时,将数组指定为类型参数。

interface A<T> {
T findAllB();
}
class Tryit implements A<int[]> {
int[] test  = {1,2,3,4}; 
public int[] findAllB() {
return test;
}    
}
System.out.println(Arrays.toString(t.findAllB()));

打印

[1, 2, 3, 4]

可悲的是,正如@Turing85所指出的,数组是"协变";,一个今天被认为是错误的功能:

很明显,这在当时被认为是一个有价值的妥协。与今天相比:回想起来,许多人认为数组协方差是一个错误。

这基本上意味着将错误类型的对象分配给它们会产生运行时错误,而不是编译时错误,这是不可取的。显然,Java的数组与List的互换性不如我所设想的那样。

然而,一线希望是,尽管;设计错误";考虑到Java的流行,它可能是不可修复的,它已经在Kotlin中得到了修复,Kotlin基本上是Java,没有所有旧的设计缺陷。

Kotlin中的数组是不变的。这意味着Kotlin不允许我们将Array<String>分配给Array<Any>,这可以防止可能的运行时故障

所以我想我唯一的选择是要么等待Java设计者解决这个问题(不太可能(,要么采用Kotlin(需要时间(,要么暂时将List<T>Arrays.asList一起使用。

PS:这些选项都不能解决我最初的问题,那就是要有一个既概括列表又概括数组的接口,比如Sequential:

package java.util;
interface Sequential<T> {
int getLength();
T getAt(int index);
}
interface List<T> extends Collection<T>, Sequential<T> {
...
}

并且允许将数组隐式地广播到Sequential

这并没有那么疯狂,Java语言设计者可以在不破坏向后兼容性的情况下轻松地做到这一点。它们甚至可以使Sequential<T>扩展Iterable<T>。要是…就好了

我没有足够的声誉发表评论,所以把它发布在这里。我同意@WJS,您可以使用java.lang.reflect.Array类来访问T,例如使用t.getClass().isArray()来确定T是否为数组,或者使用默认方法来获取T的长度,如下所示:default int getLen(T t){ return Array.getLength(t); },还可以通过索引使用Array.get(Object Array,int index(方法从t中获取元素。

不,没有这样的接口。List是抽象类数组数据结构思想的接口。

您可以通过List.toArrayList.ofArrayList构造函数在List和数组之间自由转换。

替换的最后一行("不起作用"的行(

class AImpl implements A {
List<B> findAllB() {
B[] array = ...;
...
return array; // does not work
}
} 

通过

return Arrays.asList(array);

这是将现有数组转换为所需列表的最简单方法。该列表由数组直接支持(并且是固定大小的,没有添加或删除(。

文档链接

相关内容

  • 没有找到相关文章

最新更新