8

Why when we get the length of an array don't we have to place () like

int [] ar;
System.out.println(ar.length); // no parentheses 

but for a String it will be

String st;
System.out.println(st.length());
Carl Manaster
  • 39,912
  • 17
  • 102
  • 155
C graphics
  • 7,308
  • 19
  • 83
  • 134
  • I don't agree that this question is the same as the earlier question, nor that the answers to that question answer this one. The earlier question asked "How do I find the length of these different entities?" This one asks "Why do I need parentheses to get the length of a string but not the length of an array?" I fear that the answer may be "you just do" but in any event it's not present in answers to the other question. – Carl Manaster Jul 03 '14 at 22:45
  • I also disagree. This question is about the difference between field-access and methods. If it goes into detail, its also about *why* there are different implementations inside the Java-API. – dognose Jul 03 '14 at 22:47

4 Answers4

9

why Array.length has no () but String.length() does?

At the syntactic level, it really comes down to "historical reasons" and "because that's the Java (pre) 1.0 language designers decided to do it". The only people who can truly tell you why are the language designers themselves.

However:

  • The length field is special in the sense that it is actually in the array object's header, and fetching the length of an array uses a special bytecode.

  • The length field cannot be changed by any means short of dangerous native code hacks. It is really important that this be so, to avoid problems with heap corruption, etc. (By contrast even a final field on a normal object can be modified using reflection.)

In these respects, length on an array is genuinely different from any other field.


Since the early days of (pre-)Java, the use of exposed fields in APIs has gone right out of style.

Most people would say that this is a good thing. By exposing the length information as length() and size() methods on strings, collections, etc, the class library design allows a Java implementor to change the representation of the respective types. That is not possible (in Java) if fields are exposed directly.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
6

The difference is:

  • The length of an array is NOT about the actual content - it's the dimension! An array can be of length 10, but only contain 2 elements.
  • An Object containing elements (A String is an Object, containing multiple chars) might have a certain count of Objects inside. This count can vary, depending on whether you add or remove elements. So the length() method is about the actual content!

The reason is, that an array is a language construct - Therefore, whenever you want to know something about the array (it's length or else) You have to retrieve a fixed value from the JVM, rather than calling a method that evaluates something.

(The Array-Class is just a proxy for the actual array-construct.)


Technically spoken an array (note the small a) is just a memory allocation for array.length elements in the memory. (And that's why you can't simple resize an array, but always need to create a NEW array when changing the dimension - it needs to be relocated (in C that was called realloc) in memory, so there is enough room for array.length * elementSize bits.

A List on the other hand does not care about the actual position of it's element in the memory, and therefore allows dynamic resizing at any time. (So it can server a method size() because it has no dimension, and just needs to return information about it's content.)

dognose
  • 20,360
  • 9
  • 61
  • 107
  • To get your point better I looked "language contract" up and found this: http://stackoverflow.com/questions/10057524/what-do-we-mean-by-language-construct but cant still make a connection. Can you add 1-2 lines about the language construct you used here – C graphics Jul 04 '14 at 03:26
1

This is the difference between accessing a field (no parentheses) and calling a method (requires parentheses, even if there are no arguments to the method).

Historically, arrays could have had a method in addition to or instead of a field. Strings could have had a field in addition to a method. A field is simpler, which is probably why arrays use it, but there are at least two reasons why it's good for String to have a length method:

  1. String implements the CharSequence interface, which defines a length() method, so String has to have that method. (Defining fields isn't a feature of interfaces, except for static final constants.) String could have length as a method and a field but that would be distracting.

  2. Flexibility. String's internal implementation has changed over time: at one time it used an internal char array and separate offset and length fields which defined a region within the char array. That was done so that substrings could share the parent string's char array (with different offset and length) instead of copying the array. It was later found that that optimization was rarely beneficial, so now, String has only a char array of the correct size, and the length method reads the array's length field. String no longer has its own length field, not even a private one, but they couldn't have removed it if it were part of the class's public API, which would give less flexibility to experiment with internal implementations.

Boann
  • 48,794
  • 16
  • 117
  • 146
0

Array's length is an int field, but String (and other objects) usually use a getter method.

Do note that the difference in the two lies in the fact that a string's "length" is simply the amount of information it already stores in its internal char array, but an array's length field is just its capacity.

Rogue
  • 11,105
  • 5
  • 45
  • 71
  • 2
    and that's why? Why has a object no public field, and why has array not simply a method for the length? – dognose Jul 03 '14 at 22:51
  • 1
    @dognose The length is a simple final field that can be accessed. Since array's length is immutable in the sense that you can't dynamically change the size of it, it was fine to expose that aspect of the class. – Rogue Jul 03 '14 at 22:52
  • Strings are immutable, so the capacity and length are always the same. – Mark Rotteveel Jul 04 '14 at 06:45
  • @MarkRotteveel in the eyes of reflection, not on the same level. Of course, you can't set `null` to a `char` array, but if you use something crazy like `java.misc.Unsafe`, who knows on strings, especially in reference to the length method. Array's length is not settable, even in that form. – Rogue Jul 04 '14 at 11:56