it-swarm.com.ru

Где определено свойство длины массива?

Мы можем определить длину ArrayList<E>, используя его открытый метод size(), например

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

Точно так же мы можем определить длину объекта Array, используя свойство length

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

Принимая во внимание, что метод size()ArrayList определен внутри класса ArrayList, где определено это свойство lengthArray?

256
NINCOMPOOP

Массивы - это специальные объекты в Java, у них есть простой атрибут с именем length, который final.

Не существует «определения класса» массива (вы не можете найти его ни в одном файле .class), они являются частью самого языка.

10,7. Члены массива

Членами типа массива являются все следующие:

  • Поле publicfinallength, которое содержит количество компонентов массива. length может быть положительным или нулевым.
  • Метод publicclone, который переопределяет метод с тем же именем в классе Object и не выдает никаких проверенных исключений. Тип возврата метода clone типа массива T[]: T[].

    Клон многомерного массива неглубокий, то есть он создает только один новый массив. Подмассивы являются общими.

  • Все члены унаследованы от класса Object; единственный метод Object, который не наследуется, это его метод clone.

Ресурсы:

247
Colin Hebert

В основном это «особенный» со своей собственной инструкцией байт-кода: arraylength. Итак, этот метод:

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

компилируется в байт-код следующим образом:

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

Так что это не так, как если бы это было нормальное поле. Действительно, если вы попытаетесь получить его так, как если бы оно было нормальным полем, например, это не сработает:

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

Так что, к сожалению, описание JLS каждого типа массива с открытым финальным полем length несколько вводит в заблуждение :(

114
Jon Skeet

Это определено в спецификации языка Java :

Членами типа массива являются все следующие:

  • Поле public finallength, которое содержит количество компонентов массива. length может быть положительным или нулевым.

Поскольку существует неограниченное количество типов массивов (для каждого класса есть соответствующий тип массива и then существуют многомерные массивы), они не могут быть реализованы в файле класса; JVM должна делать это на лету.

18
Michael Borgwardt

Хотя это и не прямой ответ на вопрос, это дополнение к аргументу .length vs .size(). Я исследовал что-то, связанное с этим вопросом, поэтому, когда я столкнулся с этим, я заметил, что приведенное здесь определение (я)

Общая длина конечного поля, которая содержит количество компонентов массива

не "точно" правильно.

Длина поля содержит количестводоступных местдля размещения компонента, а не количество компонентов, присутствующих в массиве. Таким образом, он представляет общий объем доступной памяти, выделенной этому массиву, а не объем этой памяти. 

Array Memory Allocation

Пример:

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

Результат:

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

Тем не менее, свойство .size()ArrayList определяет количество элементов в списке:

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

Результат:

List size:  0
List size:  1
List size:  2
15
nem035

это открытое конечное поле, которое содержит количество компонентов массива (длина может быть положительной или нулевой)

Таким образом, массив имеет те же открытые поля и методы, что и следующий класс:

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

больше информации на 

10.7 Члены массива

http://Java.Sun.com/docs/books/jls/second_edition/html/arrays.doc.html

5
Massimiliano Peluso

Длина ключевого слова действует как определенная область данных. При использовании в массиве мы можем использовать его для доступа к количеству элементов в массиве. Что касается String [], мы можем вызвать метод length (), определенный в классе String. Что касается ArrayList, мы можем использовать метод size (), определенный в ArrayList. Обратите внимание, что при создании списка массивов с ArrayList <> (Capacity), начальный размер () этого списка массивов равен нулю, так как нет элемента.

0
Xiaogang

Чтобы ответить на него как есть, где определено это свойство длины массива? В специальном Object header.

Легко видеть через JOL

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

Одна из строк этого вывода будет:

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

Обычно объекты имеют два заголовка (mark и klass), у массивов есть еще один, который всегда занимает длину 4 bytes, так как size является int.

0
Eugene