[java] 왜 배열을 Iterable에 할당 할 수 없습니까?

Java5를 사용하면 다음과 같이 작성할 수 있습니다.

Foo[] foos = ...
for (Foo foo : foos) 

또는 for 루프에서 Iterable을 사용하십시오. 이것은 매우 편리합니다.

그러나 다음과 같이 iterable에 대한 일반적인 메소드를 작성할 수 없습니다.

public void bar(Iterable<Foo> foos) { .. }

Iterable이 아니기 때문에 배열로 호출하십시오.

Foo[] foos = { .. };
bar(foos);  // compile time error 

이 디자인 결정의 이유에 대해 궁금합니다.



답변

배열은 인터페이스 ( Cloneablejava.io.Serializable)를 구현할 수 있습니다 . 왜 안돼 Iterable? 필자 Iterableiterator메소드를 추가해야 한다고 생각 하고 배열은 메소드를 구현하지 않습니다. char[]재정의하지도 않습니다 toString. 어쨌든 참조 배열은 이상적인 용도보다 덜 고려되어야합니다 List. dfa 의견 Arrays.asList으로 명시 적으로 변환을 수행합니다.

(단, clone배열을 호출 할 수 있다고 말했습니다 .)


답변

배열이 Object이지만 해당 항목이 아닐 수 있습니다. 배열은 int와 같은 기본 유형을 보유 할 수 있으며 Iterable은 대처할 수 없습니다. 적어도 그것이 내가 생각하는 것입니다.


답변

배열 Iterable은 .NET 배열이 위치별로 읽기 전용 임의 액세스를 허용하는 인터페이스를 지원하지 않는 것과 같은 이유로 지원하지 않아야합니다 (표준으로 정의 된 인터페이스는 없습니다). 기본적으로 프레임 워크에는 종종 성가신 작은 틈이있어서 고칠 시간이 없습니다. 우리가 그것들을 최적의 방법으로 스스로 고칠 수 있는지는 중요하지 않지만 종종 우리는 해결할 수 없습니다.

업데이트 : 균등하게하기 위해 위치별로 임의 액세스를 지원하는 인터페이스를 지원하지 않는 .NET 배열에 대해 언급했습니다 (내 의견 참조). 그러나 .NET 4.5에서는 정확한 인터페이스가 정의되어 배열과 List<T>클래스에서 지원됩니다 .

IReadOnlyList<int> a = new[] {1, 2, 3, 4};
IReadOnlyList<int> b = new List<int> { 1, 2, 3, 4 };

가변 목록 인터페이스 IList<T>가 상속하지 않기 때문에 여전히 완벽 하지는 않습니다 IReadOnlyList<T>.

IList<int> c = new List<int> { 1, 2, 3, 4 };
IReadOnlyList<int> d = c; // error

이러한 변경으로 인해 이전 버전과의 호환성이있을 수 있습니다.

최신 버전의 Java에서 비슷한 일이 진행되면 의견을 알고 싶습니다. 🙂


답변

불행히도, 배열은 ‘ class충분 하지’않습니다 . Iterable인터페이스를 구현하지 않습니다 .

배열은 이제 Clonable 및 Serializable을 구현하는 객체이지만 배열은 정상적인 의미의 객체 가 아니며 인터페이스를 구현하지 않는다고 생각합니다.

for-each 루프에서 사용할 수있는 이유는 Sun이 배열을 위해 일부 신택스 설탕을 추가했기 때문입니다 (특별한 경우입니다).

배열은 Java 1에서 ‘거의 객체’로 시작되었으므로 Java에서 실제 객체 로 만들기 위해 변경이 너무 과감 할 것 입니다.


답변

컴파일러는 실제로 for each배열을 for카운터 변수가 있는 간단한 루프 로 변환합니다 .

다음 컴파일

public void doArrayForEach() {
    int[] ints = new int[5];

    for(int i : ints) {
        System.out.println(i);
    }
}

그런 다음 .class 파일을 디 컴파일하면

public void doArrayForEach() {
    int[] ints = new int[5];
    int[] var2 = ints;
    int var3 = ints.length;

    for(int var4 = 0; var4 < var3; ++var4) {
        int i = var2[var4];
        System.out.println(i);
    }
}


답변