java [10] Enumeration, Annotation

lsy·2022년 10월 25일
0

자바

목록 보기
12/14

enums(열거형)

enums는 서로 관련된 상수를 편리하게 선언하기 위한 것으로, 여러 상수를 정의할 때 사용하면 유용하다. JDK1.5부터 추가되었다.

enums 정의와 사용

class Card {
	enum Kind { CLOVER, HEART, DIAMOND, SPADE }
    enum Value { TWO, THREE, FOUR }
    
    final Kind kind;
    final Value value;
}

enums를 위와 같이 선언하게 되면, 0부터 시작해서 차례대로 연속적인 값이 할당된다. enums를 선언했으면 다음과 같이 사용하면 된다.

System.out.println(kind.CLOVER);
System.out.println(kind.HEART);
System.out.println(value.TWO);

또한 enum의 중요한 특징은 값이 같아도 타입이 다르면 컴파일 에러가 발생한다는 점이다.

if(kind.CLOVER == kind.HEART) // false, 컴파일 OK
if(kind.CLOVER == value.TWO) // 의미상으론 true지만 컴파일 에러

만약 값을 저장하고 싶다면 다음과 같이 작성한다.

class Card {
	enum Kind { CLOVER(2), HEART(4), DIAMOND(6), SPADE(8) } // 2, 4, 6, 8
    enum Value { TWO(2), THREE(3), FOUR(4) } // 2, 3, 4
}

이후에 지정된 값을 저장할 수 있는 인스턴스 변수와 생성자를 새로 추가해 주어야 한다.

class Card {
	enum Kind { 
    	CLOVER(2), HEART(4), DIAMOND(6), SPADE(8);
        private final int value;
        
        Kind(int value) { this.value = value; }
        public int getValue() { return value; }
    }
    enum Value { 
    	TWO(2), THREE(3), FOUR(4) 
        private final int value;
        
        Value(int value) { this.value = value; }
        public int getValue() { return value; }
    }
}

필요하다면 하나의 상수에 여러 값을 지정할 수도 있다. 대신 그만큼 인스턴스 변수와 생성자를 새로 추가해주어야 한다.

enum Direction {
	EAST(1, ">"), SOUTH(2, "V"), WEST(3, "<"), NORTH(4, "^");
    
    private final int value;
    private final String symbol;
    
    Direction(int value, String symbol) {
    	this.value = value;
        this.symbol = symbol;
    }
    public int getValue() { return value; }
    public String getSymbol() { return symbol; }
}

enums의 구조

enums가 다음과 같이 정의되어 있을 때

enum Direction { EAST, SOUTH, WEST, NORTH }

enums 상수 하나하나가 Direction 객체다. 위 문장을 클래스로 정의하면 다음과 같다.

class Direction {
	static final Direction EAST = new Direction("EAST");
    static final Direction SOUTH = new Direction("SOUTH");
    static final Direction WEST = new Direction("WEST");
    static final Direction NORTH = new Direction("NORTH");
    
    private String name;
    private Direction(String name) {
    	this.name = name;
    }
}

static 상수 EAST, SOUTH, WEST, NORTH 값은 객체의 주소이고, 이 값은 바뀌지 않는 값(final)이므로 '=='로 비교가 가능한 것이다.

Annotation

어노테이션은 주석처럼 프로그래밍 언어에 영향을 미치지 않으면서 다른 프로그램 또는 프로그램 내에서 유용한 정보를 제공할 수 있는 방법이다.

@Override
public void print() {
	...
}

어노테이션은 표준 어노테이션메타 어노테이션으로 나뉘는데, 전자는 주로 컴파일러를 위한 것으로 컴파일러에게 유용한 정보를 제공하고 후자는 새로운 어노테이션을 정의할 때 사용한다.

표준 어노테이션의 종류

@Override 				// 컴파일러에게 오버라이딩하는 메서드라는 것을 알린다.
@Deprecated 			// 앞으로 사용하지 않을 것을 권장하는 대상에 붙인다.
@SuppressWarnings   	// 컴파일러의 특정 경고 메시지가 나타나지 않게 한다.
@SafeVarargs 			// 제네릭 타입의 가변인자에 사용한다. JDK1.7부터
@FuncionalInterface 	// 함수형 인터페이스라는 것을 알린다. JDK1.8부터
@Native 				// native메서드에서 참조되는 상수에 붙인다. JDK1.8부터

메타 어노테이션의 종류

@Target 				// 어노테이션이 적용가능한 대상을 지정하는데 사용한다.
@Documented 			// 어노테이션 정보가 javadoc으로 작성된 문서에 포함되게 한다.
@Inherited   			// 어노테이션이 자손 클래스에 상속되게 한다.
@Retention 				// 어노테이션이 유지되는 범위를 지정하는데 사용한다.
@Repeatable 			// 어노테이션을 반복해서 적용할 수 있게 한다. JDK 1.8부터

어노테이션 만들기

새로운 어노테이션을 정의하는 방법은 다음과 같다.

@interface 어노테이션이름 {
	타입 요소이름();
    ...
}

어노테이션의 요소는 다음과 같은 규칙을 지켜야 한다.

  • 요소의 타입은 기본형, String, enum, 어노테이션, class만 허용
  • ()안에 매개변수 선언 불가
  • 예외 선언 불가
  • 요소를 타입 매개변수(제네릭)로 정의할 수 없음
@interface TestInfo {
	int count();
    String testedBy();
    String[] testTools();
    TestType testType(); // enum TestType { FIRST, FINAL }
    DateTime testDate();
}
@interface DateTime {
	String yymmdd();
    String hhmmss();
}

어노테이션의 요소는 반환값이 있고 매개변수는 없는 추상 메서드의 형태를 가지며, 상속을 통해 구현하지 않아도 된다. 다만 어노테이션을 적용할 때 이 요소의 값을 빠짐없이 지정해주어야 한다.

@TestInfo(
	count = 3, testedBy="kim",
    testTools = {"JUnit", "AutoTester"},
    testType = TestType.First,
    testDate = @DateTime(yymmdd="160101", hhmmss="235959")
)
public class NewClass { ... }

어노테이션을 정의할 때 기본값을 설정할 수도 있다.

@interface TestInfo {
	int count() default 1; 				// 기본값 설정
    String testedBy() default "JUnit";	// 기본값 설정
    String[] testTools() default {"JUnit", "AutoTester"};
    TestType testType(); // enum TestType { FIRST, FINAL }
    DateTime testDate();
}
@interface DateTime {
	String yymmdd();
    String hhmmss();
}
// count = 1, testedBy = "JUnit", testTools = {"JUnit", "AutoTester"} 과 같음
@TestInfo(
    testType = TestType.First,
    testDate = @DateTime(yymmdd="160101", hhmmss="235959")
)
public class NewClass { ... }
profile
server를 공부하고 있습니다.

0개의 댓글