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

Java 中的数组长度是固定的,那么为什么 Java 允许数组大小为0呢?

String[] strings = new String[0];
94628 次浏览

Sometimes it's much more friendly to return a zero size array than null.

It signifies that it is empty. I.e. you can loop over it as if it had items and have no result occur:

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

Thereby avoiding the need to check. If the array in question were null, an exception would occur, but in this case it just does nothing, which may be appropriate.

Same as C++, it allows for cleaner handling when there is no data.

Consider this (a more detailed explanation of Noon's answer):

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);
}
}

Now compare it to this:

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);
}

This (returning empty arrays rather than null values), is in fact a best practice in Java API design world.

Besides, in Java, you can covert Lists (e.g. ArrayList) to arrays and it only makes sense to convert an empty list to an empty array.

Why does Java allow arrays of size 1? Isn't it pretty useless to wrap a single value in an array? Wouldn't it be sufficient if Java only allowed arrays of size 2 or greater?

Yes, we can pass null instead of an empty array and a single object or primitive instead of a size-one-matrix.

But there are some good arguments against such an restriction. My personal top arguments:

Restriction is too complicated and not really necessary

To limit arrays to sizes [1..INTEGER.MAX_INT] we'd have to add a lot of additional boudary checks,(agree to Konrads comment) conversion logic and method overloads to our code. Excluding 0 (and maybe 1) from the allowed array sizes does not save costs, it requires additional effort and has an negative impact on performance.

Array models vector

An array is a good data model for a vector (mathematics, not the Vector class!). And of course, a vector in mathematics may be zero dimensional. Which is conceptually different from being non-existant.


Sidenote - a prominent wrapper for an (char-)array is the String class. The immutable String materializes the concept of an empty array: it is the empty String ("").

One case I can think of where an empty array is extremely useful is to use it instead of null in a situation where null isn't allowed. One possible example of that is a BlockingQueue of arrays. When you want to signal the end of input to the reading side, what would you do? To send null seems like an obvious choice, but the thing is that BlockingQueue doesn't accept nulls. You could wrap your array inside a class with "boolean last;" kind of field, but that's kind of overkill. Sending an empty (zero-sized) array seems like the most reasonable choice.

Another case where a zero length array can be useful: To return an array containing all of the elements in a list :

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

A zero length array can be used to pass the type of the array into this method. For example:

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

A zero length array is still an instance of Object which holds zero elements.

Another case when a zero length array is useful is when copying a two dimensional array. I can write:

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;

Being that every array reference in array is being overwritten, initializing them as refernces to zero length arrays is most efficient.

A 0-length byte[], or char[] can represent an empty String, which is distinct from null. Getting the bytes, or characters, as arrays from strings (using getBytes(), getChars() of String class etc.) and the vice-versa of forming Strings from byte[], char[] is quite common. For example, for custom encoding, decoding of strings.