티스토리 뷰

프로그래밍/Java

자바 ! 제네릭( Generic )

나는연어다 2017. 5. 13. 18:36

제네릭

하나의 코드를 여러 타입에 대하여 재사용하는 기술

C++의 Template 기법과 비슷

구체적인 타입을 사용하지 않고 변수 형태로 적는다.

타입 매개변수: 클래스 타입, 인터페이스 타입, 배열 타입

                등을 나타낼수 있다.


* 보통은 대문자를 이용한다


제네릭을 사용하는 이유? 데이터를 꺼낼 때 마다 타입 변환을 해야하는 

번거로움이 있을 수 있기 때문이다.

(다형성의 Upcasting, Downcasting을 이용한 문제점 보안)




일반 클래스 클래스입니다.

1
2
3
4
5
6
class Student{
     Object name;
     
     void set(Object t){ this.name = t ; }
     Object get() { return name; }
}


일반 클래스에서 제네릭을 이용한 클래스입니다.

1
2
3
4
5
6
class Student<T>{
      T name;
       
      void set(T t) { this.name = t ; }
      T get() { return name; }
}




˚ 제네릭 클래스 사용

- 기초 자료형은 T 대신에 사용할 수 없습니다.

  클래스 객체만 사용할 수 있습니다.



˚ Raw 타입

- 제네릭 클래스의 타입 매개변수가 없는 것 입니다.

ex) Student<String> stu = new String<>();


- 만약 위에서 타입 인수가 생략된다면 Raw타입이 된다.

ex) Student stu = new Student();


※주의할 점은 처음부터 제네릭 클래스가 아니라면 Raw타입으로 사용할 수 없다는 것입니다.



제네릭 메소드


제네릭을 메소드에도 사용할 수 있다.



제네릭 클래스와는 달리 타입 매개변수의 범위가 메소드 내부로 제한된다.



메소드의 수식자와 반환형 사이에 타입 매개변수가 위치되어야 한다.


1
2
3
4
5
public class Example{
         public static <b><u><T></u></b> T get(T a){
                   return a;
         }
}


메소드 호출 시 컴파일러는 이미 타입 정보를 알고 있기 때문에 실제 타입을

<>안에 적으면 되지만 생략하여도 된다.


String s = Exaple.<String>getA(yoon);   => String s = Example.getA(yoon);




제네릭에 대한 기본적인 공부를 마치고 실습을 통해 공부하도록 하겠습니다.


과일박스안에 Orange와 Apple인 과일이 있습니다.


이러한 과일을 각각의 박스에 담는 것을 일반적인 방식과 제네릭을 사용한 방식으로 실습하겠습니다.




과일박스(Fruit Box) 클래스입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class FruitBox {
    private Fruit fruit;
 
    public void putFruit(Fruit fruit) {
        System.out.println(fruit + "을 담습니다.");
        this.fruit = fruit;
    }
     
    public Fruit getFruit(){
        System.out.println(fruit+"을 꺼냅니다.");
        return fruit;
    }
}



Fruit 클래스입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Fruit {
    private int sugar;
    private String color;
 
    public Fruit(int sugar, String color) {
        this.sugar = sugar;
        this.color = color;
    }
 
    public void showFruitInfo() {
        System.out.println("당도: " + this.sugar + "%");
        System.out.println("색깔: " + this.color + "색");
    }
}



Fruit 클래스를 상속(extends)받은 Orange 클래스입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Orange extends Fruit {
 
    public Orange() {
        super(20, "주황");
    }
    @Override
    public String toString() {
        return "오렌지";
    }
     
    public void goo(){
        System.out.println("Orange.goo()");
    }
 
}



Fruit class를 상속(extends)받은 Apple 클래스입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Apple extends Fruit {
 
    public Apple() {
        super(10, "빨강");
    }
    @Override
    public String toString() {
        return "사과";
    }
     
    public void foo(){
        System.out.println("Apple.foo()");
    }
}



이제 클래스를 사용할 일반 메인 클래스 입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ExampleMain{
    public static void main(String[] args) {
 
        FruitBox fruitBox = new FruitBox();
         
 
        fruitBox.putFruit(new Apple()); // UpCasting   
        Orange orange2 = (Orange)fruitBox.getFruit();  // DownCasting의 문제점
         
                 
        Apple apple = (Apple) fruitBox.getFruit(); // UpCasting 된 것을 받게되므로
                                                    // DownCasting
        apple.foo();
        System.out.println("꺼낸 과일: " + apple);
 
        fruitBox.putFruit(new Orange());// UpCasting
        Orange orange = (Orange) fruitBox.getFruit();// UpCasting 된 것을 받게되므로
                                                        // DownCasting
        orange.goo();
        System.out.println("꺼낸 과일: " + orange);
 
    }
}



일반 메인 클래스와 제네릭을 사용한 메인클래스를

비교하며 공부하겠습니다.



제네릭을 사용한 메인 클래스입니다..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ExampleGeneric{
    public static void main(String[] args) {
        FruitBox<apple> appleBox = new FruitBox<apple>(); // 뒤에 <>에는 비어도 상관없다.
        FruitBox<orange> orangeBox = new FruitBox<>();
         
         
        appleBox.putFruit(new Apple());
        orangeBox.putFruit(new Orange());
 
        // Orange orange = (Orange)appleBox.getClass(); 이미 appleBox로 설정되어있기 때문에
        // 안된다.
         
        // 객체형태로 데이터베이스로 보낼때 사용하며, 컬렉션 프레임워크에서 중요하다
    }
}
</orange></apple></apple>


반응형
LIST
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함