Java공부(코딩)

코딩초보의 자바(Java)공부 23일차 { 제네릭 - Generic1 }

동곤일상 2025. 1. 6. 15:30
반응형
오늘은 제네릭메서드에
관한 공부를 해볼까합니다
중요한것이니 잘
보고 배워가시는게 있으면 좋겠습니다!

제네릭이 필요한 이유

public class IntegerBox {
	private Integer value;
	
	public Integer getValue() {
		return value;
	}
	
	public void setValue(Integer value) {
		this.value = value;
	}

}
public class StringBox {
	private String value;
	
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}

}

 

메인코드

public class BoxMain {
	public static void main(String[] args) {
		IntegerBox iBox = new IntegerBox();
		StringBox sBox = new StringBox();
		
		
		iBox.setValue(12); //오토박싱에 의해 int --> Integer
		Integer value = iBox.getValue();
		System.out.println(value);
		
//		Integer에 대한 상기 !
//		String a = "13";
//		System.out.println("StringA : "+a+" type:"+a.getClass());
//		Integer b = Integer.valueOf(a);
//		System.out.println("IntegerB : "+b+" type : "+b.getClass());
//		int c = b.intValue();
//		System.out.println("intC : "+c+" type : int"); 
		
		sBox.setValue("하하하");
		String value2 = sBox.getValue();
		System.out.println(value2);
		//만약 double ,Boolean 객체 등을 담을 박스가 필요하다면??
	}

}

제네릭 적용

제네릭을 사용하면

타입안정성 , 코드 재사용 등의

이점을 얻을 수 있어요..!

 

public class GenericBox<T> {
	
	private T value;
	
	public T getValue() {
		return value;
	}
	
	public void setValue(T value) {
		this.value = value;
	}

}

<>를 사용한 클래스를 제네릭 클래스라 한다.

기호(<>) 보통 다이아몬드라 한다.

제네릭 클래스를 사용할 때는 `Integer` , `String` 같은 타입을 미리 결정하지 않는다.

대신에 클래스명 오른쪽에 `<T>` 같이 선언하면 제네릭 클래스가 된다. 여기서 `T` **타입 매개변수** 한다.

타입 매개변수는 이후에 `Integer` , `String`으로 변할 있다.

그리고 클래스 내부에 `T` 타입이 필요한 곳에 `T value` 같이 타입 매개변수를 적어두면 된다.

 

사용 예시

public class GenericMain {
	public static void main(String[] args) {
		GenericBox<Integer> iBox = new GenericBox<Integer>();
		GenericBox<String> sBox = new GenericBox<String>();
		
		iBox.setValue(14);
		sBox.setValue("동곤자바");
		
		Integer value = iBox.getValue();
		String value2 = sBox.getValue();
		
		System.out.println("IntegerBox : "+value);
		System.out.println("StringBox : "+value2);
		

	}

}

IntegerBox : 14

StringBox : 동곤자바

 


타입추론

GenericBox<Integer> iBox = new GenericBox<Integer>();

이런 식으로 제네릭클래스 인스턴스를 생성했다

하지만

뒤에 <>안에 타입은 생략해도 된다.

자바에서 앞에 클래스뒤에 넣은 타입을보고

추론을 해서 타입을 맞추기 때문!!!

GenericBox<Integer> iBox = new GenericBox<>();

이런식으로 작성해도 무관!

 


제네릭 용어와 관례

제네릭의 핵심은 **사용할 타입을 미리 결정하지 않는다는 **

굳이 비교하자면 메서드의 인자와 매개변수같은 느낌이라고

생각하시면 편할 겁니다.

**메서드에 필요한 값을 인자를 통해 매개변수로 전달해서 결정**
```java
void method2(String param) {
println(param);
}

 

메서드의 매개변수는 사용할 값에 대한 결정을 나중으로

미루는 **이고, **제네릭의 타입 매개변수는 사용할 타입에 대한 결정을 나중으로 미루는

 

**용어 정리**

**제네릭(Generic) 단어**

제네릭이라는 단어는 일반적인, 범용적인이라는 영어 단어 뜻이다.

풀어보면 특정 타입에 속한 것이 아니라 일반적으로, 범용적으로 사용할 있다는 뜻이다.

 

**제네릭 타입 (Generic Type)**

클래스나 인터페이스를 정의할 타입 매개변수를 사용하는 것을 말한다.

제네릭 클래스, 제네릭 인터페이스를 모두 합쳐서 제네릭 타입이라 한다.

타입은 클래스, 인터페이스, 기본형(`int` ) 모두 합쳐서 부르는 말이다.

: `class GenericBox<T> { private T t; }`

여기에서 `GenericBox<T>` 제네릭 타입이라 한다.

 

**타입 매개변수 (Type Parameter)**

제네릭 타입이나 메서드에서 사용되는 변수로, 실제 타입으로 대체된다.: `GenericBox<T>`

여기에서 `T` 타입 매개변수라 한다.(대문자를 사용하는것이 관례)

 

**타입 인자 (Type Argument)**

제네릭 타입을 사용할 제공되는 실제 타입이다.

: `GenericBox<Integer>`

여기에서 `Integer` 타입 인자라 한다.


제네릭 기타

다음과 같이 한번에 여러 타입 매개변수를 선언할 수 있다.
```java
class Data<K, V> {}

 

**타입 인자로 기본형은 사용할 없다**

제네릭의 타입 인자로 기본형(`int` , `double` ..) 사용할 없다. 대신에 래퍼 클래스(`Integer` , `Double` ) 사용

하면 된다.

 

 


제네릭활용예제

위의 구조로 클래스 3개를 만든 후

(이건 기본이라서 생략할게요 모르시는분들은 객체지향에 대해서

한번 보시길바래요)

2024.12.12 - [Java공부(코딩)] - 코딩초보의 Java(자바)공부 7일차 { 객체지향 프로그래밍 }

 

코딩초보의 Java(자바)공부 7일차 { 객체지향 프로그래밍 }

벌써 블로그시작한지7일이 지났네요....꾸준히 해봅시다 화이팅!!!객체 지향 프로그래밍에 대해  알아보아요.목차 )  1) 객체지향과 절차지향의 차이     1-1) 객체란?   2) 절차지향 예시    3)

ddkk1120.tistory.com

 

 

package generic.ex2;


public class Box<T> {
	private T value;

	
	public T getValue() {
		return value;
	}

	public void setValue(T value) {
		this.value = value;
	}
	
	

}

제네릭클래스를 만든 후

 

메인코드

package generic.ex2;

import generic.animal.Animal;
import generic.animal.Cat;
import generic.animal.Dog;

public class BoxMain {
	public static void main(String[] args) {
		Animal animal = new Animal("동물", 0);
		Dog dog = new Dog("멍멍이", 15);
		Cat cat = new Cat("냐옹이", 10);
		
		Box<Cat> box = new Box<Cat>();
		box.setValue(cat);
		Cat catt = box.getValue();
		System.out.println(catt);
		catt.sound();
		
		
		
		Box<Dog> box2 = new Box<Dog>();
		box2.setValue(dog);
		Dog dogg = box2.getValue();
		System.out.println(dogg);
		dogg.sound();

	}

}

Animal [name=냐옹이, size=10]

냐옹냐옹

Animal [name=멍멍이, size=15]

멍멍

 

 


문제와 풀이1

문제1 - 제네릭 기본1

**문제 설명**

다음 코드와 실행 결과를 참고해서 `Container` 클래스를 만들어라.

`Container` 클래스는 제네릭을 사용해야 한다.

package generic.test.ex1;
public class ContainerTest {
public static void main(String[] args) {
Container<String> stringContainer = new Container<>();
System.out.println("빈값 확인1: " + stringContainer.isEmpty());
stringContainer.setItem("data1");
System.out.println("저장 데이터: " + stringContainer.getItem());
System.out.println("빈값 확인2: " + stringContainer.isEmpty());
Container<Integer> integerContainer = new Container<>();
integerContainer.setItem(10);
System.out.println("저장 데이터: " + integerContainer.getItem());
}
}
```
**실행 결과**
```
빈값 확인1: true
저장 데이터: data1
빈값 확인2: false
저장 데이터: 10

 

 

정답:

public class ContainerMain {
	public static void main(String[] args) {
		Container<String> stringContainer = new Container<>();
		System.out.println("빈값 확인1: " + stringContainer.isEmpty());
		stringContainer.setItem("ii");
		System.out.println("저장 데이터: " + stringContainer.getItem());
		System.out.println("빈값 확인2: " + stringContainer.isEmpty());
		Container<Integer> integerContainer = new Container<>();
		integerContainer.setItem(10);
		System.out.println("저장 데이터: " + integerContainer.getItem());
		}

}

문제2 - 제네릭 기본2

**문제 설명**

다음 코드와 실행 결과를 참고해서 `Pair` 클래스를 만들어라.

`Pair` 클래스는 제네릭을 사용해야 한다.

 

public class PairMain {
	public static void main(String[] args) {
		Pair<Integer, String> pair1 = new Pair<>(20250106,"Date");
		System.out.println(pair1.getFirst());
		System.out.println(pair1.getSecond());
		System.out.println("pair1 = " + pair1);
		
		Pair<String, String> pair2 = new Pair<>("안녕하세요", "동곤자바입니다");
		System.out.println(pair2.getFirst());
		System.out.println(pair2.getSecond());
		System.out.println("pair2 = " + pair2);
		
		
		}

}

Set 을 넣지않고 생성자로 받아버려서

제네릭타입을 입력에맞게 설정하게 했어요!!!

 

public class Pair<T1,T2> {
	private T1 first;
	private T2 second;
	
	public Pair(T1 first , T2 second) {
		this.first = first;
		this.second = second;
	}
	
	public T1 getFirst() {
		return first;
	}
	
	public T2 getSecond() {
		return second;
	}

	@Override
	public String toString() {
		return "Pair [first=" + first + ", second=" + second + "]";
	}
	
	
}