이틀 전에 동료를 위해 코드 검토를했습니다. 나는 Java Generics를 잘 이해하지 못한다고 느꼈으므로 "Effective Java"1이 책을 꺼낸 후 관련 장을 보았습니다. 항목 24 : 확인되지 않은 경고 섹션을 제거하면 저자는 변수에 @SuppressWarnings 주석을 사용하는 방법을 설명하기 위해 ArrayList 클래스의 공개 <t> t [] toArray (t [] a) 메소드를 사용합니다.
ArrayList는 일반 클래스이며 다음과 같이 선언됩니다.
javapublic class arraylist <e> 확장 actractList <e> 구현 목록 <e>, randomAccess, clonable, java.io.serializable
이 클래스의 ToArray (t [] a) 방법은 일반적인 방법으로, 다음과 같이 선언되고 구현됩니다.
@SuppressWarnings ( "선택 취소") public <t> t [] toArray (t [] a) {if (a.length <size) // A의 런타임 유형의 새로운 배열을 만들지 만 내 함량 : return (t []) arrays.copyof (ElementData, size, a.getclass ()); Systic.ArrayCopy (0, 0, if); 크기) a [size] = null; return a;} 이 메소드는 실제로 컬렉션 인터페이스에서 선언됩니다. 우리는 종종 ArrayList를 통해 사용하기 때문에 여기에서 ArrayList를 사용합니다.
1 왜 다른 유형으로 선언됩니까?
내 질문은 다음과 같습니다. 왜이 방법이 Arraylist의 유형 E 대신 유형 T를 사용합니까? 즉,이 방법이 다음과 같이 선언되지 않는 이유는 다음과 같습니다.
javapublic e [] toarray (e [] a);
유형이 동일하면 컴파일 중에 매개 변수 유형 오류를 찾을 수 있습니다. 유형이 다르면 런타임 오류를 쉽게 생성 할 수 있습니다. 예를 들어 다음 코드 :
// arrayListList <String> strlist = new ArrayList <string> (); strlist.add ( "abc"); strlist.add ( "xyz"); // 현재 스트링 목록을 숫자 배열로 변환합니다. 다음 문서에는 컴파일 오류가 없습니다. 숫자 [] numarray = strlist.toArray (새 번호 [0]);
위의 코드를 실행하면 6 행은 Java.lang.arraystoreException 예외를 던집니다.
ToArray 메소드가 유형 E를 사용하면 문 2가 컴파일 오류를 생성합니다. 컴파일 오류는 런타임 오류보다 더 친숙합니다. 또한 제네릭의 주요 목적은 컴파일 중에 유형 변환 오류 (ClasscastException)를 제거하는 것입니다. 이 방법은 반대입니다. 이것은 큰 버그입니까? 나는 Java 버그를 발견했지만 여전히 그것을 믿을 수 없습니다.
인터넷을 확인한 후이 문제는 여러 번 2, 3, 4에 대해 논의되었습니다.
2는 유연성을 향상시킬 수 있습니다
이 선언은 더 유연하며 현재 목록의 요소를보다 일반적인 유형의 배열로 변환 할 수 있습니다. 예를 들어, 현재 목록 유형은 정수이며 요소를 숫자 배열로 변환 할 수 있습니다.
목록 <integer> intlist = new arraylist <integer> (); intlist.add (1); intlist.add (2); 숫자 [] numarray = intlist.toArray (새 번호 [0]);
이 메소드가 유형 E로 선언되면 위 코드에는 컴파일 오류가 발생합니다. 방법을 다음과 같이 선언하는 것이 더 적절한 것 같습니다.
javapublic <t super e> t [] toarray (t [] a);
그러나 <t super e>와 같은 구문은 Java에는 존재하지 않습니다. 그리고 그것이 존재하더라도 배열에는 효과가 없습니다. 이러한 이유로이 방법을 사용하면 t가 e의 상위 클래스이거나 t가 e, java.lang.arraystoreexception 5, 6, 7을 완전히 피할 수는 없습니다. 다음 두 코드를 참조하십시오. 첫 번째 코드에서 t는 e의 상위 클래스이고 두 번째 코드에서는 t와 동일합니다.
Code 1:
목록 <integer> intlist = new arraylist <integer> (); intlist.add (1); intlist.add (2); float [] floatArray = new float [2]; // float는 숫자의 서브 클래스이므로 float []는 숫자 [] number [] numarray = floatArray; // 숫자의 서브 클래스입니다. 다음 문서는 ArrayStoreExcection 예외를 버릴 것입니다.
Code 2:
list <number> intlist = new ArrayList <number> (); // 목록 유형은 숫자입니다. 그러나 숫자는 추상 클래스이며 서브 클래스 intlist.add (new Integer ())의 인스턴스 만 저장할 수 있습니다. intlist.add (new integer ()); float [] floatArray = new float []; // float는 숫자의 서브 클래스이므로 float []는 숫자 [] number [] numarray = floatArray; // 숫자의 서브 클래스입니다. 다음 문서는 ArrayStoreExcection 예외를 던지게됩니다. NumArray = intlist.toArray (numArray);
위의 예외는 모두이 사실에 의해 발생합니다. A가 B의 부모 클래스 인 경우 A []는 B []의 부모 클래스입니다. Java의 모든 클래스는 Object에서 상속하고 Object []는 모든 배열의 상위 클래스입니다.
이 게시물 8은이 방법의 유형이 e로 선언 되더라도 ArrayStoreException을 피할 수 없음을 보여주는 예를 제시합니다.
이 예외는이 방법에 대한 문서에도 언급되어 있습니다.
ArrayStoreExcection 지정된 배열의 런타임 유형 이이 목록의 모든 요소의 런타임 유형의 슈퍼 타입이 아닌 경우.
3 Java 1.5 이전 버전과 호환 될 수 있습니다.
이 방법은 Java에서 제네릭을 도입하기 전에 나타났습니다 (제네릭은 JDK1.5에 도입 됨). 당시에는 선언되었습니다.
Javapublic Object [] toArray (Object [] a)
제네릭이 나타나면 많은 클래스와 방법이 일반화됩니다. 이 방법은 다음과 같이 선언합니다.
javapublic <t> t [] toarray (t [] a)
이 선언은 Java 1.5 이전 버전과 호환됩니다.
4 몇 단어 더
이 메소드에는 배열 매개 변수가 필요합니다. 이 배열의 길이가 현재 목록의 크기보다 크거나 같거나 같으면 목록의 요소는 배열에 저장됩니다. 이 배열의 길이가 현재 목록의 크기보다 작 으면 새 배열이 생성되고 현재 목록의 요소가 새로 생성 된 배열에 저장됩니다. 효율성을 향상시키기 위해, 가능하면 전달 된 배열의 길이는이 방법으로 새 배열을 생성하지 않도록 목록의 크기보다 크거나 동일해야합니다.
목록 <integer> intlist = new arraylist <integer> (); intlist.add (); intlist.add (); // 배열에서 붙여 넣으면 길이는 숫자 [] numarray = intlist.toarray (new number []); // Statement // 배열에서 붙여 넣기 길이는 intlist 번호의 길이와 같다 [] numarray = intlist.toArray (새 번호 [intlist.size ()]); //성명
또한 매개 변수로서의 배열은 null이 될 수 없으며, 그렇지 않으면 NullPointerException이 발생됩니다.
각주 :
1
효과적인 Java (2 판)
2
링크
3
링크
4
링크
5
링크
6
링크
7
링크
8
링크
9
링크
10
링크
제작 : 2016-04-06 수요일 21:14
EMACS 24.5.1 (조직 모드 8.2.10)
검증
위의 내용은 편집기가 소개 한 Java arraylist.toArray (t []) 메소드의 매개 변수 유형이 E 대신 T 인 이유입니다. 모든 사람에게 도움이되기를 바랍니다!