728x90
제네릭스
- Generics는 파라미터화된 타입을 의미한다. 즉, 메소드에 타입(Integer, String, 유저 정의 타입)을 파라미터로 하여 메서드, 클래스, 인터페이스에 전달할 수 있게 하는 기능이다. 이를 이용하여 다양한 데이터 타입을 가지고 동작하는 클래스를 만들 수 있다. 클래스, 인터페이스 또는 메서드와 같은 엔터티가 파라미터화된 타입에 기반에 수행된다면 이를 제네릭스 엔터티라고 한다.
왜 제네릭스를 쓰는가?
- Object 클래스는 모든 다른 클래스들의 조상 클래스이다. Object 타입 참조 변수는 어떤 객체든 참조할 수 있다. 이런 특징은 타입 안정성을 해친다. 제네릭스를 사용하면 타입 안정성 효과가 있다.
- JAVA의 Generics는 C++의 template과 비슷하다. HashSet,ArrayList, HashMap 등이 제네릭스를 잘 활용하고 있는 예이다. 제네릭 타입에 두 가지 접근법이 있는데 이 둘은 근본적으로 상당히 다른 점을 갖고 있다.
자바 제레릭스의 타입
- Generic Method : 일반 메서드처럼 파라미터와 리턴값을 갖지만, actual type에 의해 인용되는 type parameter를 가지고 있다. 이는 제네릭 메서드가 더 범용적으로 사용되게 한다. 컴파일러는 타입 안정성을 고려하는데 이를 통해 프로그래머가 type casting 없이 쉽게 코드를 짤 수 있게 한다.
- Generic Classes : 일반 클래스와의 차이점은 타입 파라미터 섹션을 가진다는 것 뿐이다. 하나 이상의 파라미터 타입이 있을 수 있다. 이런 클래스들을 parameterized classes 혹은 parameterized types라고 한다.
제네릭 클래스
public class Ex011 {
public static void main(String[] args) {
// Integer 타입 인스턴스
Test<Integer> iObj = new Test<Integer>(15);
System.out.println(iObj.getObject());
// String 타입 인스턴스
Test<String> sObj = new Test<String>("Str");
System.out.println(sObj.getObject());
}
}
class Test<T> {
// T 타입 오브젝트 선언
T obj;
// 생성자
Test(T obj) {
this.obj = obj;
}
public T getObject() {
return this.obj;
}
}
/*
15
Str
*/
- 여러 개의 타입 파라미터를 넣을 수도 있다
제네릭 메서드
public class Ex013 {
public static void main(String[] args)
{
genericDisplay(11);
genericDisplay("this is string");
genericDisplay(3.14);
}
static <T> void genericDisplay(T element)
{
System.out.println(element.getClass().getName() + " = " + element);
}
}
/*
java.lang.Integer = 11
java.lang.String = this is string
java.lang.Double = 3.14
*/
- 제네릭스는 기본형 타입과는 쓸 수 없고 참조형 타입하고만 어울릴 수 있다.
- 다만 기본형 타입 배열 같은 경우에는 괜찮다. 배열은 참조형이기 때문이다.
ArrayList<int[]> arr = new ArrayList<>(); // OK.
Test<int> obj = new Test<int>(20); // OK.
- 인자 타입이 다른 제네릭 타입을 쓰는 경우
package ch1;
public class Ex011 {
public static void main(String[] args) {
Test<Integer> iObj = new Test<Integer>(5);
System.out.println(iObj.getObject());
Test<String> sObj = new Test<String>("String is a string");
System.out.println(sObj.getObject());
iObj = sObj; // Type mismatch: cannot convert from Test<String>
}
}
class Test<T> {
// T 타입 오브젝트 선언
T obj;
// 생성자
Test(T obj) {
this.obj = obj;
}
public T getObject() {
return this.obj;
}
}
→ iObj, sObj 모두 Test 타입에 속하지만, 두 개는 각각 파라미터 타입이 다르기 때문에 다른 타입을 참조하고 있는 것이다. 제네릭스는 이런 타입 안정성 기능이 포함되어 있다.
네이밍 컨벤션
- T - Type
- E - Element
- K - Key
- N - Number
- V - Value
- 제네릭스의 장점
- 코드 재사용
- 타입 안정성 : 컴파일러 단계에서 에러가 나 미리 알 수 있음
ArrayList al = new ArrayList(); // 타입 특정 X
al.add("Sachin");
al.add("Rahul");
al.add(10); // 컴파일러가 허용
String s1 = (String)al.get(0);
String s2 = (String)al.get(1);
String s3 = (String)al.get(2); // 런타임 에러 발생
/////////////////////////////////////////////////
ArrayList <String> al = new ArrayList<String> ();
al.add("Sachin");
al.add("Rahul");
al.add(10); // 컴파일 에러 발생하여 미리 방지 가능
String s1 = (String)al.get(0);
String s2 = (String)al.get(1);
String s3 = (String)al.get(2);
////////////////////////////////////////////////
ArrayList<String> al = new ArrayList<String>();
al.add("Sachin");
al.add("Rahul");
String s1 = al.get(0); // 굳이 타입 캐스팅 하지 않아도 됨
String s2 = al.get(1);
- 코드 재사용성
→ 비교 메서드의 재사용 예시
package ch1;
public class Ex015
{
public static void main(String[] args)
{
Integer[] a = { 100, 22, 58, 41, 6, 50 };
Character[] c = { 'v', 'g', 'a', 'c', 'x', 'd', 't' };
String[] s = { "Virat", "Rohit", "Abhinay", "Chandu","Sam", "Bharat", "Kalam" };
System.out.print("Sorted Integer array : ");
sort_generics(a);
System.out.print("Sorted Character array : ");
sort_generics(c);
System.out.print("Sorted String array : ");
sort_generics(s);
}
// T가 Comparable을 구현한 타입이어야 함
public static <T extends Comparable<T> > void sort_generics(T[] a)
{
for(int i = 0; i < a.length -1; i++)
{
for(int j = 0; j < a.length - i - 1; j++)
{
// Comparable 인터페이스는 compareTo 메서드를 가지고 있음
// <T extends Comparable<T> > 가 없다면 컴파일 에러 발생.
if(a[j].compareTo(a[j+1]) > 0)
{
swap(j, j+1, a);
}
}
}
for(T i : a)
{
System.out.print(i + ", ");
}
System.out.println();
}
public static <T> void swap(int i, int j, T[] a)
{
T t = a[i];
a[i] = a[j];
a[j] = t;
}
}
와일드카드<?>
TODO
728x90
'Computer Science > Programming' 카테고리의 다른 글
(작업중)Java의 Servlets과 Servlet Containers (1) | 2024.05.13 |
---|---|
Quartz API에 대해서 (1) | 2023.11.28 |
MyBatis의 fluchCache옵션에 대하여 (0) | 2023.04.11 |