Why in Java is the size of an array an attribute of a String and a method?

13

In Java, the size of an array of any object can be obtained with length , which would be an attribute. But in the case of String is length() , a method. However, if you have a array of String , it uses length , an attribute. Why?

For example:

    int[] a = {1,2};
    String b = "str";
    String[] c = {"aa", "bb"};

    a.length;
    b.length();
    c.length;
    
asked by anonymous 31.05.2017 / 02:18

3 answers

12

Arrays are treated differently than Strings , ArrayLists or anything else that can be counted in Java. A Array is practically a native type and its length can not be changed once it is initialized, so there is no need for encapsulation. The length variable can be directly exposed, with no side effects.

The reason why Strings uses a method instead of a variable is because it internally uses a char[] that it does not want to expose publicly (for reasons of immutability / encapsulation), so it involves the length variable in a length() method. It is the same reason why ArrayList has a size() method instead of a length variable.

Translated from What's the difference between length and length ()?

Just remembering that a String itself is also immutable, not just the array of char used internally by it, as can be confirmed at class documentation

    
31.05.2017 / 02:35
14

I went to search because I wanted to know the reason. Concludes that there is only speculation, no one knows the real reason. Only developers can answer this.

What seems clear to me is that the array being a language construct would be more appropriate to have a property than a phantom method that language deals with. Moreover, as this was one of the first things created in the language perhaps they did not think that a method could be better and more consistent.

String is a common class and Java does not have properties that only encapsulate access methods, that is, it could only have the field exposed if it did not use a method. It would create compatibility issues between implementations, versions and even would be inconsistent with other structures that need the method, a case is the CharSequence .

There are other theories, including the lists here, but they do not seem to make sense because even a public field could be put its value where necessary. You may have realized that there would be a new attribute taking up space that might or might not be needed.

I'm not a fan of the term attribute that is not even used in the language. She uses field for it .

    
31.05.2017 / 07:09
7

Just to give more detail to @Articuno's answer .

Like the @ bigown noted in your comment , strings are immutable entities. In the other comments were placed more links on the subject of immutability. One aspect of this important immutability is a matter of optimization: substring operations in Java can be implemented very lightly ( source ). Depending on the implementation of Java, a substring can be implemented as a continuous set of information of a vector of characters. From the example mentioned in the source, in the% JDK6 "abcde".substring(1,3) will generate a new string object, which carries with it the same character vector {'a', 'b', 'c', 'd', 'e'} of the initial string, but it considers that it starts from position 1 ( b ) and goes right before the 3 position, so it would be the position 2 ( c ). A Java implementation does not always guarantee that a string is the size of the character vector that loads its data, so it might be that it only loads part of it. If it is the case of the string storing the start index and the end index, the length() method returns fim - comeco ; if it is implemented with offset of the first character and count , then the result of the method would be count (according to the example that it gave of as it was in the JDK6). If the string implementation makes a copy of the desired subvector is used (as the example informs it does in JDK7), then the length() method simply returns vetorDeChar.length .

One advantage of implementing string.length() as a method is that you can completely change the internal implementation (including existing fields) without the programmer using a string being affected. For smaller applications, string implementation strategies are not initially felt.

  

@Maniero talks about encapsulation of access properties that could solve this Java idiosyncrasy

An interesting point about vectors is that access to their size is optimized by the JVM. There is a bytecode specialized in doing this: 0xBE , identified by the arraylength mnemonic. Using this specific bytecode has a lesser generated result than what would be generated if the traditional bytecode of catching fields, getfield ( 0xB4 ), is used, which requires two additional bytes for the attribute index. The Wikipedia has a page listing bytecodes .

    
31.05.2017 / 05:24