Java 제네릭을 이해하는 가장 쉬운 방법은이를 Java 유형 캐스팅에서 일부 작업을 절약 할 수있는 편리한 구문으로 간주하는 것입니다.
List <plect> box = ...; Apple Apple = Box.get (0);
위의 코드 자체는 명확하게 표현되었습니다. Box는 Apple Objects가있는 목록입니다. Get 메소드는 Apple Object 인스턴스를 반환 하며이 프로세스에는 유형 변환이 필요하지 않습니다. 제네릭이 없으며 위의 코드는 다음과 같이 작성해야합니다.
목록 상자 = ...; Apple Apple = (Apple) Box.get (0);
제네릭의 주요 이점은 컴파일러가 매개 변수의 유형 정보를 유지하고 유형 확인을 수행하며 유형 변환 작업을 수행 할 수 있도록하는 것이 분명합니다. 컴파일러는 이러한 유형 변환이 절대적으로 올바른지 확인합니다. 프로그래머에 의존하여 객체 유형을 기억하고 유형 변환을 수행하는 것과 비교할 때 - 프로그램이 실행될 때 고장이 발생하여 디버깅하고 해결하기가 어렵습니다. 컴파일러는 프로그래머가 컴파일 시간에 많은 수의 유형 검사를 강제하고 오류를 찾도록 도와줍니다.
제네릭의 구성
제네릭의 구성은 유형 변수의 개념으로 이어집니다. Java 언어 사양에 따르면, 유형 변수는 다음과 같은 상황에서 발생하는 무제한 글리프의 유형입니다.
일반 클래스 선언 일반 인터페이스 선언 일반 방법 선언 일반 생성자 선언
일반 클래스 및 인터페이스
클래스 또는 인터페이스에 하나 이상의 유형 변수가있는 경우 일반적인 것입니다. 유형 변수는 각도 브래킷으로 정의되며 클래스 또는 인터페이스 이름에 배치됩니다.
공개 인터페이스 목록 <T> 확장 컬렉션 <T> {...}간단히 말해서, 유형 변수의 역할은 매개 변수와 같으며, 이는 유형 검사를 위해 컴파일러에 정보를 제공하는 매개 변수와 같습니다.
전체 컬렉션 프레임 워크와 같은 Java 클래스 라이브러리의 많은 클래스가 일반적인 형태로 수정되었습니다. 예를 들어, 위의 첫 번째 코드에서 사용한 목록 인터페이스는 일반 클래스입니다. 이 코드에서 Box는 목록 <ple> 객체이며, 이는 Apple 유형 변수와 함께 목록 인터페이스의 클래스 구현 인스턴스입니다. 컴파일러는이 유형 변수 매개 변수를 사용하여 호출 될 때 Get 메소드를 자동으로 변환하고 Apple 객체를 반환합니다.
실제로이 새로 떠오르는 일반 태그 또는이 목록 인터페이스의 Get 메소드는 다음과 같습니다.
t get (int index);
Get 메소드는 실제로 Type T의 객체를 반환합니다. 이는 List <T> 선언의 유형 변수입니다.
일반적인 방법 및 생성자
매우 유사하게, 하나 이상의 유형 변수가 방법과 생성자에 선언되면 일반일 수도 있습니다.
Public STATIC <T> T GETFIRST (List <T> 목록)
이 방법은 목록 <t> 매개 변수를 수락하고 T 형의 객체를 반환합니다. Java 클래스 라이브러리에서 제공된 일반 클래스를 사용하거나 자신의 일반 클래스를 사용할 수 있습니다. 유형-안전 쓰기 데이터 ... 다음 코드는 예입니다. 목록 <string> 인스턴스를 작성한 다음 일부 데이터를로드합니다.
list <string> str = new arraylist <string> (); str.add ( "hello"); str.add ( "세계.");
List <string>에 다른 객체를로드하려고하면 컴파일러가 오류가 발생합니다.
str.add (1);
유형-안전한 읽기 데이터 ...
목록 <string> 객체를 사용하는 경우 항상 문자열 객체를 얻습니다.
문자열 mystring = str.get (0);
TRAVERSAL : ITERATOR <T>와 같은 클래스 라이브러리의 많은 클래스는 기능이 향상되고 일반화됩니다. 목록 <t> 인터페이스의 iterator () 메소드는 이제 반복자 <t>를 반환합니다. T Next () 메소드에 의해 반환 된 객체는 유형으로 변환 할 필요가 없으며 올바른 유형을 직접 얻을 수 있습니다.
for (iterator <string> iter = str.iterator (); iter.hasnext ();) {String s = iter.next (); system.out.print (s);}Foreach를 사용하면 "각각의 경우"구문도 제네릭의 혜택을받습니다. 이전 코드는 다음과 같이 작성할 수 있습니다.
for (string s : str) {system.out.print (s);}이것은 읽고 유지하기가 쉽습니다.
자동 캡슐화 (자가 옥싱) 및 자동 포장 (오토 박스). Java Generics를 사용할 때는 다음 코드와 마찬가지로 Autoboxing/Autounboxing의 두 가지 기능이 자동으로 사용됩니다.
List <integer> ints = new ArrayList <integer> (); ints.add (0); ints.add (1); int sum = 0; for (int i : ints) {sum += i; }그러나 이해해야 할 한 가지는 포장 및 포장 풀기가 성능 손실을 가져오고 모든 범용을주의해서 사용해야한다는 것입니다.
제네릭은 Java SE 1.5의 새로운 기능입니다. 제네릭의 본질은 매개 변수화 된 유형입니다. 즉, 작동하는 데이터 유형은 매개 변수로 지정됩니다. 이 매개 변수 유형은 클래스, 인터페이스 및 메소드를 작성하는 데 사용할 수 있으며 각각 일반 클래스, 일반 인터페이스 및 일반 메소드라고합니다.
Java 언어로 제네릭을 소개하는 장점은 안전하고 단순하다는 것입니다.
제네릭이없는 Java SE 1.5 이전에는 유형 객체를 참조하여 매개 변수의 "임의의"이 달성되었습니다. "임의의"의 단점은 명시적인 캐스트 유형 변환이 필요하다는 것이 었고이 변환은 개발자가 실제 매개 변수 유형을 예측해야했습니다. 캐스트 유형 변환 오류의 경우 컴파일러가 오류가 발생하지 않을 수 있으며 실행 중에만 예외가 발생합니다. 이는 보안 위험입니다.
제네릭의 장점은 컴파일 할 때 유형 안전을 확인하고 모든 캐스트가 자동적이고 암시되어 코드의 재사용 속도를 향상 시킨다는 것입니다.
제네릭 사용에는 몇 가지 규칙과 제한 사항이 있습니다.
1. 일반 유형의 유형 매개 변수는 간단한 유형이 아닌 클래스 유형 (사용자 정의 클래스 포함) 일 수 있습니다.
2. 동일한 일반 유형은 여러 버전에 해당 할 수 있으며 (매개 변수 유형이 불확실하기 때문에) 일반 클래스의 다른 버전의 인스턴스는 호환되지 않습니다.
3. 제네릭에 대한 여러 유형 매개 변수가있을 수 있습니다.
4. 일반 매개 변수 유형은 예를 들어 확장 진술을 사용할 수 있습니다. 습관적으로 "경계 유형"이됩니다.
5. 일반 유형의 매개 변수 유형은 와일드 카드 유형 일 수도 있습니다. 예를 들어 Class Classtype = class.forname (java.lang.string);
제네릭에는 많은 콘텐츠가 포함 된 인터페이스, 방법 등이 있으며 능숙하게 이해하고 마스터하고 적용하려면 약간의 노력이 필요합니다. 다음은 제네릭에 대해 배웠을 때 (내가 본 인상을 기반으로 작성) 동일한 기능을 실현할 수있는 두 가지 예입니다. 하나는 제네릭을 사용하고 다른 하나는 그렇지 않습니다. 비교를 통해 제네릭의 적용을 빠르게 배울 수 있습니다. 이것을 배우고 기본적으로 제네릭 내용의 70%를 배우십시오.
예 1 : 제네릭이 사용됩니다
공개 계급 신사 {private t ob; // 일반 멤버 정의 변수 public gen (t ob) {this.ob = ob; } public t getob () {return ob; } public void setob (t ob) {this.ob = ob; } public void showtyep () {system.out.println ( "실제 유형은" + ob.getClass (). getName ()); }} public class gendemo {public static void main (String [] args) {// 일반 클래스 Gen intob = new Geninteger (88)의 정수 버전을 정의합니다. intob.showtyep (); int i = intob.getob (); System.out.println ( "value =" + i); System.out.println("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------예 2 : 제네릭이 사용되지 않습니다
공개 클래스 gen2 {개인 객체 OB; // 일반 유형 멤버 정의 공개 gen2 (object ob) {this.ob = ob; } public object getOb () {return ob; } public void setob (Object OB) {this.OB = OB; } public void showtyep () {system.out.println ( "실제 유형은" + ob.getClass (). getName ()); }} public class gendemo2 {public static void main (string [] args) {// 클래스 Gen2 Gen2 Gen2 intob = new Gen2 (88)); intob.showtyep (); int i = (integer) intob.getob (); system.out.println ( "values =" + i);System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ strob.getob (); system.out.println ( "value =" + s)};실행 결과 :
두 예제에서 데모를 실행 한 결과는 동일하며 콘솔 출력은 다음과 같습니다.
실제 t 유형은 다음과 같습니다.
java.lang.integer
값 = 88
------------------------------------
실제 t 유형은 java.lang.string입니다
가치 = 안녕하세요!
Exit 코드 0으로 프로세스가 완료되었습니다
이것을 이해하면 기본 일반 응용 프로그램 및 코드 읽기가있을 때 미래에는 문제가되지 않을 것입니다.
위의 것은 Java Generics의 예제입니다. 자바 제네릭을 배우는 친구는 그것을 참조 할 수 있습니다.