2

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

interface A {
    B[] findAllB();
}

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

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

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

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

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

我想知道低级Java数组是否实现了一个接口(或者甚至可能有一个接口),或者换句话说,可以安全地返回一个数组来代替它。

如果这是可能的,java.util.List也可以扩展它,以便我们可以在幕后交替返回数组或列表。

我已经怀疑这是不可能的,但在计算机的世界里,一切皆有可能,所以谁知道呢。

4

5 回答 5

0

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

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]
于 2022-01-08T00:29:54.243 回答
0

可悲的是,正如@Turing85 指出的那样,数组是“协变的”,这一特性在今天被认为是一个错误

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

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

然而,一线希望是,即使考虑到 Java 的流行,这种“设计错误”可能无法补救,但它已在 Kotlin 中得到修复,它基本上是 Java,没有所有旧的设计缺陷。

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

所以我想我唯一的选择是要么等待 Java 设计者解决这个问题(不太可能),要么采用 Kotlin(需要时间),要么暂时使用List<T>with 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>extend Iterable<T>。要是...

于 2022-01-08T00:41:56.773 回答
0

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

于 2022-01-08T05:01:37.400 回答
0

不,没有这样的界面。List是抽象类数组数据结构概念的接口。

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

于 2022-01-09T09:54:42.307 回答
-1

替换最后一行(“不起作用”的那一行)

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

经过

 return Arrays.asList(array);

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

文档链接

于 2022-01-07T23:51:28.267 回答