JAVA 기초

[JAVA 기초] JAVA의 정석 - Ch.12 지네릭스, 열거형, 애너테이션 (정리)

beginner-in-coding 2025. 1. 22. 17:45

Ch.12 지네릭스, 열거형, 애너테이션


-      지네릭스(Generics)

  • 지네릭스란
    • 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입 체크를 위해 사용
    • 장점
      1. 타입의 안정성을 높임
      2. 타입 체크와 형변환을 생략할 수 있으므로 코드가 간결
  • 지네릭 클래스의 선언
    • 지네릭 클래스로 변환하는 방법
      • 클래스이름 옆에 <T> 붙임
      • Object를 모두 T로 변환
        • T: 타입 변수(Type variable)
        • E: element
        • 기호의 종류만 다를 뿐 임의의 참조형 타입을 의미함
    • 지네릭스 용어
      • 원시 타입, 지네릭 클래스, 타입 매개변수 또는 타입 변수
    • 지네릭스의 제한
      • 모든 객체에 동일하게 작동해야 하는 static멤버에 타입 변수 T를 사용할 수 없음
      • 지네릭 배열로 선언할 수 없음 
        • 컴파일하는 시점에서 T가 어떤 타입이 될 지 모르기 때문
  • 지네릭 클래스의 객체 생성과 사용
    • 참조변수와 생성자에 대입한 타입(매개변수화된 타입)이 일치해야 함
    • 지네릭 타입은 상속 관계여도 사용할 수 없음
    • 지네릭 클래스가 상속 관계일 때, 대입한 타입이 같으면 사용 가능함
  • 제한된 지네릭 클래스
    • 목적: 한 종류 뿐만 아니라 다양한 종류의 타입을 받기 위해서 사용
    • 제네릭 타입에 extends를 사용: 특정 타입 + 그 타입의 자손들만 대입할 수 있게 제한됨
    • 인터페이스도 구현해야한다면 &로 연결
  • 와일드 카드
    • 지네릭 타입이 다른 것만으로는 오버로딩 조건이 성립되지 않음
    • 와일드 카드 - ?
      • Object와 다를 것이 없음
      • 어떤 타입도 들어올 수 있음
      • 상한(upper bound)와 하한(lower bound)
        • 상한 제한
          • <? extends T>  
          • T와 그 자손들만 가능
        • 하한 제한
          • <? super T>
          • T와 그 조상들만 가능
      • <?> == <? extends Object>
  • 지네릭 메서드
    • 의미: 메서드의 선언부에 지네릭 타입이 선언된 메서드
    • 지네릭 클래스에 정의된 타입 매개변수 != 지네릭 메서드에 정의된 타입 매개변수
    • static 메서드에는 지네릭 사용 가능
  • 지네릭 타입의 형변환
    • 지네릭 타입과 넌지네릭 타입의 형변환 가능
    • 대입된 타입이 다른 지네릭 타입간에는 형변환 불가능
  • 지네릭 타입의 제거
    • 컴파일러는 지네릭 타입을 이용해서 소스파일을 체크하고, 필요한 곳에 형변환을 넣어 준 후 지네릭 타입을 제거
    • 컴파일된 파일(*.class)에는 지네릭 타입에 대한 정보가 없음
    • 이전의 소스 코드와의 호환성을 위해

-      열거형(enums)

  • 열거형이란
    • 타입의 안전한 열거형(typesafe enum)
      • C언어의 열겨형보다 향상된 기능을 가짐: 열거형이 갖는 값뿐만 아니라 타입까지 관리해서 논리적인 오류를 줄일 수 있음
      • 실제 값이 같아도 타입이 다르면 false
    • 사용 이유: 상수의 값이 바뀌면 해당 상수를 참조하는 모든 소스를 다시 컴파일해야하지만, 열거형 상수를 이용하면 기존의 소스를 다시 컴파일하지 않아도 됨
  • 열거형의 정의와 사용
    • 형식: enum 열거형이름 {  상수명1, 상수명2, ...  }
    • 사용 방법: 열거형이름.상수명
    • 열거형 상수간의 비교에는 '=='이 사용 가능  →  빠른 성능 제공
      • 단 비교 연산자 '>', '<'는 사용할 수 없음  →  compareTo() 사용
    • java.lang.Enum 클래스: 모든 열거형의 조상
      • values() 메서드: 통해 열거형의 모든 상수를 배열에 담아 반환
      • valueOf() 메서드: 열거형 상수의 이름으로 상수에 대한 참조를 얻을 수 있음
  • 열거형에 멤버 추가하기
    • Enum 클래스의 ordinal()이 상수가 정의된 순서를 알려주지만 사용하지 않는 것이 좋음
    • 열거형 상수 값이 불규칙한 경우  →  상수의 이름 옆에 원하는 값을 괄호()와 함께 적어주면 됨
      • 지정된 값을 저장할 수 있는 인스턴스 변수와 생성자 필요
      • 열거형의 생성자는 묵시적으로 private
      • 상수에 여러 값을 지정 가능  →  그에 맞게 변수와 생성자 추가
    • 열거형에 추상 메서드 추가하기
      • 추상 메서드를 선언하면 각 열거형 함수가 이 추상 메서드를 구현해야함
  • 열거형의 이해
    • 열거형 상수 각각 열거형의 객체
    • 열거형 상수의 값은 객체의 주소이고, 이 값이 바뀌지 않는 값이므로 '=='으로 비교가 가능한 것
    • 그래서 추상 메서드를 추가하면, 각 객체마다 구현해줘야하는 것

-      애너테이션(annotation)

  • 애너테이션이란
    • 의미: 프로그램의 소스코드 안에 다른 프로그램을 위한 정보를 미리 약속된 형식으로 포함 시킨 것
    • JDK에서 제공하는 표준 애너테이션은 주로 컴파일러를 위해 정보를 제공하는 역할
    • 메타 애너테이션: 새로운 애너테이션을 정의할 때 사용
  • 표준 애너테이션
    • 애너테이션 종류 (메타 애너테이션 제외)
      1. @Override: 컴파일러에게 오버라이딩이라는 것을 알림
      2. @Deprecated: 앞으로 사용하지 않을 것을 권고
      3. @SupperessWaring: 컴파일러의 특정 경고 메세지가 나타나지 않게 설정
      4. @SafeVarags: 지네릭스 타입의 가변인자에 사용
      5. @FuntionalInterface: 함수형 인터페이스라는 것을 알림
      6. @Native: native 메서드에서 참조되는 상수 앞에 붙임
  • 메타 애너테이션
    • 애너테이션을 위한 애너테이션
      • 애너테이션에 붙이는 애너테이션
      • 애너테이션을 정의할 때 사용
    • 종류
      1. @Target: 애너테이션에 적용 가능한 대상을 지정하는데 사용
      2. @Document: 애너테이션 정보가 java.doc으로 작성된 문서에 포함되도록 함
      3. @Inherited: 애너테이션이 자손 클래스에 상속되도록 함
      4. @Retention: 애너테이션이 유지되는 범위를 지정하는데 사용
      5. @Repeatable: 애너테이션을 반복해서 적용할 수 있게함
  • 애너테이션의 타입 정의하기
    • 인터페이스 정의법 + '@' 기호를 붙이기
    • 애너테이션의 요소: 애너테이션 내에 선언된 메서드
      • 반환값 존재 + 매개변수는 없는 추상 메서드의 형태
      • 상속을 통해 구현하지 않아도 됨
      • 단, 애너테이션을 적용할 때 값을 입력해줘야함
      • 각 요소들은 기본값을 가질 수 있으며, 기본값을 가진 요소는 입력 값이 없을 때 사용
      • 요소가 하나인 경우: 요소의 이름 생략 가능
      • 요소의 타입이 배열인 경우: 괄호{}를 사용해서 여러 개의 값을 지정
    • java.lang.annotation.Annotation: 모든 애너테이션의 조상
      • 애너테이션은 상속을 허용하지 않으므로 조상으로 지정할 수 없음
    • 마커 애너테이션
      • 값을 지정할 필요가 없는 경우, 애너테이션의 요소를 하나도 지정하지 않을 수 있음
      • 요소가 하나도 정의되어 있지 않은 애너테이션을 의미
    • 애너테이션 요소의 규칙
      1. 요소의 타입은 기본형, String, enum, 애너테이션, Class만 허용
      2. ()안에 매개변수를 선언할 수 없음
      3. 예외를 선언할 수 없음
      4. 요소를 타입 매개변수로 정의할 수 없음