Java ArrayList.toArray(T[]) 방법의 매개 변수 유형은 E가 아닌 T의 원인 분석

5121 단어 arraylisttoarray
이틀 전 동료에게 코드 리뷰를 해주면서 자바의Generics에 대해 잘 파악하지 못한 것 같아서'Effective 자바'1이라는 책을 꺼내 관련 부분을 살펴보았다.Item 24: Eliminate unchecked warnings 이 절에서 저자는 Array List 클래스의public ArrayList는 generic class입니다.

Javapublic class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
이 종류의 toArray(T[]a) 방법은 generic method입니다. 이것은 이렇게 설명하고 실현됩니다.

@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
이 방법은 사실상 Collection 인터페이스에서 설명한 것이다.우리는 자주 Array List를 통해 그것을 사용하기 때문에, 여기에는 Array List를 예로 들 수 있다.
1 왜 다른 유형으로 선언합니까?
내 질문: 왜 이 방법은 유형 T를 사용하고 ArrayList의 유형 E를 사용하지 않습니까?즉, 이 방법은 왜 이렇게 성명하지 않는가.

Javapublic E[] toArray(E[] a);
만약 형식이 같다면, 컴파일하는 동안 매개 변수의 형식 오류를 발견할 수 있습니다.유형이 다르면 실행 중 오류가 발생하기 쉽습니다.예를 들어 아래의 코드:

//  String   ArrayList
List<String> strList = new ArrayList<String>();
strList.add("abc");
strList.add("xyz");
//  strList   Number  。 , 。
Number[] numArray = strList.toArray(new Number[0]);
위의 코드를 실행하면 라인 6가java를 던집니다.lang. ArrayStoreException 예외.
ToArray 메서드에서 유형 E를 사용하면 문장 2에서 컴파일 오류가 발생합니다.번역 오류는 아무래도 운행 오류보다 친절하군요.그리고generics의 주요 목적은 형식 안전을 위해 형식 변환 오류(ClassCastException)를 컴파일하는 동안 없애는 것이다.이 방법은 도리를 거꾸로 행하였다.설마 이게 큰 버그야?자바의 버그는 내가 만났지만, 이곳에서 버그가 나온다는 것은 나는 아직 그다지 믿을 수 없다.
인터넷에 접속해 보니 이 문제는 이미 여러 차례 토론되었다. 2, 3, 4.
2 유연성 향상
이러한 성명은 현재list의 요소를 더욱 일반적인 유형의 그룹으로 변환할 수 있는 유연성을 가진다.예를 들어 현재list의 유형은 Integer입니다. 우리는 그것의 요소를 하나의 Number 그룹으로 변환할 수 있습니다.

List<Integer> intList = new ArrayList<Integer>();
intList.add(1);
intList.add(2);
Number[] numArray = intList.toArray(new Number[0]);
만약 이 방법이 유형 E로 성명된다면, 위의 코드는 컴파일 오류가 있을 것이다.보기에 이 방법은 다음과 같이 성명하는 것이 더욱 적합할 것 같다.

Javapublic <T super E> T[] toArray(T[] a);
그러나 와 같은 문법은 자바에 존재하지 않는다.그리고 존재하더라도 수조에 작용하지 않는다.그렇기 때문에 이 방법을 사용할 때 T가 E의 부류이거나 T가 E와 같아도 자바를 완전히 피할 수 없다.lang. ArrayStoreException 이상 5, 6, 7.아래 두 단락의 코드를 보십시오.첫 번째 코드에서 T는 E의 부류이고 두 번째 코드에서 T는 E와 같다.이 두 단락의 코드는 모두 이상을 던질 것이다.
코드 1:

List<Integer> intList = new ArrayList<Integer>();
intList.add(1);
intList.add(2); 
Float[] floatArray = new Float[2];
//Float   Number  ,  Float[]   Number[]  
Number[] numArray = floatArray;
//  ArrayStoreException  
numArray = intList.toArray(numArray);
코드 2:

List<Number> intList = new ArrayList<Number>();
//List   Number。  Number  , 
intList.add(new Integer());
intList.add(new Integer()); 
Float[] floatArray = new Float[];
//Float   Number  ,  Float[]   Number[]  
Number[] numArray = floatArray;
//  ArrayStoreException  
numArray = intList.toArray(numArray);
위의 이상은 모두 이 사실로 인해 발생한 것이다. 만약에 A가 B의 부류라면 A[]는 B[]의 부류이다.Java의 모든 클래스는 Object에서 상속되며 Object[]는 모든 배열의 상위 클래스입니다.
이 글은 8에서 예를 들어 이 방법의 유형이 E로 밝혀져도 ArrayStore Exception 이상을 피할 수 없다는 것을 설명한다.
이 방법의 문서에서도 이 이상이 언급되었다.

ArrayStoreException if the runtime type of the specified array is not a supertype of the runtime type of every element in this list.
3 Java 1.5 이전 버전과 호환 가능
이 방법은 자바가 Generics를 도입하기 전에 (JDK1.5에서 Generics를 도입했다) 9가 나왔다.그때 그것은 이렇게 성명되었다.

Javapublic Object[] toArray(Object[] a)
Generics가 등장한 후, 많은 종류와 방법들이generic로 변했다.이 방법도 대세에 따라 이렇게 성명되었다.

Javapublic <T> T[] toArray(T[] a)
이렇게 하면 Java 1.5 이전 버전과 10을 호환할 수 있습니다.
4 잔소리 두 마디
이 방법은 수조 파라미터가 필요하다.만약 이 그룹의 길이가 현재list의size보다 크거나 같으면list의 요소는 이 그룹에 저장됩니다.이 그룹의 길이가 현재list의size보다 작으면 새 그룹을 만들고 현재list의 요소를 이 새로 만든 그룹에 저장합니다.효율을 높이기 위해서, 가능하다면, 전송된 그룹의 길이는list의size보다 크거나list의size보다 커서, 이 방법으로 새 그룹을 만드는 것을 피해야 합니다.

List<Integer> intList = new ArrayList<Integer>();
intList.add();
intList.add();
// ,  
Number[] numArray = intList.toArray(new Number[]); // 
// ,  intList  
Number[] numArray = intList.toArray(new Number[intList.size()]); // 
또한 매개 변수인 그룹은null일 수 없습니다. 그렇지 않으면 NullPointerException 이상이 발생합니다.
Footnotes:

Effective Java (2nd Edition)

Link

Link

Link

Link

Link

Link

Link

Link

Link
Created: 2016-04-06 Wed 21:14
Emacs 24.5.1 (Org mode 8.2.10)
Validate
위의 내용은 여러분에게 소개할 Java Array List입니다.toArray(T[]) 방법의 매개 변수 유형은 E가 아닌 T의 원인 분석입니다. 여러분에게 도움이 되기를 바랍니다!

좋은 웹페이지 즐겨찾기