views:

321

answers:

4

Why do we have length of an array as an attribute. array.length and for String we have a method str.length()?

Just came in my mind, is there some reason?

+1  A: 

A bit simplified you can think of it as arrays being a special case and not ordinary classes (a bit like primitives, but not). String and all the collections are classes, hence the methods to get size, length or similar things.

I guess the reason at the time of the design was performance, if they created it today they had probably come up with something like array backed collection classes instead.

If anyone is interested, here is a small snippet of code to illustrate the difference between the two in generated code, first the source:

public class ArrayTest {
  public static void main(String[] args) {
    int[] test = {12,1,4};
    String test2 = "Hoo";
    System.out.println(test.length);
    System.out.println(test2.length());
  }
}

Cutting a way the not so important part of the byte code, running javap -c on the class results in the following for the two last lines:

20: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
23: aload_1
24: arraylength
25: invokevirtual #4; //Method java/io/PrintStream.println:(I)V
28: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
31: aload_2
32: invokevirtual #5; //Method java/lang/String.length:()I
35: invokevirtual #4; //Method java/io/PrintStream.println:(I)V

In the first case (20-25) the code just ask the JVM for the size of the array (in JNI this would have been a call to GetArrayLength()) whereas in the String case (28-35) it needs to do a method call to get the length.

In the mid 90's, without good JITs and stuff, it would have killed performance totally to only have the java.util.Vector (or something similar) and not a language construct which didn't really behave like a class but was fast. They could of course have masked the property as a method call and handled it in the compiler but I think it would have been even more confusing to have a method on something that isn't a real class.

Fredrik
Java treats array as objects and strings as an immutable objects!! :|
Myth17
@Myth: I don't see your point... The length property of arrays is not a public field or anything, it is a construct of the jvm (arraylength is even an operation in the bytecode). It is very obvious when you do JNI or if you just disassemble the code where it comes from.
Fredrik
A: 

In Java, an Array stores its length separately from the structure that actually holds the data. When you create an Array, you specify its length, and that becomes a defining attribute of the Array. No matter what you do to an Array of length N (change values, null things out, etc.), it will always be an Array of length N.

A String's length is incidental; it is not an attribute of the String, but a byproduct. Though Java Strings are in fact immutable, if it were possible to change their contents, you could change their length. Knocking off the last character (if it were possible) would lower the length.

I understand this is a fine distinction, and I may get voted down for it, but it's true. If I make an Array of length 4, that length of four is a defining characteristic of the Array, and is true regardless of what is held within. If I make a String that contains "dogs", that String is length 4 because it happens to contain four characters.

I see this as justification for doing one with an attribute and the other with a method. In truth, it may just be an unintentional inconsistency, but it's always made sense to me, and this is always how I've thought about it.

jboxer
+4  A: 

Has been discussed before at CodeRanch.

See the discussion here.

missingfaktor
calling dupe on a previously asked StackOverflow question is useful, but linking to other sites is not as helpful. It would be better to answer the question here while citing the discussion as a source for your answer, IMO.
Carson Myers
@Myers : Why? What's the problem?
missingfaktor
@Rahul: One problem is that other sites may die, have their URLs changed or something else which makes the answer totally useless for someone who finds his way in here using google or something else. A user that clicks on a SO link is likely to expect an answer here and not somewhere else.
Fredrik
@Rahul G, and you have also to consider the marketing strategy of SO.
Joset
+1  A: 

I was taught that for arrays, length is not retrieved through a method due to the following fear: programmers would just assign the length to a local variable before entering a loop (think a for loop where the conditional uses the array's length.) The programmer would supposedly do so to trim down on function calls (and thereby improve performance.) The problem is that the length might change during the loop, and the variable wouldn't.

Matthew
Good point.....
Zaki
The length of an array can not change during the loop.
Fredrik
you can't change the length of this particular array, but you can assign a new one to the same variable
Bozho
@Bozho: True, but then it is another array and if you do that intentionally and don't update whatever you check your loop against you have a bug. Java has never had the intention to stop you from writing bugs. You can do infinite loops, recursion til you die and all kinds of logical errors without java trying to stop you from it. It is a good reason for not storing the length in a variable but it sure isn't the reason why it is designed that way.
Fredrik