Java为什么允许大小为0的数组?


Answers:


121

它表示它为空。即您可以遍历它,就好像它有项目并且没有结果发生一样:

for(int k = 0; k < strings.length; k++){
   // something
}

从而避免了检查的需要。如果所讨论的数组为null,则会发生异常,但是在这种情况下,它什么也不做,这可能是适当的。


9
对于存在函数时test(Object... objects)显式调用函数也很有用test()
Frithjof

1
@Frithjof:facepalm:
Aleksandr Dubinsky

50

Java为什么允许大小为1的数组?将单个值包装在数组中不是很没用吗?如果Java只允许使用大小为2或更大的数组,那还不够吗?

是的,我们可以传递null而不是空数组,而可以传递单个对象或基元,而不是尺寸一矩阵。

但是有一些反对这种限制的好理由。我个人的主要论点:

限制太复杂了,没有必要

为了将数组的大小限制为[1..INTEGER.MAX_INT],我们必须添加许多其他的boudary检查,(同意Konrads的评论)我们的代码的转换逻辑和方法重载。从允许的阵列大小中排除0(可能是1)并不能节省成本,它需要付出额外的努力并对性能产生负面影响。

数组模型向量

阵列为矢量良好的数据模型(数学,Vector类!)。当然,数学中的向量可以是零维的。从概念上讲,这与不存在的概念不同。


旁注-String类(char-)的显着包装器。不可变体现String了一个空数组的概念:它是一个空的String("")。


2
我不相信你的限制论点。Java(与C不同)已经需要检查负数。该检查可以轻松地适应于0(只需更改>= 0> 0)。但是您当然对其余部分是正确的,因此添加此限制将毫无意义。
康拉德·鲁道夫

在我看来,循环迭代参数似乎更好:“ for(int k = 0; k <strings.length; k ++){//某事}”
dannyxyz22 2012年

2
不,这不是我的观点,因为在没有零大小数组的世界中,根本就不存在空字符串(基于char数组),因此不需要在循环中考虑空数组。该迭代参数是非常实用的副作用。在那个世界中,一个数组至少要有一个条目。(或两个,因为:为什么一个人只需要一个数组?)
Andreas Dolk

负索引和索引过高的检查都是相同的检查:负索引始终是无符号的,且不小于数组的长度
harold


14

考虑一下(有关Noon答案的更详细说明):

public String[] getStrings() {
 if( foo ) {
  return null;
 } else {
  return new String[] {"bar, "baz"};
 }
}

String[] strings = getStrings();
if (strings != null) {
 for (String s : strings) {
  blah(s);
 }
}

现在将其与此:

public String[] getStrings() {
 if( foo ) {
  return new String[0];
 } else {
  return new String[] {"bar, "baz"};
 }
}

// the if block is not necessary anymore
String[] strings = getStrings();
for (String s : strings) {
 blah(s);
}

实际上(返回空数组而不是null值)实际上是Java API设计界的最佳实践。

此外,在Java中,您可以将列表(例如ArrayList)转换为数组,只有将空列表转换为空数组才有意义。



4

零长度数组可能有用的另一种情况:要返回包含列表中所有元素的数组:

<T> T[ ] toArray(T[ ] a)

零长度数组可用于将数组的类型传递给此方法。例如:

ClassA[ ] result = list.toArray(new ClassA[0]);

零长度数组仍然是持有零元素的Object的实例。


2

我可以想到的一种情况是,在不允许使用null的情况下,使用空数组而不是null最为有用。一个可能的例子是数组的BlockingQueue。当您想向阅读端发出输入结束信号时,您会怎么做?发送null似乎是一个显而易见的选择,但事实是BlockingQueue不接受null。您可以使用“ boolean last;”类型的字段将数组包装到一个类中,但这有点过头了。发送空(零大小)数组似乎是最合理的选择。


0

零长度数组很有用的另一种情况是复制二维数组时。我可以写:

public int[][] copyArray(int[][] array){
     int[][] newArray = new int[array.length][0];
     for(int i=0;i<array.length;i++){
         newArray[i] = array[i];
     }
     return newArray;

由于数组中的每个数组引用都将被覆盖,因此将它们初始化为对零长度数组的引用是最有效的。


0

长度为0byte[]char[]可以表示一个空值String,与有所不同null。得到的字节数,或字符,如阵列从字符串(使用getBytes()getChars()String类等),并且反之亦然形成的String从s byte[]char[]是相当普遍的。例如,对于自定义编码,对字符串进行解码。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.