본문 바로가기
JAVA/이재환의 자바 프로그래밍 입문

[Java] Ch.18 열거형, 가변 인수, 어노테이션

by ♡˖GYURI˖♡ 2023. 10. 23.

열거형

서로 관련 있는 상수들을 모아 놓고 대표할 수 있는 이름을 정의한 것

자바에서 열거형은 클래스처럼 사용됨

enum 이름 {
	// 요소 나열
}

 

 

final 상수를 사용했을 때 모호함

옛날 st

interface MyNum
{
    int SPRING = 0;
    int SUMMER = 1;
    int FALL = 2;
    int WINTER = 3;
    
    int DO = 0;
    int RE = 1;
    int MI = 2;
    int FA = 4;
    int SOL = 5;
    int RA = 6;
    int SI = 7;
}

인터페이스에 사용된 변수는 앞에 public static final이 생략됨

위 코드에서 SPRING과 DO는 같은 값을 가지고 있기에 잘못 사용하면 의미 전달에 있어 모호함이 나타날 수 있음

 

모호한 경우 예제

interface Human1 {
   // public static final이 생략된 final 상수
   int MAN = 1;  
   int WOMAN = 2; 
}

interface Machine1 {
   int TANK = 1;
   int AIRPLANE = 2;
}

public class Ex01_Constants
{
    public static void main(String[] args)
    {
        createUnit(Machine1.TANK);

        createUnit(Human1.MAN); // 잘못된 상수 사용
    }

    public static void createUnit(int kind) {
        switch(kind) {
        case Machine1.TANK:
            System.out.println("탱크를 만듭니다.");
            break;
        case Machine1.AIRPLANE:
            System.out.println("비행기를 만듭니다.");
            break;
        }
    }
}

//컴파일 및 실행 과정에서 발견되지 않는 오류

하지만 에러가 발생하지 않음 → 둘 다 숫자 1로 판정되었기 때문

 

 

열거형으로 모호함 피하기

상수를 사용했을 때 이런 의미의 모호함을 해결하는 데 열거형을 사용함

열거형은 내부적으로는 상수처럼 0부터 시작하는 값을 가지지만, 클래스처럼 사용되기 때문에 앞과 같은 코드를 작성했을 때 에러가 발생하게 됨

enum Human2 { MAN, WOMAN }

enum Machine2 { TANK, AIRPLANE }

public class Ex02_Enum
{
    public static void main(String[] args)
    {
    	createUnit(Machine2.TANK);

//      createUnit(Human2.DOG); // 잘못된 상수 사용 : 에러

        // 참고 : C처럼 숫자로 비교하면 에러가 난다.
//    	if (Human2.MAN == 0) {
//    		
//    	}
    }

    public static void createUnit(Machine2 kind) {
        switch(kind) {
        case TANK:
            System.out.println("탱크를 만듭니다.");
            break;
        case AIRPLANE:
            System.out.println("비행기를 만듭니다.");
            break;
        }
    }
}

//컴파일 및 실행 과정에서 발견되지 않는 오류

 

열거형 값도 내부적으로는 0부터 값을 가지고 자동으로 증가하지만, 값으로 바로 비교하지는 않음

Human2.MAN == 0 처럼 비교하면 클래스와 기본 자료형을 비교한 것이기 때문에 에러가 발생함

 

열거형은 클래스 안쪽에 정의할 수도 있음

클래스 안쪽에 정의를 하면 해당 클래스에서만 사용할 수 있음

class Customer {
	enum Gender {MALE, FEMALE}
    
    public Gender gen;
    
    public String toString() {
    	if (gen == GENDER.MALE)
        	return "Thank you, Mr " + name;
        else
        	return "Thank you, Mrs " + name;
    }
}

 

 

가변 인수(Variable Length Argument)

메서드 인수 개수가 가변적인 것

가변 인수에는 다음과 같이 말줄임표 ... 를 붙임

PrintStream printf(String format, Object ... args)

 

가변 인수가 아닌 인수와 함께 사용할 때는 가변 인수 매개변수가 항상 마지막에 와야 함

myMethod(int a, int b, int ... v)

 

가변 인수 선언에 대한 컴파일러의 처리는 컴파일러가 다음과 같이 배열 기반 코드로 수정해 처리하게 됨

// 가변인수
public static void helloEverybody(String...vargs) {...}

public static void main(String[] args)
{
	helloEverybody("홍길동");
    helloEverybody("홍길동", "전우치");
    helloEverybody("홍길동", "전우치", "손오공");
}
// 배열
public static void helloEverybody(String[] vargs) {...}

public static void main(String[] args)
{
	helloEverybody(new String[]{"홍길동"});
    helloEverybody(new String[]{"홍길동", "전우치"});
    helloEverybody(new String[]{"홍길동", "전우치", "손오공"});
}

 

public class Ex03_Varargs
{
    public static void helloEverybody(String... vargs) 
    {
        for (String s : vargs) 
            System.out.print(s + '\t');
        System.out.println();
    }

    public static void main(String[] args)
    {
        helloEverybody("홍길동");
        helloEverybody("홍길동", "전우치");
        helloEverybody("홍길동", "전우치", "손오공");
    }
}

for문을 이용하여 데이터를 하나씩 꺼내올 수 있음

vargs.length 멤버 변수도 사용할 수 있음

vargs[0]처럼 지정해서 특정 요소의 값을 가져올 수도 있음

 

 

어노테이션

  • 자바 어노테이션(annotation)은 자바 소스 코드에 추가하여 사용할 수 있는 메타 데이터의 일종
  • @ 기호를 앞에 붙여서 사용
  • 자바 5 이상에서 사용 가능

 

@Override

오버라이딩을 올바르게 했는지 컴파일러가 체크함

오버라이딩할 때 메서드명을 잘못 적는 실수를 하는 경우가 많은데 이런 점을 방지하는 데 사용됨

interface Unit4 
{
    public void move(String str);
}

class Human4 implements Unit4 
{
    @Override
    public void move(String str) 
    {
        System.out.println(str);
    }
}

public class Ex04_Override
{
    public static void main(String[] args)
    {
        Unit4 unit = new Human4();
        unit.move("인간형 유닛이 이동합니다.");
    }
}

 

 

@Deprecated

이 어노테이션이 적용된 메서드는 문제의 발생 소지가 있거나 개선된 기능의 다른 것으로 대체되어서 더 이상 필요 없게 되었음을 뜻함

아직은 호환성 유지를 위해 존재하지만, 이후에 사라질 수 있는 클래스 또는 메서드를 가리켜 Deprecated되었다고 함

interface Unit5 
{
    @Deprecated
    public void move(String str);
    public void run(String str);
}

class Human5 implements Unit5 
{
    @Override
    public void move(String str) 
    {
        System.out.println(str);
    }
    @Override
    public void run(String str) 
    {
        System.out.println(str);
    }
}

public class Ex05_Deprecated
{
    public static void main(String[] args)
    {
        Unit5 unit = new Human5();
        unit.move("인간형 유닛이 이동합니다.");
        unit.run("인간형 유닛이 달립니다.");
    }
}

[cmd]에서 'javac -encoding UTF-8' 명령으로 직접 컴파일하면 컴파일은 되었찌만 Deprecated된 메서드가 포함되어 있다는 메시지를 보여줌

 

 

@SuppressWarnings

자바의 버전업에 따른 Deprecated 메시지는 하위 호환성을 위해 메시지만 표시되고 실제로 메서드가 없어지지는 않음

하지만 Deprecated되었다는 경고는 계속 발생함

@Suppresswarnings 어노테이션에 deprecation 관련 경고 등 특정 메시지를 지정하면 해당 경고 메시지를 출력하지 말라는 의미임

interface Unit6 
{
    @Deprecated
    public void move(String str);
    public void run(String str);
}

class Human6 implements Unit6 
{
    @Override
    @SuppressWarnings("deprecation")
    public void move(String str) 
    {
        System.out.println(str);
    }
    @Override
    public void run(String str) 
    {
        System.out.println(str);
    }
}

public class Ex06_SuppressWarnings
{
    @SuppressWarnings("deprecation")
    public static void main(String[] args)
    {
        Unit6 unit = new Human6();
        unit.move("인간형 유닛이 이동합니다.");
        unit.run("인간형 유닛이 달립니다.");
    }
}