JAN's History

자바의정석 CH 12 - 2 열거 본문

자바

자바의정석 CH 12 - 2 열거

JANNNNNN 2023. 4. 23. 13:50

2. 열거형

- 관련된 상수들을 같이 묶어 놓은 것. Java는 타입에 안전한 열거형을 제공

값은 0으로 같지만 타입이 다르기 때문에 비교할 수 없다.

=> 자바의 열거형은 값&타입 모두 체크한다.

- 열거형 정의하는 방법. 상수값이 0 1 2 3.. 씩 부여된다.

- 열거형 타입의 변수를 선언하고 사용하는 방법

dir에는 4가지 값 중 하나만 들어올 수 있다.

- 열거형 상수의 비교에 ==와 compareTo() 사용가능

compareTo는 같으면 0, 왼쪽이 더 크면 양수, 오른쪽이 더 크면 음수

- 모든 열거형은 Enum의 자손이며, 위의 메서드를 상속받는다.

- values(), valueOf()는 컴파일러가 자동으로 추가해준다.

values() : 열거형의 모든 상수를 배열로 반환한다.

valueOf 는 valudOf("WEST")<-열거형 상수 이름으로 사용할 수 있다. 

=> 즉, 문자열의 이름으로 열거형 상수를 사용할 수 있다.

=>ordinal은 상수 값이 아니라 상수 값의 순서라는 점!

2-1 열거형에 멤버 추가하기

- 불연속적인 열거형 상수의 경우, 원하는 값을 괄호()안에 적는다.

순서는 0 1 2 3..

- 괄호()를 사용하려면, 인스턴스 변수와 생성자를 새로 추가해 줘야 한다.

괄호() 값의 개수 만큼 iv를 선언해줘야하고 그 값을 받을 생성자도 추가해야한다.

=> 참고로 Direction 앞에는 private이 생략된 것, 생성자는 항상 private이 생략되어 있다.

- 열거형의 생성자는 묵시적으로 private으로 외부에서 객체 생성이 불가능하다.

+public int getValue() {return value;}

+ public String getSymbol() {return symbol;}

+ of : 0~3 범위를 벗어나면 예외를 발생하게 했고, 벗어나지 않으면 -1를 반환하도록 메서드 생성

여기선 값 2개를 받기 때문에 int와 String 객체를 모두 받는 iv를 선언한 것.

Direction의 값을 배열로 저장.

values는 열거형이 가지고 있는 모든 상수를 반환한다. getvalue로 값을 찍어낸 것.

d1에는 EAST를 저장하고 d2에는 1이 저장되어 1-1= 0으로 d2 = 0인 EAST가 들어간다.

rotate는 시계방향으로 원으로 회전하는 것. 동서남북으로 회전해야하기 때문에 num을 4로 나눈 것

=>5를 넣으면 5를 4로 나눴을 때 나머지는 1이니까 1번 회전

음수일 때는 시계반대방향으로 회전

=>시계방향으로 3번 도는 것과 같다.

3. 애너테이션

-주석처럼 프로그래밍 언어에 영향을 끼치지 않으며 유용한 정보를 제공

=> 원래는 자바가 소스코드와 소스코드에 대한 설명이 따로 존재했는데 이제는 저렇게 하나로 합쳐진 것.

- 에너테이션 사용 예시

=> JUnit에게 테스트하겠다는 뜻.

- 자바에서 제공하는 애너테이션

3-2 @Override

- 오버라이딩을 올바르게 했는지 컴파일러가 체크하게 한다.

- 오버라이딩 할 때 메서드 이름을 잘못적는 실수를 하는 경우가 많다.

- 오버라이딩할 땐 메서드 앞에 습관적으로 @Override를 붙이자.

=> @Override하면 실수했는지 컴파일러가 알려준다.

@Deprecated

- 앞으로 사용하지 않을 것을 권장하는 필드나 메서드에 붙인다.

- @Deprecated의 사용 예, Date클래스의 getDate()

- @Deprecated가 붙은 대상이 사용된 코드를 컴파일하면 나타나는 메시

=> 경고로 표시. 에러는 아님

@Functionallnterface

함수형 인터페이스에 붙이면 컴파일러가 올바르게 작성했는지 체크

함수형 인터페이스에는 하나의 추상메서드만 가져야 한다는 제약이 있음

=> 1개의 함수형 인터페이스에 2개의 메서드가 있어서 에러

@SuppressWarnings

- 컴파일러의 경고메시지가 나타나지 않게 억제한다.

- 괄호()안에 억제하고자 하는 경고의 종류를 문자열로 지정

=> 이 경고는 내가 확인했다는 의미로 붙이는 것

- 둘 이상의 경고를 동시에 억제하려면 다음과 같이 한다.

3-2 메타 애너테이션

- 메타 애너테이션은 "애너테이션을 위한 애너테이션"이다.

- 애너테이션을 정의할 떄, 적용 대상이나 유지기간의 지정에 사용된다.

@Target

- 애너테이션을 정의할 때, 적용대상 지정에 사용된다.

=> 애너테이션을 붙일 수 있는 것은 FIELD와 TYPE, TYPE_USE이기 때문에 클래스와 iv, cv와 타입이 사용되는 모든 곳에 붙일 수 있는 것이다.

@Retention

-애너테이션이 유지되는 기간을 지정하는데 사용

=>Source와 RUNTIME만 기억하자

- 컴파일러에 의해 사용되는 애터테이션의 유지정책은 SOURCE이다.

- 실행시에 사용가능한 애너테이션의 정책은 RUNTIME이다.

@Documented, Inherited

-javadoc으로 작성한 문서에 포함시키려면 @Documented를 붙인다.

=> 사용할 일 많이 X

- 애터테이션을 자손 클래스에 상속하고자 할 떄 @Inherited를 붙인다.

@Repeatable

- 반복해서 붙일 수 있는 애너테이션을 정의할 때 사용

-@Repeatable이 붙은 애너테이션을 반복해서 붙일 수 있따.

-@Repeatable인 @ToDo를 하나로 묶을 컨테이너 애너테이션도 정의해야함

 

- 애너테이션을 직접 만들어 쓸 수 있다.

@interface 애너테이션이름을 하고 안에 추상메서드를 선언하면 됨

- 애너테이션의 메서드는 추상 메서드이며, 애너테이션을 적용할 때 지정한다(순서X)

사용할 때엔 구현할 필요 없이 @TestInfo ()안에 애너테이션을 사용해주면 된다.

+ enum은 열거형 선언하는 방법

3-3 애너테이션의 요소

- 적용 시 값을 지정하지 않으면, 사용될 수 있는 기본값 지정 가능(null제외)

- 요소가 하나이고 이름이 value일 땐 요소 이름 생략 가능

- 요소 타입이 배열인 경우 괄호{}을 사용해야한다.

=> 값이 없을 때엔 괄호가 반드시 필요 !!

- Annotation은 모든 애너테이션의 조상이지만 상속은 불가

- 사실 Annotation은 인터페이스이다.

=> 모든 애너테이션의 조상은 Annotation이라는 인터페이스이고 이러한 추상메서드를 가지고 있다. 

이 추상메서드들은 구현할 필욘 없지만 컴파일러가 알아서 구현해주기 때문에 사용가능하다.

마커 애너테이션

- 요소가 하나도 정의되지 않은 애너테이션

=> 그냥 이름만 알아두자.

=> 요소가 하나도 없으니 정의할 필요가 없다.

3-4 애너테이션 요소의 규칙

- 애너테이션의 요소를 선언할 때 아래의 규칙을 반드시 지켜야 한다.

  • 요소 타입은 기본형, String, enum, 애너테이션, Class(=설계도 객체)만 허용된다.
  • 괄호()안에 매개변수를 선언할 수 없다. 즉, 추상메서드만 가
  • 예외를 선언할 수 없다.
  • 요소를 타입 매개변수로 정의할 수 없다. ex)지네릭 타입 <T>

=> 즉, 추상메서드만 사용 가능하다고 생각하자.

@TestInfo를 class에 정의했다.

@interface안에는 defalut 값은 정의할 수 있다. 즉, defalut는 @TestInfo에서 값을 굳이 지정 안해도 된다. 덮어쓰기 가능

Class<Ex12_8> cls = Ex12_8 class;를 cls로 부르게 하고

TestInfo anno = cls.getAnnotation(TestInfo.class);로 TestInfo를 구현한 class를 anno라고 부르게 한다.

=>getAnnotaion이란 메서드는 클래스에 붙은 애너테이션을 읽어올 수 있다.

그러면 anno 안에 있는 TestInfo의 객체들을 사용할 수 있다.

testDate안에 있는 객체는 .으로 연결해서 사용

+ 향상된 for문 : anno.testTools를 str에 계속 찍는다. 그리고 sysout와 함께!

 

annoArr에 cls에 모든 애너테이션을 불러오도록 한다.

그리고 Annotation의 a로 프린트를 모두 찍으면 생성된 객체들이 모두 print된다.