273

We can determine the length of an ArrayList<E> using its public method size(), like

ArrayList<Integer> arr = new ArrayList(10);
int size = arr.size();

Similarly we can determine the length of an Array object using the length property

String[] str = new String[10];
int size =  str.length;

Whereas the size() method of ArrayList is defined inside the ArrayList class, where is this length property of Array defined?

Sнаđошƒаӽ
  • 16,753
  • 12
  • 73
  • 90
AllTooSir
  • 48,828
  • 16
  • 130
  • 164
  • In terms of question organization, I would suggest putting your question "where is the length property of Array defined?" before all the explanations to prevent your post from sounding like a beginner's tutorial. – NoName Jul 09 '17 at 19:04

7 Answers7

261

Arrays are special objects in java, they have a simple attribute named length which is final.

There is no "class definition" of an array (you can't find it in any .class file), they're a part of the language itself.

10.7. Array Members

The members of an array type are all of the following:

  • The public final field length, which contains the number of components of the array. length may be positive or zero.
  • The public method clone, which overrides the method of the same name in class Object and throws no checked exceptions. The return type of the clone method of an array type T[] is T[].

    A clone of a multidimensional array is shallow, which is to say that it creates only a single new array. Subarrays are shared.

  • All the members inherited from class Object; the only method of Object that is not inherited is its clone method.

Resources:

johnchen902
  • 9,531
  • 1
  • 27
  • 69
Colin Hebert
  • 91,525
  • 15
  • 160
  • 151
  • 85
    Note also that `ArrayList.size()` provides the number of object actually stored in the array whereas `myArray.length` (`[]`) provides the "capacity". That is, if for `myArray = new int[10];`, it returns 10. It is not the number of objects you've put in the array. – wmorrison365 Feb 16 '12 at 13:15
  • 1
    @Colin How array objects are so special I mean why do designers need to made it special and why not provide class file of an array ? – Vikas Verma Sep 20 '14 at 16:34
  • 5
    @VikasVerma Why are arrays not like objects? Because of history. When Java was designed, most attempts at language innovation failed when not similar to C in syntax and style. Thus C++, Objective-C, and Java were among the few languages to escape obscurity during that era. Java was consciously designed to include curly braces, [primitives](http://en.wikipedia.org/wiki/Primitive_data_type), and plain arrays to appear familiar to mainstream programmers of the day. See interviews with James Gosling and other Sun folks. Some people stick with Collections for pure OOP, and avoid plain arrays. – Basil Bourque Feb 18 '15 at 03:37
  • 1
    @VikasVerma, at some point, java must be built on lower level technology. If java doesn't exist, you can't build it with java. You have to use C++ (or something else, but C++ in this case) to build some primitive compilation for the rest of java to have context for its own existence. You cannot have classes for everything without eventually hitting rock bottom where you code it in C++. How exactly would you build an array in java? If you can't use a `List` because that uses arrays in their implementations. – Alexander Bird Mar 07 '17 at 18:56
  • if you want to answer it *as is*, then https://stackoverflow.com/a/50506451/1059372 – Eugene May 24 '18 at 10:03
120

It's "special" basically, with its own bytecode instruction: arraylength. So this method:

public static void main(String[] args) {
    int x = args.length;
}

is compiled into bytecode like this:

public static void main(java.lang.String[]);
  Code:
   0:   aload_0
   1:   arraylength
   2:   istore_1
   3:   return

So it's not accessed as if it were a normal field. Indeed, if you try to get it as if it were a normal field, like this, it fails:

// Fails...
Field field = args.getClass().getField("length");
System.out.println(field.get(args));

So unfortunately, the JLS description of each array type having a public final field length is somewhat misleading :(

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    i don't remember exactly a quote by Albert Einstein but what it say's is "the people understand a thing very well can only explain the things in very simpler way" i think it suits you very well :) – JAVA Sep 09 '13 at 08:01
  • @Jon Skeet How array object is special I mean why do designers need to made it special and why not provide class file of an array ? – Vikas Verma Sep 20 '14 at 16:39
  • 2
    @VikasVerma: Think about the size of an array object. All other types have a fixed size - every instance is the same size, whereas arrays vary based on their length. That's just one example. If you think you could achieve the same results without using anything special, what do you think the fields of an array class would look like? How would you represent `int[]` when generics don't apply to primitive types? (And heck, generics didn't exist for a long time anyway.) You *could* get away without arrays by using linked lists for all collections, but it would be awful for efficiency. – Jon Skeet Sep 20 '14 at 17:15
  • @JonSkeet But what about StringBuffer class type it also have fixed size ? Yes indeed I was thinking about generics but you point out before I asked Thanks for it . – Vikas Verma Sep 20 '14 at 19:14
  • @VikasVerma: The `StringBuffer` class itself does, yes - because it holds a reference to a `char[]` (or did, at least; I don't know whether it still does, off-hand). So while a `StringBuilder` is responsible for more memory, its immediate size and layout are fixed. – Jon Skeet Sep 20 '14 at 22:08
  • @JonSkeet Thanks now this special behavior of array make sense to me. – Vikas Verma Sep 21 '14 at 17:28
  • @JonSkeet it's stored in a special `Object header`... https://stackoverflow.com/a/50506451/1059372 how's this btw stored in C#? – Eugene May 24 '18 at 10:04
  • @Eugene: Not sure, to be honest. It's not something I've ever had to worry about :) – Jon Skeet May 24 '18 at 13:26
  • @JonSkeet no no, me either, but I'm just "itched" so bad about it right now :) – Eugene May 24 '18 at 13:27
  • I think the notion is from a JLS perspective length is a field whereas from a JVM perspective it's not. Your point about reflection not treating it as a field seems like a consequence of reflection deliberately taking on a JVM-centric view. It's definitely confusing but I would argue not needlessly though. – Shmuel Newmark Jun 17 '21 at 04:21
19

It's defined in the Java language specification:

The members of an array type are all of the following:

  • The public final field length, which contains the number of components of the array. length may be positive or zero.

Since there is a limitless number of array types (for every class there is a corresponding array type, and then there are multidimensional arrays), they cannot be implemented in a class file; the JVM has to do it on the fly.

Pang
  • 9,564
  • 146
  • 81
  • 122
Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
15

Even though this is not a direct answer to the question, it is an addition to the .length vs .size() argument. I was researching something related to this question so when I came across it I noticed that the definition(s) provided here

The public final field length, which contains the number of components of the array.

is not "exactly" correct.

The field length contains the number of available places to put a component, not the number of components present in the array. So it represents the total available memory allocated to that array, not how much of that memory is filled.

Array Memory Allocation

Example:

static class StuffClass {
    int stuff;
    StuffClass(int stuff) {
        this.stuff = stuff;
    }
}

public static void main(String[] args) {

    int[] test = new int[5];
    test[0] = 2;
    test[1] = 33;
    System.out.println("Length of int[]:\t" + test.length);

    String[] test2 = new String[5];
    test2[0] = "2";
    test2[1] = "33";    
    System.out.println("Length of String[]:\t" + test2.length);

    StuffClass[] test3 = new StuffClass[5];
    test3[0] = new StuffClass(2);
    test3[1] = new StuffClass(33);
    System.out.println("Length of StuffClass[]:\t" + test3.length);         
}

Output:

Length of int[]:        5
Length of String[]:     5
Length of StuffClass[]: 5

However, the .size() property of the ArrayList does give the number of elements in the list:

ArrayList<Integer> intsList = new ArrayList<Integer>();
System.out.println("List size:\t" + intsList.size());
intsList.add(2);
System.out.println("List size:\t" + intsList.size());
intsList.add(33);
System.out.println("List size:\t" + intsList.size());

Output:

List size:  0
List size:  1
List size:  2
nem035
  • 34,790
  • 6
  • 87
  • 99
  • 2
    It is correct, since all the elements are initialized to zero. Arrays can't be "empty" – Guido May 21 '15 at 01:54
  • Well that is exactly what I said. It is not "exactly" correct. It still has length of 5 even though nothing was added to the array. Thus it doesn't not "exactly" contain the number of elements in the array. Your comment is just an addition to my answer, not a reason to make it incorrect. – nem035 May 28 '15 at 17:02
  • It could be "incorrect" if you tried to make a distinction between `null` and non-null elements. But the distinction doesn't work. After all, the `size()` of (say) a `List` may include `null` values too. – Stephen C Jan 10 '16 at 14:09
  • Yup, essentially my point was that `size` behaves dynamically, while `length` is a static property... the fact that the remaining unfilled space in an array gets initialized to "*Non Values*" (depending on the type) doesn't really contradict this point. – nem035 Jan 10 '16 at 17:27
5

it's public final field , which contains the number of components of the array (length may be positive or zero)

An array thus has the same public fields and methods as the following class:

class A implements Cloneable, java.io.Serializable {
    public final int length = X;
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            throw new InternalError(e.getMessage());
        }
    }
}

more info at

10.7 Array Members

http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html

Massimiliano Peluso
  • 26,379
  • 6
  • 61
  • 70
2

To answer it as it-is, where is this length property of array defined? In a special Object header.

Easy to see via JOL

 int [] ints = new int[23];
 System.out.println(ClassLayout.parseInstance(ints).toPrintable());

One of the lines from this output is going to be:

OFFSET  SIZE      TYPE DESCRIPTION
16       4        (object header)   17 00 00 00 (00010111 00000000 00000000 00000000) (23)

Usually Objects have two headers (mark and klass), arrays have one more that always occupy 4 bytes in length, as size is an int.

Eugene
  • 117,005
  • 15
  • 201
  • 306
-1

The keyword length acts like a data filed defined. When using in an array, we can use it to access how many elements in an array. Regarding to String[], we can invoke length() method defined in String class. With regard to ArrayList, we can use size() method defined in ArrayList. Note that when creating an array list with ArrayList<>(capacity), the initial size() of this array list is zero since there is no element.

htlbydgod
  • 330
  • 2
  • 8