날아라쩡글이의 블로그입니다.

Generic(제네릭) 본문

중앙 HTA (2106기) story/java API story

Generic(제네릭)

날아라쩡글이 2021. 10. 5. 21:20
반응형
  • web에서 활용도가 많은 class이다. 
  • java.base에 존재한다. 
  • 자바 5부터 추가되었다. 
  • <T> , <T,K>한글자가 아닌 여러글자도 존재한다.
  • 소스레벨에서 데이터 타입이 결정되지 않고, 별칭(타입파라미터) 만 지정한다. 
    • 데이터타입은 필드의 타입, 매개변수 타입, 리턴타입등이다. 
  • 객체 생성시점, 구현클래스 구현시점, 메소드 실행시점에 별칭을 대신할 데이터 타입을 외부에서 지정하는 것이다. 
  • 클래스나 인터페이스 옆에 header처럼 적어 놓았다. 
  • 제네릭은 <>다이아몬드표기법으로 타입파라미터(별칭)을 지정한다. 
    • 객체생성시점, 구현클래스구현시점, 메소드실행시점에 데이터타입을 지정한다. 
    • 데이터타입은 클래스 혹은 인터페이스타입만 가능하다. 
    • 기본자료형은 제네릭의 데이터타입으로 지정할 수 없다.
  • 제네릭이 나오게 된 이유 
    1. Box라는 class를 생성한 후 Box안에 생선도 넣고, 고구마도 넣고, 기계물품도 넣고, 다양한 물건을 넣고 꺼내고 싶었다. 그러나 데이터 타입을 1가지만 정하면 그것밖에 꺼낼 수 없고 , 범용적으로 사용되고 있는 상속되고 있는 타입을 정해서 입력을 하더라도 Phone과 Apple이 함께 출력될 수 없는다. 
    2. 그럼 저장소의 타입을 모든 객체의 부모인 데이터타입으로 설정하면 어떨까?? 일단 결과는 반은 성공적이었다. 모든 객체는 모든지 클래스 형변환으로 담을 수 있고, 출력도 가능했기 때문이다. 그러나 문제점이 발생했다. 
      1. 저장되는 객체의 종류를 지정할 수 없다. (타입의 안정성이 확보되지 않는다.)
      2. 저장된 객체를 출력할 때마다 형변환이 필요하다.(강제형변환이 필요하다.)
    3. 장점?? Box의 객체는 모든 종류의 객체를 저장할 수 있다. 

    1. Food객체를 여러개 저장하는 NoneGenericBox의 객체를 생성하였다. 
    2.  생성된 NoneGenericBox 객체에 food객체를 저장한다. 
    3. void addItem(Object item) {...}이 실행된다. 
    4. 그리고 저장될 때 Object 타입으로 클래스 형변환이 된다. 
    5. NoneGenericBox 에 다른타입을 입력해도 에러가 나지 않는다 . 
      1. 생성된 Box객체에 Food객체와 다른 객체를 저장해도 오류가 발생하지 않는다.(타입의 안정성이 보장되지 않는다.)
    6. NoneGenericBox 객체에 저장된 Food객체를 가져온다. 
    7. 그럼 Object의 객체의 주소값이 반환된다. 
    8. Object getItem(int index){...}가 실행된다. 
    9. Food타입으로 강제 형변환한다. 형변환 연산자를 꼭 사용해야한다. 
      1. 강제형변환을 꼭 사용해야한다.
  • 이 부분을 극복하기 위해서 제네릭을 사용하기로 하였다. 
    • 타입 결정에 제한적이다. 
    • 안정성이 확보되지 않았다. 
    • 형변환 사용을 해야한다. 
  • 위의 이유때문에 문제가 있다면..? 그럼 처음부터 타입을 정하지 말자. 

제네릭

  • 위에서 Object를 쓴 부분을 <T>로 바꾸고 Object의 부분을 T로 지정해 놓으면 된다. 
  • T = 타입파라미터 
  • 그리고 GenericBox는 main메소드가 있는 App객체에 생성을 할 때 타입파라미터를 사용하기 바로 직전에 작성을 해주면 된다. 그렇게 되면 
  •  
  • 이렇게 T로 설정한 곳이 사용할 객체를 넣자마자 바로 Food, Contact사용할 객체의 데이터 타입으로 변한것을 확인할 수 있다. 
  • 위의 T의 자리에 실제로 생성된 객체 데이터 타입이 들어가 있다. 
  • <T>자리에 들어가는 것만 쓰기전에 정해주면 되는 class가 제네릭 class이다. 
  • Object 처럼 고정이아니라 사용 바로 직전에 그 타입으로 정해지는 것이다. 
  • 언제 사용될까? 객체를 저장하는 collection클래스에 거의 사용된다. 
  • 타입파라미터란 - 필드의 타입, 매개변수의 타입, 리턴타입이다. 
  • Box<int > numbers = new Box<int>();이것은 사용이 불가하다. 
  • int를 담고 싶다면, Box<Integer> numbers = new Box<>();이렇게 사용이 가능하다.

 

제네릭 클래스 

  • 타입파라미터를 하나이상 가지고 있는 클래스이다. 
  • 여러 종류의 객체를 다루는 클래스를 제네릭 클래스로 정의하면 타입의 안전성을 보장받고, 형변환코드를 제거할 수 있다. 
  • 제네릭 클래스는 
    • 자료구조(Set, List, Map<K, V>)
    • 데이터를 반복처리하는 것 에서 사용한다.

제네릭 클래스는 <T>를 지정하지 않으면, 생략한다면 Object의 타입으로 변하게 된다. 

타입파라미터로 설정한 부분이 전부 Object타입으로 변하게 된다. 

  • 타입의 안정성이 보장되지 않는다. 
  • 저장된 객체를 사용할 때에는 형변환 연산자를 사용해야한다. 
  • 제네릭을 사용하면 이렇게 쉽게 코드를 작성할 수 있다. 
  • 이제 타입에 따른 객체를 생성할 수 있다. 
    • 타입지정이라는 것은 없다. Generic<T> 타입파라미터에 내가 실제로 저장하고 싶은 타입을 저장해준다. 
    • 타입안정성으로 오류가 나지 않는다. 
    • 값을 가져올때 형변환이 필요없다. 
    • 컴파일이 되는 시점을 알 수 있다. (error의 발생, 빨간줄이 가는 것을 보고 확인할 수 있다. )

자바의 변화 

  • 1.4   -----> 1.5( 자바 5 버젼 )
    1. 오토박싱/ 언박싱
    2. 향상된 for문
    3. 제네릭
  • 1.7 -----> 1.8(자바 8버젼) 
    1. 람다표현식  ->
    2. Strim도입
    3. 인터페이스 변화(추상메소드가 아닌걸 추구할 수 있게됨)
  • 1.8 -----> 1.9(자바 9버젼)
    • 모듈의 도입, 라이브러리를 도입했다. 

제네릭의 extends

  • 전체 객체만 아닌 Phone타입만 담고싶을 때 사용하는 
  • 타입파라미터에  지정하는 타입을 제한하는 방법이다. 
  • T의 자리에 Phone에게 extends하고 있는 객체를 가져올 수 있다. 라는 뜻이다. 
  • 그렇기 때문에 PhoneGenericBoxApp에 나온 Phone ,SmartPhone, FeaturePhone의 객체를 호출해도 error가 나지 않고, Food객체나 구현, 상속객체가 아니면 error가 난다. 
  • 한정시키고 싶을 때 사용한다. 
  • <T extends Phone> : 부모를 포함한 하위객체라는 뜻이다. 

제네릭의 와일드 카드 

  • 물음표가 들어가는 방법이다. 
  • 작성방법 
    1. <? extends T>
    2. <? super T>
    3. <?>
  • 제네릭의 다형성을 적용할 때 사용한다. 
  • '?','extends','super'를 사용해서 다룰 객체의 상한과 하한을 지정할 수 있다.
  • 한종류의 제네릭 타입 참조변수로 다른타입이 지정된 객체를 다룬다. 
  • 매개변수나 반환타입에 작성이 가능하다. 
  • 제네릭으로 선언된 것을 매개변수와 반환타입에 지정할 수 있다. 
  • 제네릭의 와일드카드의 경우 class와 interface정의시 사용할 수 없다. 
    • 현재까지 사용한 제네릭처럼 사용할 수 없다는 뜻이다. 
    • public class Box<T extends Phone>
    • public class Box<T>처럼 사용할 수 없다. 
  • <? extends T> 
    • 상한제한이다. T와 T의 하위만 허용한다. 
  • <? super T>
    • 하한제한이다. T와 T의 상위만 허용한다. 
    • 잘 사용하지 않는다.
  • <?>
    • 제한없다. 
  • 이전에 제네릭타입으로 글을 작성한 부분이 있다. 
  • public class Object {
  • class<?>  getclass() {...}
  • } 여기서 <?>이부분은 아무객체나 들어와도 상관없다는 뜻이다. 

Object클래스의 제네릭 와일드 카드

  • public class <?> getclass(){...}
  • collection<E> 인터페이스의 void addAll(colletion<? extends E> items);
  • predicate<T> 인터페이스의 static <T> predicate<T> not(predicate<? super T>target)
반응형

'중앙 HTA (2106기) story > java API story' 카테고리의 다른 글

Map interface  (0) 2021.10.08
Set interface, List interface(iterator)  (0) 2021.10.07
System, Wrapper, math class  (0) 2021.10.03
StringBuilder, StringBuffer  (0) 2021.10.03
String Class  (0) 2021.10.01
Comments