이 논문은 예제와 함께 Java 프로그래밍에서 JDK1.4, JDK1.5 및 JDK1.6의 차이를 분석합니다. 다음과 같이 참조에 대해 공유하십시오.
간단히 말해서 : 1.4와 1.5 사이에는 두 가지 가장 큰 차이점이 있습니다. 하나는 1.5에 제네릭이 있고 다른 1.5는 8 개의 기본 데이터 유형의 캡슐화 된 데이터 유형을 자동으로 캡슐화 할 수 있습니다. 즉, 정수 a = 4는 허용되지 않습니다. 1.5와 1.6 사이에는 큰 차이가 없습니다. 1.6 대부분의 변화는 GUI라고 생각합니다. 이는 많은 편리한 레이아웃 관리 및 확장을 제공합니다.
이 기간 동안 나는 전자 정부 회사에 합류하여 Weblogic8을 사용했습니다. 그런 다음 JDK1.4를 사용해 봅시다. Eclipse는 JDK 버전을 변경했습니다. 그러나 이전 프로젝트는 기본적으로 인기를 얻었습니다.
★ JDK1.5의 새로운 기능 :
1. 제네릭
2 자동 포장/개봉
3 세
4 정적 가져 오기
5 가변 길이 매개 변수
1. 제네릭 (유형 주조로 인한 오류를 피하십시오)
예를 들어:
ArrayList List = New ArrayList (); list.add (새 정수 (3)); list.add (새 정수 (4)); int i = ((정수) (list.get (0))). parseint ();
매우 번거 롭습니다
ArrayList <integer> list = new ArrayList <integer> (); list.add (새 정수 (3)); list.add (새 정수 (4)); int i = list.get (0) .parseint ();
2 자동 포장/개봉
위의 예의 마지막 문장은 다음으로 변경 될 수 있습니다.
코드 사본은 다음과 같습니다. int i = list.get (0);
원래 유형과 해당 래퍼 클래스를 명시 적으로 변환 할 필요가 없기 때문에
3 세
루프 향상
int a [] = {......}; // 초기화 (int i : a) {......}이전 i = 0; i <a.length; i ++를 사용하지 마십시오
4 정적 가져 오기
이전에 Java.Math를 조정했습니다
코드 사본은 다음과 같습니다. Math.sqrt ();
이제 정적 가져 오기 java.lang.math.sqrt;
sqrt ();
이 방법을 자신의 수업에 갖는 것과 같습니다.
5 가변 길이 매개 변수
int sum (int ... intlist) {int sum; 합 = 0; for (int i = 0; i <intlist.length; i ++) {sum+= intlist [i]; } 반환 합계;}매개 변수가 있으며 배열로 취급하십시오
★ JDK6.0의 새로운 기능
루프 명령문 주석 주석에 대한 향상된 "숨겨진"정적 메소드 variadic 매개 변수 (vararg)
루프 명령문에 대한 와일드 카드 및 공분산 반환이 강화되었습니다
오버 세트 및 어레이를 반복하기 위해 향상된 루프는 간단하고 호환 가능한 구문을 제공합니다. 언급 할 가치가있는 두 가지 점이 있습니다.
1. 루프에서 초기화 표현식은 한 번만 계산됩니다. int 표현
에 대한 강력한 :
int sum = 0; 정수 [] 숫자 = computenumbers (); for (int i = 0; i <numbers.length; i ++) sum+= 숫자 [i];
향상 :
int sum = 0; for (int number : computenumbers ()) sum += 숫자;
한정
루프 반복을 위해 향상시 반복자 또는 첨자에 액세스 할 수 없습니다.
다음 예를 참조하십시오.
for (int i = 0; i <numbers.length; i ++) {if (i! = 0) system.out.print ( ","); system.out.print (숫자 [i]);}또 다른 예는 다음과 같습니다.
for (iterator <integer> it = n.iterator (); it.hasnext ();) if (it.next () <0) it.remove ();
의견
주석 처리는 큰 주제입니다. 이 기사는 핵심 언어 기능에만 초점을 맞추기 때문에 가능한 모든 형태와 함정을 다루려고하지는 않습니다. 우리는 내장 주석 (억제, 감가 상승 및 재정의) 및 일반 주석 처리의 한계에 대해 논의 할 것입니다.
경고를 억제하십시오
이 주석은 클래스 또는 메소드 레벨에서 컴파일러 경고를 끕니다. 때로는 코드가 거부 된 메소드를 사용해야하거나 유형-안전이 유형-안전인지 정적으로 결정할 수없는 작업을 수행해야한다는 것을 컴파일러보다 더 명확하게 알고 있습니다.
@suppresswarnings ( "감가 상각") public static void selfdestruct () {thread.currentthread (). stop ();}이것은 아마도 내장 주석에서 가장 유용한 것일 것입니다. 불행히도, 1.5.0_04의 Javac은이를 지원하지 않습니다. 그러나 1.6은 그것을지지하고 Sun은 그것을 1.5로 거꾸로 포팅하기 위해 노력하고 있습니다.
이 주석은 Eclipse 3.1에서 지원되며 다른 IDE도 지원할 수 있습니다. 이를 통해 경고에서 코드를 완전히 제거 할 수 있습니다. 컴파일 시간에 경고가있는 경우 방금 추가했는지 확인할 수 있습니다. 안전하지 않은 코드를 보는 데 도움이됩니다. 제네릭이 추가되면 사용하는 것이 더 편리합니다.
더 이상 사용되지 않았습니다
불행히도, 더 이상 사용되지 않는 것은 그다지 유용하지 않습니다. 원래 @deprecated javadoc 태그를 대체하기위한 것이었지만 필드가 포함되어 있지 않기 때문에 감가 상승 클래스 또는 메소드 사용자가 교체로 사용 해야하는 것을 제안 할 방법이 없습니다. 최대
두 가지 사용에는 Javadoc 태그 와이 주석이 필요합니다.
보수
Override는 주석이 주석을 달 때 슈퍼 클래스에서 동일한 서명으로 메소드를 무시해야한다고 말합니다.
@overridepublic int hashcode () {...}위의 예를 살펴보면 "C"가 해시 코드에서 자본화되지 않은 경우 컴파일 시간에 오류가 없지만 런타임에 예상대로 메소드가 호출되지 않습니다. 오버라이드 태그를 추가하면 컴파일러가 실제로 다시 작성된 경우 프롬프트가됩니다.
이것은 또한 슈퍼 클래스가 변하는 상황에서도 도움이됩니다. 새 매개 변수가 메소드에 추가되고 메소드 자체의 이름이 바뀌면 더 이상 슈퍼 클래스에서 아무것도 다시 작성하지 않기 때문에 서브 클래스가 갑자기 컴파일되지 않습니다.
다른 메모
의견은 다른 시나리오에서 매우 유용합니다. 동작을 직접 수정하지 않고 동작을 직접 수정하지 않고 특히 보일러 플레이트 코드를 추가 할 때 동작을 향상시키는 경우, 주석은 EJB 및 웹 서비스와 같은 프레임 워크에서 매우 잘 작동합니다.
주석은 전처리 자로 사용할 수 없습니다. Sun의 디자인은 특히 주석으로 인해 클래스의 바이트 코드의 수정을 방지합니다. 이를 통해 언어의 결과를 올바르게 이해할 수 있으며 IDE와 같은 도구는 심층 코드 분석 및 리팩토링을 수행 할 수 있습니다.
댓글은은 총알이 아닙니다. 내가 처음 접했을 때 사람들은 다양한 기술을 시도하려고 노력했습니다. 다른 사람들로부터 얻은 다음 제안을 참조하십시오.
공개 클래스 foo {@propertyprivate int bar;}아이디어는 개인 필드 바에 대한 Getter 및 Setter 메소드를 자동으로 작성하는 것입니다. 불행히도이 아이디어에는 두 가지 실패가 있습니다. 1) 작동하지 않으며 2) 코드를 읽고 처리하기가 어렵습니다. 앞에서 언급했듯이 Sun은 특히 주석으로 클래스의 수정을 방지하기 때문에 구현할 수 없습니다.
가능하더라도 코드를 잘 읽을 수 없게하기 때문에 좋은 생각이 아닙니다. 이 코드를 처음 볼 때 주석이 메소드를 생성한다는 것을 알 수 없습니다. 또한 향후 이러한 방법 내에서 일부 작업을 수행 해야하는 경우 의견은 쓸모가 없습니다. 요컨대, 정기적 인 코드가 댓글로 할 수있는 일을하려고하지 마십시오.
낱낱이 세다
Enum은 공개 정적 최종 INT 선언과 매우 흡사하며 수년 동안 열거적 값으로 사용되었습니다. INT에 대한 가장 크고 가장 명백한 개선은 유형 안전입니다. 다른 유형을 하나의 유형의 열거로 대체 할 수는 없으며,이 유형의 열거로 교체 할 수는 없으며 모든 int는 컴파일러에 대해 동일합니다. 예외가 거의 없으면 모든 열거 스타일의 int 구조는 일반적으로 열렬한 인스턴스로 대체되어야합니다.
열거는 몇 가지 추가 기능을 제공합니다. 두 개의 실제 클래스 열거 및 열거는 열거를 위해 특별히 최적화 된 표준 세트 구현입니다. 컬렉션에 열거 유형 만 포함되어 있다는 것을 알고 있으면 해시 맵 또는 해시 세트 대신 이러한 특수 컬렉션을 사용해야합니다.
대부분의 경우 ENUM을 사용하여 코드의 모든 공개 정적 최종 INT를 대체 할 수 있습니다. 그것들은 비교할 수 있고 정적으로 가져올 수 있으므로 내부 클래스 (또는 내부 열거 유형)의 경우에도 그에 대한 참조가 동등한 것으로 보입니다. 열거 유형을 비교할 때이를 선언하는 지침은 순차적 값을 나타냅니다.
"숨겨진"정적 방법
모든 열거 형 유형 선언에 두 가지 정적 메소드가 나타납니다. 그것들은 열거적인 방법 자체가 아닌 열거적 서브 클래스의 정적 방법이기 때문에 java.lang.enum의 javadoc에는 나타나지 않습니다.
첫 번째는 values ()이며, 열거 유형의 가능한 모든 값의 배열을 반환합니다.
두 번째는 valueof ()이며 제공된 문자열의 열거 유형을 반환하며 소스 코드 선언과 정확히 일치해야합니다.
방법
열거 유형에 대한 가장 좋아하는 측면 중 하나는 방법이있을 수 있다는 것입니다. 과거에는 공개 정적 최종 INT를 변환하고 데이터베이스 유형에서 JDBC URL로 변환하기 위해 일부 코드를 작성해야 할 수도 있습니다. 이제 열거 형식 자체는 완전한
코드 조작 방법. 다음은 DatabaseType 열거 유형의 추상 방법과 각 열거 인 인스턴스에 제공된 구현을 포함한 예입니다.
public enum databaseType {Oracle {public string getJdbCurl () {...}}, mySQL {public string getJdbCurl () {...}}; public acpract string getJdbCurl ();}이제 열거 유형은 실제 방법을 직접 제공 할 수 있습니다. 예를 들어:
DatabaseType dbtype = ...; 문자열 jdbcurl = dbtype.getjdbcurl ();
URL을 얻으려면 유틸리티 방법이 어디에 있는지 미리 알아야합니다.
vararg
Mutable 매개 변수를 올바르게 사용하면 일부 정크 코드가 정리됩니다. 일반적인 예는 가변 수의 문자열 매개 변수가있는 로그 메소드입니다.
log.log (문자열 코드) log.log (문자열 코드, 문자열 arg) log.log (문자열 코드, 문자열 arg1, String arg2) log.log (문자열 코드, String [] args)
변수 매개 변수를 논의 할 때 처음 4 가지 예를 새로운 변수 매개 변수로 바꾸면 호환됩니다.
다음과 같이 코드를 복사하십시오. log.log (문자열 코드, 문자열 ... Args)
모든 돌연변이 가능한 매개 변수는 소스 호환입니다. 즉, 로그 () 메소드의 모든 호출 프로그램이 다시 컴파일되면 네 가지 방법을 모두 직접 교체 할 수 있습니다. 그러나 후진 바이너리 호환성이 필요한 경우 처음 세 가지 방법을 포기해야합니다. 문자열 배열 매개 변수가있는 마지막 메소드 만 Variadic 버전과 동일하므로 variadic 버전으로 대체 할 수 있습니다.
캐스트를 입력하십시오
발신자가 어떤 유형의 매개 변수를 사용해야하는지 알 수 있으려면 변이 가능한 매개 변수가있는 유형 주조를 피해야합니다. 다음 예를 살펴보면 첫 번째 희망은 끈이고 두 번째 희망은 예외입니다.
log.log (Object ... Objects) {String Message = (String) 객체 [0]; if (Objects.length> 1) {Exception e = (예외) 개체 [1]; // 예외로 무언가를 수행}}} 메소드 서명은 다음과 같아야하며 해당 변동성 매개 변수는 각각 문자열과 예외를 사용하여 선언됩니다.
코드 사본은 다음과 같습니다. log.log (문자열 메시지, 예외 E, Objects) {... ...}
변수 매개 변수를 사용하여 유형 시스템을 파괴하지 마십시오. 강하게 입력 한 경우에만 사용할 수 있습니다. 이 규칙의 경우 PrintStream.printf ()는 흥미로운 예외입니다.이 유형은 나중에 수용 할 수 있도록 첫 번째 인수로 유형 정보를 제공합니다.
공분산 반환
공분산 반환의 기본 사용은 구현의 반환 유형이 API보다 더 구체적인 것으로 알려진 경우 유형 주조를 피하는 것입니다. 다음 예에서는 동물 대상을 반환하는 동물원 인터페이스가 있습니다. 우리의 구현은 AnimalIMPL 객체를 반환하지만 JDK 1.5 이전에는 Animal Object를 반환하도록 선언해야합니다. :
공공 인터페이스 동물원 {public Animal Getanimal ();} 공개 클래스 zooimpl은 동물원 {public Animal Getanimal () {return new Animalimpl ();}}공분산 수익률을 사용하면 세 가지 패턴이 있습니다.
직접 필드 액세스. API 제한을 우회하기 위해 일부 구현은 서브 클래스를 필드에 직접 노출시킵니다.
다음과 같이 코드를 복사하십시오. zooimpl._animal
또 다른 형태는 구현이 실제로 특정 하위 클래스라는 것을 알면서 호출 프로그램에서 다운 변환을 수행하는 것입니다.
코드 사본은 다음과 같습니다.
내가 본 마지막 형태는 완전히 다른 서명으로 인한 문제를 피하는 데 사용되는 구체적인 방법입니다.
코드 사본은 다음과 같습니다. zooimpl._getanimal ();
이 세 가지 모드에는 문제와 한계가 있습니다. 충분히 깔끔하지 않거나 불필요한 구현 세부 사항을 노출시킵니다.
공분산
공분산 반환 모드는 더 깨끗하고 안전하며 유지 관리가 쉽고 유형 주조 또는 특정 방법 또는 필드가 필요하지 않습니다.
public Animalimpl getanimal () {return new Animalimpl (); } 결과 사용 :
코드 사본은 다음과 같습니다. zooimpl.getanimal (). inmpmethod ();
제네릭 사용
우리는 제네릭 사용과 제네릭 구성의 두 가지 관점에서 제네릭에 대해 배울 것입니다. 목록, 세트 및지도의 명백한 사용에 대해서는 논의하지 않습니다. 일반 컬렉션이 강력하고 자주 사용해야한다는 것을 아는 것으로 충분합니다.
우리는 일반적인 방법의 사용과 유형을 추론하는 컴파일러의 방법에 대해 논의 할 것입니다. 일반적으로 이것들 중 어느 것도 잘못되지 않지만 무언가 잘못되면 오류 메시지가 매우 혼란 스러울 수 있으므로 이러한 문제를 해결하는 방법을 알아야합니다.
일반적인 방법
Java 5는 일반적인 유형 외에도 일반적인 방법을 도입합니다. java.util.collections 의이 예에서는 단일 요소 목록이 구성됩니다. 새 목록의 요소 유형은 방법에 전달 된 객체의 유형에 따라 추론됩니다.
다음과 같이 코드를 복사하십시오. static <t> list <t> collections.singletonlist (t o)
예제 사용 :
공개 목록 <integer> getListOfone () {return collections.singletonList (1);}예제 사용에서 우리는 int를 통과합니다. 따라서 메소드의 리턴 유형은 <integer> 목록입니다. 컴파일러는 t를 정수로 끌어냅니다. 일반적으로 유형 매개 변수를 명시 적으로 지정할 필요가 없기 때문에 일반 유형과 다릅니다.
이것은 또한 오토 옥싱과 제네릭 사이의 상호 작용을 보여줍니다. 유형 매개 변수는 참조 유형이어야합니다. 그래서 우리는 목록 <int> 대신 목록 <integer>를 받고 있습니다.
매개 변수가없는 일반 방법
emptylist () 메소드는 java.util.collections에서 empty_list 필드의 유형-안전 순열으로 제네릭으로 소개됩니다.
다음과 같이 코드를 복사하십시오. static <t> list <t> collections.emplylist ()
예제 사용 :
공개 목록 <integer> getnointegers () {return collections.emplyist ();}이전 예제와 달리이 방법은 매개 변수가 없으므로 컴파일러는 어떻게 T 유형을 추론합니까? 기본적으로 매개 변수를 한 번 사용하려고합니다. 작동하지 않으면 반품 또는 할당 유형을 다시 사용하려고합니다. 이 예에서 리턴은 <integer> 목록이므로 T는 정수로 추론됩니다.
return 문 또는 할당 문 밖에서 일반 방법이 호출되면 어떻게됩니까? 그런 다음 컴파일러는 유형 추론의 두 번째 전송을 수행 할 수 없습니다. 다음 예에서는 empallist ()가 조건부 연산자 내부에서 호출됩니다.
공개 목록 <integer> getnointegers () {return x? collections.emptylist () : null;} 컴파일러는 반환 컨텍스트를 볼 수없고 t를 추론 할 수 없기 때문에 객체를 포기하고 가져옵니다. "<boodge>를 <integer>를 나열하도록 목록을 변환 할 수 없음"과 같은 오류 메시지가 표시됩니다.
이 오류를 해결하려면 유형 매개 변수를 메소드 호출로 명시 적으로 전달해야합니다. 이런 식으로 컴파일러는 유형 매개 변수를 유추하려고 시도하지 않으며 올바른 결과를 얻을 수 있습니다.
코드 사본은 다음과 같습니다. return x? 컬렉션. <integer> emptylist () : null;
이런 일이 자주 발생하는 또 다른 곳은 메소드 호출입니다. 메소드가 목록 <string> 매개 변수를 가져 와서 해당 매개 변수의 전달 된 emptylist ()를 호출 해야하는 경우이 구문도 필요합니다.
컬렉션 밖에서
다음은 컬렉션이 아니라 일반적인 방식으로 제네릭을 사용하는 일반 유형의 세 가지 예입니다. 세 가지 예는 모두 표준 Java 라이브러리에서 나옵니다.
다음과 같이 코드를 복사하십시오 : 클래스 <t>
클래스는 클래스 유형에서 매개 변수화됩니다. 이를 통해 유형 주조없이 신규식을 구성 할 수 있습니다.
코드를 다음과 같이 복사하십시오. 비교 가능 <t>
비교할 수있는 것은 실제 비교 유형에 따라 매개 변수입니다. 이것은 () 호출 할 때 더 강력한 타이핑을 제공합니다. 예를 들어, 문자열은 비슷한 <string>를 구현합니다. 문자열 이외의 다른 것에서 compareto ()를 호출하면 컴파일 시간에 실패합니다.
코드를 다음과 같이 복사하십시오
열거는 열거 유형에 의해 매개 변수화됩니다. 색상이라는 열거 유형은 enum <coll>을 확장합니다. getDeclaringClass () 메소드는 열거 형 유형 클래스 객체를 반환합니다.이 예에서는 색상 객체입니다. 이름이없는 클래스를 반환 할 수있는 getClass ()와 다릅니다.
와일드 카드
제네릭의 가장 복잡한 부분은 와일드 카드 캐릭터에 대한 이해입니다. 우리는 세 가지 유형의 와일드 카드와 그 용도에 대해 논의 할 것입니다.
먼저 어레이가 어떻게 작동하는지 이해합시다. 정수 []에서 숫자 []에 값을 할당 할 수 있습니다. 플로트를 숫자 []에 쓰려고하면 컴파일 될 수 있지만 런타임에 실패하고 ArrayStoreException이 나타납니다.
정수 [] ia = 새로운 정수 [5]; 숫자 [] na = ia; na [0] = 0.5; // 컴파일하지만 런타임에 실패합니다
예제를 일반으로 직접 변환하려고하면 할당이 허용되지 않으므로 컴파일 시간에 실패합니다.
목록 <integer> ilist = new arraylist <integer> (); list <number> nlist = ilist; // 허용되지 않음 .add (0.5);
제네릭을 사용하는 경우 컴파일 할 때 코드가 나타나지 않는 한 런타임 클래스 캐스트 렉싱이 발생하지 않습니다.
상한 와일드 카드
우리가 원하는 것은 배열과는 다른 정확한 요소 유형의 목록입니다.
List <number>는 요소 유형이 특정 유형 번호 인 목록입니다.
List <? 확장 번호>는 정확한 요소 유형의 목록입니다. 숫자 또는 하위 유형입니다.
상한
초기 예제를 업데이트하고 List <? 숫자>를 연장하면 이제 과제가 성공할 것입니다.
목록 <integer> ilist = new arraylist <integer> (); list <? 숫자> nlist = ilist; 숫자 n = nlist.get (0); nlist.add (0.5); // 허용되지 않습니다
목록의 정확한 요소 유형 (플로트, 정수 또는 번호)에 관계없이 번호로 할당 할 수 있기 때문에 목록에서 번호를 얻을 수 있습니다.
여전히 부동 소수점 유형을 목록에 삽입 할 수 없습니다. 우리는 이것이 안전하다는 것을 증명할 수 없기 때문에 컴파일 시간에 실패합니다. 부동 소수점 유형을 목록에 추가하려면 ILIST의 초기 유형 안전성이 깨질 것입니다. 정수를 저장합니다.
와일드 카드는 어레이보다 더 표현력이 뛰어납니다.
왜 와일드 카드를 사용합니다
다음 예에서 와일드 카드는 API 사용자의 유형 정보를 숨기는 데 사용됩니다. 내부적으로 세트는 CustomerImpl로 저장됩니다. API 사용자는 고객을 읽을 수있는 세트를 받고 있다는 것을 알고 있습니다.
세트 <customerimpl>에서 <sulfort>를 설정하도록 값을 할당하는 것은 불가능하기 때문에 와일드 카드가 필요합니다.
공개 클래스 CustomerFactory {private set <customerimpl> _customers; public set <? 확장 고객> getCustomers () {return _customers;}}와일드 카드 및 공분산 반환
와일드 카드 문자의 또 다른 일반적인 사용법은 공분산 반환과 함께 사용하는 것입니다. 과제와 동일한 규칙을 공분산 수익에 적용 할 수 있습니다. 다시 작성된 메소드에서보다 구체적인 일반 유형을 반환하려면 선언 된 방법은 와일드 카드를 사용해야합니다.
공개 인터페이스 번호 창출자 {public list <? 확장 번호> generate ();} public class fibonaccigenerator 확장 숫자 성기기 {public list <integer> generate () {...}}배열을 사용하려면 인터페이스가 숫자를 반환 할 수 있고 구현은 정수를 반환 할 수 있습니다 [].
하한
우리가 말하는 것은 주로 상한 와일드 카드에 관한 것입니다. 하한 와일드 카드도 있습니다. List <? Super Number>는 정확한 "요소 유형"이 알려지지 않은 목록이지만 Mnumber 또는 슈퍼 타입 일 수 있습니다. 따라서 목록 <번호> 또는 목록 <botort> 일 수 있습니다.
하단 제한 와일드 카드는 상단 제한 와일드 카드보다 훨씬 덜 일반적이지만 필요할 때 필요합니다.
하한 및 상한
List <? 숫자> readlist = new ArrayList <integer> (); 번호 n = readList.get (0); list <? 수퍼 번호> writeList = New ArrayList <Object> (); writeList.Add (New Integer (5));
첫 번째는 읽을 수있는 숫자 목록입니다.
두 번째는 쓸 수있는 숫자 목록입니다.
무한한 와일드 카드
마지막으로, 목록 <?> 목록의 내용은 모든 유형 일 수 있으며 List <와 거의 동일합니다. 객체를 확장합니다. 객체는 언제든지 읽을 수 있지만 내용은 목록에 기록 할 수 없습니다.
공공 API의 와일드 카드
요컨대, 앞에서 언급 한 바와 같이, 와일드 카드는 발신자의 구현 세부 정보를 숨기는 데 매우 중요하지만, 하한 와일드 카드가 읽기 전용 액세스를 제공하는 것처럼 보이더라도 제거 (int 위치)와 같은 비 게널 메소드로 인해 해당되지 않습니다. 진정으로 변경되지 않은 컬렉션을 원한다면 Zava.util.collection에서 unmodifiablelist ()를 사용할 수 있습니다.
API를 쓸 때 와일드 카드를 기억하십시오. 일반적으로 일반 유형을 통과 할 때 와일드 카드를 사용해야합니다. 더 많은 발신자가 API에 액세스 할 수 있습니다.
목록을 수신하여 <? List <bumer> 대신 숫자>를 확장하면 여러 가지 유형의 목록에서 다음 방법을 호출 할 수 있습니다.
코드 사본은 다음과 같습니다. void removenegatives (list <? extends number> list);
일반적인 유형을 구성하십시오
이제 우리는 우리 자신의 일반 유형을 구성하는 것에 대해 논의 할 것입니다. 제네릭을 사용하여 유형 안전을 향상시킬 수있는 몇 가지 예를 보여 주며 제네릭 유형을 구현할 때 몇 가지 일반적인 문제에 대해 논의 할 것입니다.
수집과 같은 기능
일반 클래스의 첫 번째 예는 컬렉션 스타일의 예입니다. 쌍에는 두 가지 유형 매개 변수가 있으며 필드는 유형의 인스턴스입니다.
공개 최종 클래스 쌍 <a, b> {public final a 첫 번째; 공개 결승 B 초; 공개 쌍 (첫 번째, b 초) {this.first = first; this.second = second;}}따라서 두 유형의 각 조합에 대해 전용 클래스를 작성하지 않고 메소드에서 두 항목을 반환 할 수 있습니다. 또 다른 방법은 유형이 안전하지 않거나 어수선한 객체 []를 반환하는 것입니다.
다음 사용으로, 우리는이 방법에서 파일과 부울을 반환합니다. 이 방법의 클라이언트는 유형 캐스팅없이 직접 필드를 사용할 수 있습니다.
public pair <file, boolean> getFileAndWritestatus (문자열 경로) {// 파일 만들기 및 statustr성 새 페어 <파일, boolean> (파일, 상태);} pair <file, boolean> result = getFileAndWritestatus ( "..."); file f = result.first; 부울 writeable = result.second;컬렉션 밖에서
다음 예에서는 제네릭이 추가 컴파일 타임 보안에 사용됩니다. DBFactory 클래스를 생성 된 피어 유형으로 매개 변수화함으로써 실제로 공장 서브 클래스가 피어의 특정 하위 유형을 반환하도록 강요합니다.
공개 초록 클래스 dbfactory <t extends dbpeer> {보호 된 초록 t createemptypeer (); public list <t> get (string chanstraint) {list <t> peers = new arraylist <t> (); // Database MagicEturn Peers;}}DBFactory <customer>를 구현함으로써 CustomerFactory는 CreateEmptyPeer ()에서 고객을 반환해야합니다.
공개 클래스 CustomerFactory 확장 DBFactory <customer> {공개 고객 CreateEmptyPeer () {return new Customer ();}}일반적인 방법
매개 변수와 매개 변수 사이의 일반적인 유형에 대한 제약 조건을 부과하려는 경우 일반적인 방법을 사용할 수 있습니다.
예를 들어, 서면으로 작성된 반전 함수가 위치 적으로 역전되면 일반적인 방법이 필요하지 않을 수 있습니다. 그러나 반전이 새 목록을 반환하려는 경우 새 목록의 요소 유형이 들어오는 목록의 유형과 동일하기를 원할 수 있습니다. 이 경우 일반적인 방법이 필요합니다.
다음과 같이 코드를 복사하십시오.
콘크리트
일반 클래스를 구현할 때는 배열 t []를 구성 할 수 있습니다. 제네릭은 삭제에 의해 구현되므로 허용되지 않습니다.
대상을 t []로 캐스팅 할 수 있습니다. 그러나 이것은 안전하지 않습니다.
콘크리트 솔루션
일반 튜토리얼의 협약에 따르면 솔루션은 "유형 토큰"을 사용합니다. 생성자에 클래스 <t> 매개 변수를 추가하면 클라이언트가 클래스 유형 매개 변수에 올바른 클래스 객체를 제공하도록 강요 할 수 있습니다.
공개 클래스 Arrayexample <T> {private class <T> Clazz; public arrayexample (class <t> clazz) {this.clazz = clazz;} public t [] getArray (int size) {return (t []) array.newinstance (Clazz, size);}}Arrayexample <string>을 구성하려면 Clist.class 유형이 클래스 <string>이므로 클라이언트는 String.class를 생성자에게 전달해야합니다.
클래스 객체가 있으면 올바른 요소 유형의 그룹을 구성 할 수 있습니다.
이 기사가 모든 사람의 Java 프로그래밍에 도움이되기를 바랍니다.