English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
在本教程中,我们将通过示例了解Java泛型,如何创建泛型类和方法及其优势。
在Java中,제너릭有助于创建可与不同类型的对象(数据)一起使用的类,接口和方法。因此,允许我们重用我们的代码。
注意:제너릭泛型不适用于基本类型(int,float,char等)。
要了解在Java中如何使用제너릭,我们可以使用ArrayListJava集合框架的类。
ArrayList类是泛型类的一个示例。我们可以使用ArrayList来存储任何类型的数据。例如
import java.util.ArrayList; class Main { public static void main(String[] args) { //创建一个数组列表来存储Integer 数据 ArrayList<Integer> list1 = new ArrayList<>(); list1.add(4); list1.add(5); System.out.println("ArrayList of Integer: ") + list1); //创建数组列表来存储String 数据 ArrayList<String> list2 = new ArrayList<>(); list2.add("Four"); list2.add("Five"); System.out.println("ArrayList of String: ") + list2); //Double 데이터를 저장하기 위한 배열 목록을 생성했습니다. ArrayList<Double> list3 = new ArrayList<>(); list3.add(4.5); list3.add(6.5); System.out.println("ArrayList of Double: ", + list3); } }
출력 결과
ArrayList of Integer: [4, 5] ArrayList of String: [Four, Five] ArrayList of Double: [4.5, 6.5]
위 예제에서 Integer, String, Double 타입의 요소를 저장하기 위해 같은 ArrayList 클래스를 사용했습니다. 왜냐하면Java 제너릭, 이는 가능합니다.
이 줄을 주목하세요,
ArrayList<Integer> list1 = new ArrayList<>();
귀여운 괄호 <>에서 Integer를 사용했습니다. 괄호 <>는 제너릭에서타입 파라미터.
파라미터 type는 제너릭 클래스나 메서드가 적용할 수 있는 객체(데이터)의 타입을 지정합니다.
Java에서 제너릭의 작동 방식을 알았으므로, 자신의 제너릭 클래스를 어떻게 생성할지 보겠습니다.
class Main { public static void main(String[] args) { //정수 데이터로 제너릭 클래스를 초기화했습니다. GenericsClass<Integer> intObj = new GenericsClass<>(5); System.out.println("제너릭 클래스는 다음과 같이 반환합니다:", + intObj.getData()); //문자 데이터로 제너릭 클래스를 초기화했습니다. GenericsClass<String> stringObj = new GenericsClass<>("Java Programming"); System.out.println("제너릭 클래스는 다음과 같이 반환합니다:", + stringObj.getData()); } } class GenericsClass<T> { //T 타입 변수 private T data; public GenericsClass(T data) { this.data = data; } //T 타입 변수를 반환하는 메서드 public T getData() { return this.data; } }
출력 결과
제너릭 클래스는 다음과 같이 반환합니다: 5 제너릭 클래스는 다음과 같이 반환합니다: Java Programing
위 예제에서 GenericsClass라는 제너릭 클래스를 생성했습니다. 이 클래스는 어떤 타입의 데이터를 처리할 수 있습니다.
class GenericsClass<T> {...}
이곳에서 T는타입 파라미터Main 클래스 내부에서 intObj와 stringObj라는 GenericsClass 객체를 생성했습니다.
intObj을 생성할 때, 타입 매개변수 T는 Integer으로 대체됩니다. 이는 intObj이 GenericsClass를 통해 정수 데이터를 처리한다는 의미입니다.
stringObj을 생성할 때, 타입 매개변수 T는 String으로 대체됩니다. 이는 stringObj이 GenericsClass를 통해 문자 데이터를 처리한다는 의미입니다.
전용 클래스와 유사하게, Java에서 전용 메서드를 생성할 수도 있습니다.
class Main { public static void main(String[] args) { //Integer 데이터로 클래스를 초기화합니다 DemoClass demo = new DemoClass(); demo.<String>genericMethod("Java Programming"); } } class DemoClass { //전용 메서드 public <T> void genericsMethod(T data) { System.out.println("이는 전용 메서드입니다."); System.out.println("전달된 메서드 데이터는 " + data); } }
출력 결과
이는 전용 메서드입니다. 메서드에 전달된 데이터는: Java Programming
위 예제에서는 DemoClass 내부에 정의된 전용 메서드 genericsMethod를 생성했습니다.
public <T> void genericMethod(T data) {...}
이곳에서는 타입 매개변수 <T>를 수정자(public)와 반환 타입(void) 사이에 삽입합니다.
실제 타입 <String>을 메서드 이름 앞의 괄호에 두어 전용 메서드를 호출할 수 있습니다.
demo.<String>genericMethod("Java Programming");
주의대부분의 경우, 전용 매개변수를 생략할 수 있습니다. 이는 컴파일러가 메서드에 전달된 값으로 타입 매개변수를 일치시킬 수 있기 때문입니다. 예를 들어,
demo.genericsMethod("Java Programming");
보통,type 매개변수모든 데이터 타입을 받을 수 있습니다(원시 타입 제외). 하지만 특정 타입(예를 들어 숫자 타입의 데이터를 받는 것)에 대해 전용 타입을 사용하고 싶다면 제한된 타입을 사용할 수 있습니다.
extends 키워드를 사용합니다. 예를 들어,
<T extends A>
이는 T가 A의 서브 타입의 데이터만 받을 수 있음을 의미합니다.
class GenericsClass<T extends Number> { public void display() {}} System.out.println("This is a bounded type generics class."); } } class Main { public static void main(String[] args) { //GenericsClass 객체 생성 GenericsClass<String> obj = new GenericsClass<>(); } }
위의 예제에서는 GenericsClass를 생성했다.제한된 타입의 제너릭 클래스. 여기서는 표현식에 주의해야 한다.
<T extends Number>
이는 T가 Number의 서브 타입 데이터 타입( Integer, Double 등)만 사용할 수 있다는 의미다.
그러나, 우리는 String으로 제너릭 클래스의 객체를 생성했기 때문에, 프로그램을 실행할 때 다음과 같은 오류를 받게 된다.
GenericsClass<String> obj = new GenericsClass<>(); ^ reason: inference variable T has incompatible bounds equality constraints: String lower bounds: Number where T is a type-변수: T extends Number declared in class GenericsClass
제너릭다른 타입 데이터에 적용할 수 있는 코드를 작성할 수 있게 한다. 예를 들어,
public <T> void genericsMethod(T data) {...}
여기서는 제너릭 메서드를 생성했다. 이 메서드는 정수 데이터, 문자열 데이터 등에 대해 작업할 수 있다.
제너릭type 매개변수제너릭 코드에서 사용하는 데이터 타입에 대한 정보를 제공한다.
따라서, 컴파일 시에 오류를 인식할 수 있어, 실행 시 오류보다 더 쉽게 수정할 수 있다. 예를 들어,
//제너릭을 사용하지 않음 NormalClass list = new NormalClass(); //NormalClass의 메서드 호출 list.display("String");
위의 코드에서는 일반 클래스가 있다. 이 클래스의 display() 메서드를 호출하기 위해 문자열 데이터를 전달하여 호출한다.
여기서 컴파일러는 매개변수에 전달된 값이 올바른지 모른다. 그러나, 제너릭 클래스를 사용할 때 어떻게 될지 보자.
//제너릭 사용 GenericsClass<Integer> list = new GenericsClass<>(); //GenericsClass의 메서드 호출 list2.display("String"); 위의 코드에서는 제너릭 클래스가 있습니다. 여기서 타입 파라미터는 이 클래스가 Integer 데이터를 처리하고 있다는 것을 의미합니다. 따라서 문자 데이터가 매개변수로 전달될 때, 컴파일러는 오류를 생성합니다.
콜렉션 프레임워크는 Java의 제너릭 개념을 사용합니다. 예를 들어,
// String 타입 ArrayList 생성 ArrayList<String> list1 = new ArrayList<>(); // Integer 타입 ArrayList 생성 ArrayList<Integer> list2 = new ArrayList<>();
위의 예제에서는 다른 타입의 데이터를 처리하는 데 같은 ArrayList 클래스를 사용했습니다.
ArrayList과 비슷하게, 다른 컬렉션(LinkedList, Queue, Maps 등)도 Java의 제너릭입니다.