λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸ’»/JAVA

[Java] 15일차 : μ œλ„ˆλ¦­(Generics)

by λ”°κΆˆ 2024. 3. 6.

 

 

μ œλ„ˆλ¦­( generics)μ΄λž€?
λ‹€μ–‘ν•œ νƒ€μž…μ˜ 객체λ₯Ό λ‹€λ£¨λŠ” ν΄λž˜μŠ€λ‚˜ μΈν„°νŽ˜μ΄μŠ€μ—μ„œ μ‚¬μš©ν•  데이터 νƒ€μž…μ„ μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 λ•Œ κ²°μ •ν•˜λŠ” κ²ƒμœΌλ‘œ  JDK 5.0λΆ€ν„° 지원
데이터 ν˜•μ— λŒ€ν•œ λ³„λ„μ˜ λ©”μ†Œλ“œλ‚˜ 멀버 λ³€μˆ˜λ₯Ό κ΅¬ν˜„ν•  ν•„μš” 없이 미리 μ •μ˜λœ λ©”μ†Œλ“œ λ˜λŠ” 멀버 λ³€μˆ˜μ— μ„œλ‘œ λ‹€λ₯Έ μžλ£Œν˜•μœΌλ‘œ μ²˜λ¦¬ν•  수 μžˆλ‹€.
객체의 νƒ€μž…μ„ 컴파일 ν•  λ•Œ μ²΄ν¬ν•˜λ―€λ‘œ 객체 νƒ€μž…μ˜ μ•ˆμ •μ„±μ„ 높이고 λΆˆν•„μš”ν•œ ν˜• λ³€ν™˜μ„ 쀄일 수 μžˆλ‹€.



β–Άμž₯점

  • μ„±λŠ₯ μ €ν•˜λ₯Ό μœ λ°œν•˜λŠ” κ°•μ œ μΊμŠ€νŒ…μ„ 쀄일 수 μžˆλ‹€.
  • 컴파일 ν•  λ•Œ νƒ€μž… 였λ₯˜λ₯Ό μ²΄ν¬ν•˜λ―€λ‘œ 객체 νƒ€μž…μ˜ μ•ˆμ •μ„±μ„ 높인닀.
  • 반볡적인 μ½”λ“œλ₯Ό μ€„μΌμˆ˜ 있으며, μž¬μ‚¬μš©μ„± μ¦κ°€λ‘œ μœ μ§€λ³΄μˆ˜κ°€ νŽΈλ¦¬ν•˜λ‹€.

 

μ œλ„ˆλ¦­ 클래슀 및 μ œλ„ˆλ¦­ μΈν„°νŽ˜μ΄μŠ€ 
νƒ€μž… νŒŒλΌλ―Έν„°λ₯Ό ν•˜λ‚˜ 이상 κ°–λŠ” μ œλ„ˆλ¦­ νƒ€μž…μ˜ 클래슀 λ˜λŠ” μΈν„°νŽ˜μ΄μŠ€
ν΄λž˜μŠ€λ‚˜ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ„ μ–Έν•  λ•Œ νƒ€μž…μ„ μ§€μ •ν•˜μ§€ μ•Šκ³  μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 λ•Œ μ‚¬μš©ν•  νƒ€μž…μ„ νŒŒλΌλ―Έν„°λ‘œ μ§€μ •
ν΄λž˜μŠ€λ‚˜ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ„ μ–Έν•  λ•Œ 클래슀 λ˜λŠ” μΈν„°νŽ˜μ΄μŠ€ 이름 뒀에 <> λΆ€ν˜Έλ₯Ό 뢙이며, <> λΆ€ν˜Έ 사이에 νƒ€μž… νŒŒλΌλ―Έν„°λ₯Ό μ§€μ •
μ œλ„ˆλ¦­ νƒ€μž…μ€ λ‘κ°œ μ΄μƒμ˜ νƒ€μž… νŒŒλΌλ―Έν„°λ₯Ό κ°€μ§ˆ 수 있으며, 각 νƒ€μž…μ€ 콀마(,)둜 κ΅¬λΆ„ν•œλ‹€.



νƒ€μž… νŒŒλΌλ―Έν„° 

일반적으둜 λŒ€λ¬Έμž μ•ŒνŒŒλ²³ ν•œ 문자λ₯Ό μ‚¬μš©

 

 

 

 

μ œλ„ˆλ¦­ λ©”μ†Œλ“œ

  • νƒ€μž… νŒŒλΌλ―Έν„°λ₯Ό ν•˜λ‚˜ 이상 κ°–λŠ” λ©”μ†Œλ“œ
  • λ©”μ†Œλ“œλ₯Ό μ„ μ–Έν•  λ•Œ νƒ€μž…μ„ μ§€μ •ν•˜μ§€ μ•Šκ³  λ©”μ†Œλ“œλ₯Ό 호좜 ν•  λ•Œ λͺ…μ‹œμ μœΌλ‘œ νƒ€μž…μ„ μ§€μ •ν•˜κ±°λ‚˜ λ©”μ†Œλ“œμ˜ λ§€κ°œλ³€μˆ˜ κ°’μ˜ νƒ€μž…μœΌλ‘œ μ§€μ •
  • μ„ μ—… 방법은 리턴 νƒ€μž… μ•žμ— <> 기호λ₯Ό μΆ”κ°€ν•˜κ³  <> 기호 μ•ˆμ— νƒ€μž… νŒŒλΌλ―Έν„°λ₯Ό 기술 ν•œ ν›„ 리턴 νƒ€μž…κ³Ό 맀개 λ³€μˆ˜ νƒ€μž…μ—μ„œ νƒ€μž… νŒŒλΌλ―Έν„°λ₯Ό μ‚¬μš©
  • β–Ά λ©”μ†Œλ“œ 호좜 ν˜•μ‹
  • λͺ…μ‹œμ μœΌλ‘œ νƒ€μž… νŒŒλΌλ―Έν„° μ§€μ • : λ¦¬ν„΄νƒ€μž… λ³€μˆ˜ = 객체λͺ….<λͺ…μ‹œμ μΈνƒ€μž…>λ©”μ†Œλ“œλͺ…(λ§€κ°œλ³€μˆ˜κ°’);
  • λ©”μ†Œλ“œμ˜ λ§€κ°œλ³€μˆ˜κ°’ νƒ€μž…μœΌλ‘œ νƒ€μž… νŒŒλΌλ―Έν„° μ§€μ • λ¦¬ν„΄νƒ€μž… λ³€μˆ˜ = 객체λͺ….λ©”μ†Œλ“œλͺ…(λ§€κ°œλ³€μˆ˜κ°’);

 

 

μ œλ„ˆλ¦­μ˜ μ™€μΌλ“œ μΉ΄λ“œ(wildcard)

  • μ œλ„ˆλ¦­μ€ 컴파일 λ‹¨κ³„μ—μ„œ νƒ€μž… μ•ˆμ •μ„± μœ„ν•΄ μ§€μ›ν•˜λ―€λ‘œ 기본적으둜 λ‹€ν˜•μ„±(Polymorphism)을 κ°–μ§€ μ•ŠλŠ”λ‹€. λ”°λΌμ„œ μ œλ„ˆλ¦­(Gereric)에 λ‹€ν˜•μ„±μ„ 갖도둝 λ§Œλ“€κΈ° μœ„ν•΄ μ™€μΌλ“œ μΉ΄λ“œλ₯Ό μ‚¬μš©ν•œλ‹€.
  • μ œλ„ˆλ¦­ νƒ€μž…μ„ λ§€κ°œκ°’μ΄λ‚˜ 리턴 νƒ€μž…μœΌλ‘œ μ‚¬μš©ν•  λ•Œ ꡬ체적인 νƒ€μž… λŒ€μ‹  μ™€μΌλ“œ μΉ΄λ“œ(?)λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€. 즉, μ œλ„ˆλ¦­ νƒ€μž…μ˜ 클래슀λ₯Ό νŒŒλΌλ―Έν„°λ‘œ μ‚¬μš©ν•  λ•Œ ꡬ체적인 νƒ€μž…μ΄ μ •ν•΄μ§€μ§€ μ•ŠλŠ” κ²½μš°μ— μ‚¬μš©ν•œλ‹€.

 

 

package ch10.unit01;

public class Ex03 {

	public static void main(String[] args) {
		Test3<String> t1 = new Test3<String>();
		t1.set("μ„œμšΈ");
		//t1.set(100); 컴였λ₯˜
		String s = t1.get();
		System.out.println(s);
		
		Test3<Integer> t2 = new Test3<>(); // new Test3<>();μ—μ„œ <>에 Integer
		t2.set(100);
		//t2.set("seoul"); 컴였λ₯˜
		int n = t2.get();
		System.out.println(n);
		
		/* κ°€λŠ₯ν•˜μ§€λ§Œ κ²½κ³ , 이경우 μ œλ„ˆλ¦­μ€ Object둜 처리 
		Test3 t3 = new Test3();
		t3.set("μ„œμšΈ");
		t3.set(50);
		*/
	}

}
//Generic - ν•˜λ‚˜μ˜ νƒ€μž… νŒŒλΌλ―Έν„° 
class Test3<T>{
	
	private T t;
	
	public void set(T t) {
		this.t = t;
	}
	public T get() {
		System.out.println(t.getClass());
		
		return t;
	}
}

 

 

package ch10.unit01;

public class Ex04 {

	public static void main(String[] args) {
		Test4 <String, Integer> obj = new Test4<>();
		
		obj.set("μžλ°”", 95);
		obj.disp();

	}

}
// λ‘κ°œμ˜ νƒ€μž… νŒŒλΌλ―Έν„°
class Test4<T,U> {
	private T t;
	private U u;
	
	public void set(T t, U u) {
		this.t = t;
		this.u = u;
	}
	
	public void disp() {
		System.out.println("T:"+t.getClass().getName()+","+t);
		System.out.println("U:"+t.getClass().getName()+","+u);
	}
	
}

 

 

 

package ch10.unit01;
//μ œλ„ˆλ¦­ μΈν„°νŽ˜μ΄μŠ€
public class Ex05 {

	public static void main(String[] args) {
		Test5<Integer> t = new TestImp15<>();
		t.disp(100);

	}

}

//μ œλ„ˆλ¦­ μΈν„°νŽ˜μ΄μŠ€
interface Test5<T>{
	public void disp(T t);
}

//κ΅¬ν˜„ 클래슀 - 1
class TestImp15<T> implements Test5<T>{

	
	public void disp(T t) {
		System.out.println(t);
	}
}

class DemoImp15<T> implements Test5<String>{
	
	public void disp(String t) {
		System.out.println(t);
	}
}

 

 

 

package ch10.unit01;

public class Ex06 {

	public static void main(String[] args) {
		Test6 t = new Test6();
		
		t.disp("μžλ°”");
		t.disp(100);

		t.write(100);
		//t.wriet("μžλ°”"); 컴였λ₯˜ 
	}

}

//generic method 
class Test6{
	public <U> void disp(U u) {
		System.out.println(u.getClass().getName()+","+u);
	}
	
	// Number 
	public <U extends Number> void write(U u) {
		System.out.println(u.getClass().getName()+","+u);
	}
}

 

 

 

 

package ch10.unit01;

public class Ex07 {

	public static void main(String[] args) {
		Test1<Integer> t = new Test1<Integer>();
		
		t.set(100);
		System.out.println(t.get());
		
		/*Integer a = 10;
		Number b = a; κ°€λŠ₯, up casting
		*/
		
		//Test1<Number> t2 = t; // 컴였λ₯˜ λΆˆκ°€ μ œλ„ˆλ¦­μ€ 상속 관계가 μ•„λ‹˜ 
								// Test1<Integer>이 Test1<Number>의 μžμ‹ 관계가 λ μˆ˜μ—†μŒ
		
	}

}

class Test1<T> {

	private T t;

	public void set(T t) {
		this.t = t;
	}

	public T get() {
		return t;
	}
}

 

 

 

package ch10.unit02;

public class Ex02 {

	public static void main(String[] args) {

		Test2<String>t = new Test2<>();
		t.set("μžλ°”");
		write(t);
		
		Test2<Integer> t2 = new Test2<>();
		t2.set(100);
		write(t2);
		

	}
	
	/*
	 * μ œλ„ˆλ¦­ μ™€μΌλ“œ μΉ΄λ“œ - ?
	 : λͺ¨λ“  ν΄λž˜μŠ€λ‚˜ μΈν„°νŽ˜μ΄μŠ€κ°€ κ°€λŠ₯
	 : μ œλ„ˆλ¦­ νƒ€μž…μ— μ˜μ‘΄μ μ΄μ§€ μ•ŠλŠ” λ©”μ†Œλ“œλ“±μ„ ν˜ΈμΆœν•  λ•Œ μ‚¬μš©
	 : 읽기만 κ°€λŠ₯. 변경은 λΆˆκ°€ 
	 */
	
	
	
	public static void write(Test2<?>obj) {
		obj.disp();
		// obj.set(30); // 컴였λ₯˜, μžλ£Œν˜• κ²°μ •λ˜μ§€ μ•ŠμŒ
		System.out.println("------------\n");
		
	}
	
}
class Test2<T>{
	private T t;

	public T get() {
		return t;
	}

	public void set(T t) {
		this.t = t;
	}
	
	public void disp() {
		System.out.println(t);
	}
	
}