배열의 길이 속성은 어디에 정의되어 있습니까?


263

우리는의 길이를 결정할 수 있습니다 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()메소드 ArrayListArrayList클래스 내에서 정의 되는 반면, 이 length프로퍼티는 어디에 Array정의되어 있습니까?


질문 구성 측면에서 "배열의 길이 속성은 어디에 정의되어 있습니까?"라는 질문을하는 것이 좋습니다. 게시물이 초보자 용 자습서처럼 들리지 않도록 모든 설명 전에
NONAME

답변:


250

배열은 Java의 특수 객체이며 이름이라는 간단한 속성 lengthfinal있습니다.

배열의 "클래스 정의"는 없으며 (.class 파일에서 찾을 수 없음) 언어 자체의 일부입니다.

10.7. 배열 구성원

배열 유형의 멤버는 모두 다음과 같습니다.

  • public final필드 length배열의 요소의 수를 포함. length양수 또는 0 일 수 있습니다.
  • public메소드 clone는 클래스에서 동일한 이름의 메소드를 대체하고 Object확인 된 예외를 발생시키지 않습니다. clone배열 유형 의 메소드의 리턴 유형은 T[]입니다 T[].

    다차원 배열의 복제본은 얕습니다. 즉, 하나의 새 배열 만 만듭니다. 하위 배열이 공유됩니다.

  • 모든 멤버는 클래스에서 상속되었습니다 Object. Object상속되지 않는 유일한 방법 은 그 clone방법입니다.

자원:


84
또한 ArrayList.size()실제로 배열에 저장된 객체 수 를 제공하는 반면 myArray.length( [])는 "용량"을 제공합니다. 즉,의 경우 myArray = new int[10];10을 반환합니다. 배열에 넣은 개체 수는 아닙니다.
wmorrison365

1
@Colin 배열 객체가 그렇게 특별한 이유 디자이너가 그것을 특수하게 만들어야하는 이유와 배열의 클래스 파일을 제공하지 않는 이유는 무엇입니까?
Vikas Verma

5
@VikasVerma 왜 배열은 객체와 같지 않습니까? 역사 때문에. 자바가 설계되었을 때, 언어 혁신에 대한 대부분의 시도는 구문과 스타일면에서 C와 비슷하지 않을 때 실패했습니다. 따라서 C ++, Objective-C 및 Java는 그 시대에 모호함을 피하기 위해 소수의 언어 중 하나였습니다. Java는 의식적으로 중괄호, 프리미티브 및 일반 배열을 포함하여 오늘날의 주류 프로그래머에게 친숙하게 보이 도록 설계되었습니다 . James Gosling 및 기타 Sun 직원과의 인터뷰를 참조하십시오. 어떤 사람들은 순수한 OOP를 위해 컬렉션을 고수하고 일반 배열을 피합니다.
Basil Bourque

1
@VikasVerma는 어느 시점에서 자바는 저수준 기술을 기반으로해야합니다. java가 존재하지 않으면 java로 빌드 할 수 없습니다. C ++ (또는이 경우 C ++)을 사용하여 나머지 Java가 고유 한 컨텍스트를 갖도록 원시 컴파일을 빌드해야합니다. C ++로 코딩 할 때 바닥을 치지 않으면 모든 것에 대한 클래스를 가질 수 없습니다. Java로 정확히 배열을 작성 하시겠습니까? List구현에 배열을 사용하기 때문에 사용할 수없는 경우 .
Alexander Bird

당신은 그것을 응답 할 경우 와 같이 다음, stackoverflow.com/a/50506451/1059372
유진

114

기본적으로 자체 바이트 코드 명령과 함께 "특별" 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));

불행히도 공개 최종 필드 length가 있는 각 배열 유형의 JLS 설명 은 다소 오도됩니다.


1
내가 알버트 아인슈타인에 의해 정확하게 견적을 기억하지 않지만이의는 "사람들이 매우 간단한 방법으로 일을 설명 할 수 아주 잘 일을 이해"무슨 말을 내가 그것을 :) 아주 잘 맞는 생각
JAVA

@Jon Skeet 배열 객체가 특별한 이유 디자이너가 그것을 특수하게 만들어야하는 이유와 배열의 클래스 파일을 제공하지 않는 이유는 무엇입니까?
Vikas Verma

2
@VikasVerma : 배열 객체의 크기를 생각하십시오. 다른 모든 유형의 크기는 고정되어 있습니다. 모든 인스턴스의 크기는 동일하지만 배열은 길이에 따라 다릅니다. 한 가지 예일뿐입니다. 특별한 것을 사용하지 않고 동일한 결과를 얻을 수 있다고 생각되면 배열 클래스의 필드는 어떻게 생겼을까 요? int[]제네릭이 기본 유형에 적용되지 않는 경우를 어떻게 표현 하시겠습니까? (그리고 어쨌든 제네릭은 오랫동안 존재하지 않았습니다.) 모든 컬렉션에 대해 링크 된 목록을 사용하면 배열 없이도 도망 갈 수 있지만 효율성은 끔찍합니다.
Jon Skeet

@JonSkeet 그러나 StringBuffer 클래스 유형은 크기가 고정되어 있습니까? 네, 실제로 제네릭에 대해 생각하고 있었지만 고맙습니다.
Vikas Verma

@VikasVerma : StringBuffer클래스 자체는 그렇습니다 char[]. 따라서 a StringBuilder는 더 많은 메모리를 담당하지만 즉시 크기와 레이아웃이 고정됩니다.
Jon Skeet

18

Java 언어 사양에 정의되어 있습니다 .

배열 유형의 멤버는 모두 다음과 같습니다.

  • public final필드 length배열의 요소의 수를 포함. length양수 또는 0 일 수 있습니다.

어레이 형태의 무한 개수가 존재하기 때문에 (각 클래스에 대응하는 어레이 형태가 있고, 그 다음 , 그들이 클래스 파일에서 구현 될 수있는 다차원 배열이있다); JVM은 즉시 수행해야합니다.


15

이것이 질문에 대한 직접적인 대답은 아니지만 .length.size()논쟁에 추가됩니다 . 나는이 질문과 관련된 것을 연구하고 있었으므로 그것을 만났을 때 나는 여기에 정의가 제공되어 있음을 알았습니다.

배열의 구성 요소 수 를 포함하는 공개 최종 필드 길이 입니다.

"정확하게"정확하지 않습니다.

필드 길이에는 배열에있는 구성 요소 수가 아니라 구성 요소를 배치 할 수있는 사용 가능한 위치 수가 포함 됩니다. 따라서 해당 메모리에 얼마나 많은 메모리가 채워져 있는지가 아니라 해당 어레이에 할당 된 총 가용 메모리를 나타냅니다.

어레이 메모리 할당

예:

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

1
모든 요소가 0으로 초기화되므로 정확합니다. 배열은 "빈"수 없습니다
Guido

그게 바로 내가 말한 것입니다. "정확하게"정확하지 않습니다. 어레이에 추가 된 것이 없더라도 여전히 길이는 5입니다. 따라서 배열의 요소 수를 "정확하게"포함하지 않습니다. 귀하의 의견은 내 대답에 대한 추가 사항이며 잘못된 이유는 아닙니다.
nem035

null널이 아닌 요소와 구별 하지 않는 요소를 구별하려고하면 "잘못된"것일 수 있습니다 . 그러나 구별이 작동하지 않습니다. 결국, size()of (즉) a 도 값을 List포함 할 수있다 null.
Stephen C

기본적으로 제 요점은 size동적으로 동작하는 반면 length정적 속성은 ... 배열의 채워지지 않은 나머지 공간이 " 비값 "(유형에 따라)으로 초기화된다는 사실은 이 점과 실제로 모순되지 않습니다.
nem035

5

배열의 구성 요소 수를 포함하는 public final field입니다 (길이는 양수이거나 0 일 수 있음).

따라서 배열은 다음 클래스와 동일한 공용 필드 및 메소드를 갖습니다.

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


0

그대로 대답하려면 배열 의이 길이 속성은 어디에 정의되어 있습니까? 특별 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)

일반적으로 객체는 두 개의 헤더 (마크와의 klass), 배열은 항상 점유하는 것이 더욱 하나가이 4 bytes같은 길이를 size입니다 int.


-1

키워드 길이는 정의 된 데이터와 같은 역할을합니다. 배열에서 사용할 때 배열을 사용하여 배열의 요소 수에 액세스 할 수 있습니다. String []과 관련하여 String 클래스에 정의 된 length () 메서드를 호출 할 수 있습니다. ArrayList와 관련하여 ArrayList에 정의 된 size () 메서드를 사용할 수 있습니다. ArrayList <> (capacity)로 배열 목록을 만들 때 요소가 없으므로이 배열 목록의 초기 크기 ()는 0입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.