[Java] 제네릭

2024. 8. 14. 09:00·Java
목차
  1. 제네릭
반응형

제네릭

  • 클래스 선언시에는 결정하지 못한 필드 또는 매개변수 또는 메소드의 리턴타입을 객체가 생성시에 결정짓도록 하는 방법
  • 타입변수는 래퍼클래스 사용
  • 제네릭 클래스 사용시 생성 객체를 담는 변수에도 반드시 <> 기호를 사용하여 타입의 데이터타입을 결정해줘야 한다
    생략시 Object 타입으로 받는다
  • 원리 : 타입파라미터라고 하는 외부에서 타입을 전달받을 수 있는 타입변수 사용하여 객체 생성시 타입변수로 타입을 전달받아 객체 내부의 데이터타입을 결정짓는다
  • 다이아몬드 문법 : 제네릭을 사용한 객체 생성시 왼쪽의 클래스 변수의 타입을 보고 오른쪽 타입을 예측할 수 있다면
      타입값을 생략하는 문법을 의미(자바 8버전 이상부터 사용할 수 있다)
  • 제네릭 타입을 갖는 부모 클래스를 상속받는 경우 자식쪽에서 부모의 타입을 결정할 수 있다
  • 자식 타입파라미터 값은 부모로 전달할 수 있다

 

 

1) A, B, Main01

public class A {
	public Object field01;
}

 

public class B <A> {
	private A field01;

	public void setField01(A field01) {
		this.field01 = field01;
	}
	
	public A getField01() {
		return field01;
	}
}

 

public class Main01 {
	public static void main(String[] args) {
		A a01 = new A();
		a01.field01 = "Hi"; //String
		
		A a02 = new A();
		a02.field01 = 'H';  //Character
		
		String f01 = (String)a01.field01; //강제형변환 필요
		
		//String f02 = (String)a02.field01; //java.lang.ClassCastException 오류 발생
		if(a02.field01 instanceof String) {
			String f02 = (String)a02.field01;
		}
        
		B<String> b = new B<String>();
		
		B<Character> bb = new B<Character>();
		
		b.setField01("H");
		String f = b.getField01();
		
		bb.setField01('H');
		
		System.out.println("프로그램 종료");
	}
}

 

 

2) Box, GenericExample

타입파라미터로 T 사용

GenericExample 클래스에서 Box box1 생성할때 String으로 생성, Box box2 생성할때 Integer로 생성

public class Box<T> {
	public T content;
}

 

 

public class GenericExample {
	public static void main(String[] args) {
		//Box<String> box1 = new Box<String>();
		Box<String> box1 = new Box<>();
		box1.content = "안녕하세요";
		String str = box1.content;
		System.out.println(str);
		
		//Box<Integer> box2 = new Box<Integer>();
		Box<Integer> box2 = new Box<>();
		box2.content = 100; //int -> Integer로 자동 박싱
		int value = box2.content;
		System.out.println(value);
	}
}

 

 

3) 제네릭 타입을 갖는 부모 클래스 상속

public class B <A> {
	private A field01;

	public void setField01(A field01) {
		this.field01 = field01;
	}
	
	public A getField01() {
		return field01;
	}
}

 

public class Child01 extends B<String> {
	public String field02;
	
	public static void main(String[] args) {
		Child01 child01 = new Child01();
		
		child01.setField01("");
		
		Child02 child02 = new Child02();
		child02.setField01(100);
	}
}

class Child02 extends B<Integer>{
	
}

 

 

4) 자식 클래스에서 생성할때 타입결정하도록 제네릭

자식 타입파라미터 값은 부모로 전달할 수 있다

public class B <A> {
	private A field01;

	public void setField01(A field01) {
		this.field01 = field01;
	}
	
	public A getField01() {
		return field01;
	}
}



public class Child03<T> extends B<T> {
	
	public static void main(String[] args) {
		Child03<String> child03 = new Child03<String>();
		child03.setField01("");
		
	}
}

 

 

5) 아래의 코드를 보고 Container 제네릭 타입을 만들어보기

public static void main(String[] args) {
    Container<String> container = new Container<String>();
    container.set("홍길동");
    String str = container.get();

    Container<Integer> container2 = new Container<Integer>();
    container2.set(6);
    int value = container2.get();

}

 

 

만든 결과

public class Container<T> {
	public T field;
	
	public void set(T field) {
		this.field = field;
	}
	
	public T get() {
		return field;
	}
	
	public static void main(String[] args) {
		Container<String> container = new Container<String>();
		container.set("홍길동");
		String str = container.get();
		
		Container<Integer> container2 = new Container<Integer>();
		container2.set(6);
		int value = container2.get();
		
		System.out.println("str :" + str + ", value :" + value);
	}

}

실행결과)

str :홍길동, value :6

 

 

6) 해당 main을 실행했을때 실행결과가 밑처럼 나오도록 Sample01 제네릭 타입 만들기
 100
 안녕하세요

 20

=> Sample01<Child01> sample01 = new Sample01<Child01>();
sample01.field01 = new Child01(); 

sample01.field01에 new Child01()을 생성하였기 때문에 Child01의 부모인 B에 있는 get, set을 사용하여 

sample01.field01.setField01("100");
System.out.println(sample01.field01.getField01()); 가능하였다.

public static void main(String[] args) {
    Sample01<Child01> sample01 = new Sample01<Child01>();
    sample01.field01 = new Child01();

    sample01.field01.setField01("100");
    System.out.println(sample01.field01.getField01());

    Sample01<String> sample02 = new Sample01<String>();
    sample02.field01 = "안녕하세요";
    System.out.println(sample02.field01);
    
    Sample01<Integer> sample03 = new Sample01<Integer>();
    sample03.field01 = 10;
    System.out.println(sample03.field01 + 10);
}

 

만든 결과

public class B <A> {
	private A field01;

	public void setField01(A field01) {
		this.field01 = field01;
	}
	
	public A getField01() {
		return field01;
	}
}

public class Child01 extends B<String> {

}

 

public class Sample01<T> {
    public T field01;

    public static void main(String[] args) {
        Sample01<Child01> sample01 = new Sample01<Child01>();
        sample01.field01 = new Child01();

        sample01.field01.setField01("100");
        System.out.println(sample01.field01.getField01());

        Sample01<String> sample02 = new Sample01<String>();
        sample02.field01 = "안녕하세요";
        System.out.println(sample02.field01);

        Sample01<Integer> sample03 = new Sample01<Integer>();
        sample03.field01 = 10;
        System.out.println(sample03.field01 + 10);
	}
}

실행결과)

100
안녕하세요
20

 

 

7) 해당 main을 실행했을때 실행결과가 밑처럼 나오도록 Sample02 제네릭 타입 만들기
안녕하세요,

3.15

public static void main(String[] args) {
    Sample02<String> s1 = new Sample02<String>();
    s1.field = "안녕하세요,";
    String resultStr = s1.getField();
    System.out.println(resultStr);

    Sample02<Double> s2 = new Sample02<Double>();
    s2.field = 3.15;
    Double resultDouble = s2.getField();
    System.out.println(resultDouble);
}

 

만든 결과

public class Sample02<T> {
	public T field;
	
	public T getField() {
		return field;
	}
	
	
	public static void main(String[] args) {
		Sample02<String> s1 = new Sample02<String>();
		s1.field = "안녕하세요,";
		String resultStr = s1.getField();
		System.out.println(resultStr);
		
		Sample02<Double> s2 = new Sample02<Double>();
		s2.field = 3.15;
		Double resultDouble = s2.getField();
		System.out.println(resultDouble);
	}
}

실행결과)

안녕하세요,
3.15

 

 

반응형

'Java' 카테고리의 다른 글

[Java] 컬렉션 프레임워크  (0) 2024.08.16
[Java] 제네릭 타입  (0) 2024.08.15
[Java] Date, SimpleDateFormat, Calendar  (0) 2024.08.13
[Java] toString(), StringBuilder, StringTokenizer, Math, Wrapper  (0) 2024.08.10
[Java] Object, equals(), hashCode()  (0) 2024.08.09
  1. 제네릭
'Java' 카테고리의 다른 글
  • [Java] 컬렉션 프레임워크
  • [Java] 제네릭 타입
  • [Java] Date, SimpleDateFormat, Calendar
  • [Java] toString(), StringBuilder, StringTokenizer, Math, Wrapper
초보개발자J
초보개발자J
초보개발자J
J의 코딩 노트
초보개발자J
전체
오늘
어제
  • 분류 전체보기 (126)
    • Java (49)
    • MySQL (10)
    • HTML, CSS (8)
    • JavaScript, jQuery, Ajax (12)
    • Spring (15)
    • Python (0)
    • Baekjoon [Java] (27)
    • Git (1)
    • Spring Boot (3)
    • Visual Studio Code (1)
    • 일상 (0)
    • 영어 (0)
반응형

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

hELLO· Designed By정상우.v4.5.3
초보개발자J
[Java] 제네릭

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.