티스토리 뷰

반응형

 C++을 1년정도 하다가 최근에 자바를 배우기 시작했는데 C++보다 편한점이 많은 듯 하면서 은근 불편하고 그런 것들이 있더라고요. 그 중 하나가 enum 사용방식인 것 같습니다. 

 

 먼저 흔히 알고 있는 C++에서의 enum 사용법은 

enum YearFlag
{
    NOT_LEAP_YEAR,
    LEAP_YEAR
};

 

 기본적으로 이렇게 쓰는데

 

enum YearFlag
{
    NOT_LEAP_YEAR = 1,
    LEAP_YEAR
};

 

 이렇게 쓰면 알아서 1, 2, ... 이런 식으로 숫자 번호가 부여되고 그랬습니다. 그래서 상수값에 이름을 붙여주고 싶을 때 간편하게 사용할 수 있었습니다.(알고리즘 문제 풀 때 굉장히 애용하던 기능) C#에서도 비슷하게 사용할 수 있길래 자바에서도 그럴 줄 알았거든요 처음에는?

 

 하지만 자바에서는

enum YearFlag
{
	NOT_LEAP_YEAR,
	LEAP_YEAR
}

 

 여기까지는 되는데

 

enum YearFlag
{
	NOT_LEAP_YEAR = 1, //불가능!
	LEAP_YEAR
}

 

 이렇게 쓰는 것이 가능하지 않았습니다. (이클립스가 빨간줄 보여줌...)

 

enum YearFlag
{
	NOT_LEAP_YEAR(0),
	LEAP_YEAR(1); //세미콜론 필수!
	
	private final int value;
	YearFlag(int value) { this.value = value; }
	public int getValue() { return value; }
}

 

 자바에서 enum을 사용할 때 특정 상수 혹은 문자값에 이름을 붙여주고 싶으면 위와 같이 괄호 안에 쓴 다음 맨 마지막 열거자 뒤엔 세미콜론 ; 을 붙여줘야 했습니다. 그리고 저기서 끝나는 것이 아니고 다음 구문과 같이 특정 값을 저장할 수 있는 인스턴스를 만들 수 있는 변수와 생성자를 하나 선언한 다음에 그걸 리턴해주는 함수도 같이 써야 하더라고용...

 좀 귀찮.... 그냥 코드에 0이랑 1로만 써 놓으면 가독성이 떨어져서 가독성 좀 높일려고 enum을 쓰려는건데 이렇게까지 해야하다니...ㅎ

 

 그리고 저걸 그대로 쓰면 상수값 0과 1을 출력해 주는 것이 아니고 열거자 이름 자체가 그대로 출력이 되어서... 또 불편했습니다.....

import java.util.*;

enum YearFlag
{
	NOT_LEAP_YEAR(0),
	LEAP_YEAR(1);
	
	private final int value;
	YearFlag(int value) { this.value = value; }
	public int getValue() { return value; }
}

public class Main {

	public static void main(String[] args) {

		Scanner s = new Scanner(System.in);
		
		int year = s.nextInt();
		YearFlag y = YearFlag.LEAP_YEAR;
		
		if (0 == year % 4)
		{
			if (0 != year % 100 || 0 == year % 400)
				y = YearFlag.LEAP_YEAR;
			else 
				y = YearFlag.NOT_LEAP_YEAR;
		}
		else 
			y = YearFlag.NOT_LEAP_YEAR;
		
		System.out.println(y);

	}

}

 

 대충 이런식으로 주어진 해가 윤년인지 아닌지 구분하는 코드를 작성한다면 원하는 답은 윤년일 때 1, 아닐 때 0을 출력하는 것인데 이 코드는 

 

 열거자 이름을 그대로 출력하더라고요. 약간 좀... 1이 출력되길 바랬는데... C++ 하다 오신 분들은 제가 무슨 출력을 바랬는지 아실거라 생각합니다... 

 

 그래서 원래 의도대로 0과 1을 출력하고 싶으면 아래처럼 ordinal()이라는 메소드를 사용하면 되는데 

import java.util.*;

enum YearFlag
{
	NOT_LEAP_YEAR(0),
	LEAP_YEAR(1);
	
	private final int value;
	YearFlag(int value) { this.value = value; }
	public int getValue() { return value; }
}

public class Main {

	public static void main(String[] args) {

		Scanner s = new Scanner(System.in);
		
		int year = s.nextInt();
		
		int answer = YearFlag.NOT_LEAP_YEAR.ordinal();
		if (0 == year % 4)
		{
			if (0 != year % 100 || 0 == year % 400)
				answer = YearFlag.LEAP_YEAR.ordinal();
			else 
				answer = YearFlag.NOT_LEAP_YEAR.ordinal();
		}
		else 
			answer = YearFlag.NOT_LEAP_YEAR.ordinal();
		
		System.out.println(answer);

	}

}

 

 

 중요한 점은 ordinal() 메소드 자체의 반환값은 int지만 단순히 열거자들의 나열 순서를 리턴하는 것 뿐 열거자에 저장된 값을 리턴하는 것은 아니라는 것입니다. 상당히 제한된 형태로만 사용할 수 있겠다는 생각이 드네욤...ㅠ 

 

 

* 상수 사용을 C++랑 비슷하게 쓰려면 const 키워드를 쓰지 않고 

import java.util.*;

public class Main {
	
	final static int LEAP_YEAR = 1;
	final static int NOT_LEAP_YEAR = 0;

	public static void main(String[] args) {

		Scanner s = new Scanner(System.in);
		
		int year = s.nextInt();
		
		int answer = NOT_LEAP_YEAR;
		if (0 == year % 4)
		{
			if (0 != year % 100 || 0 == year % 400)
				answer = LEAP_YEAR;
			else 
				answer = NOT_LEAP_YEAR;
		}
		else 
			answer = NOT_LEAP_YEAR;
		
		System.out.println(answer);

	}

}

 

 위와 같이 finalstatic 키워드를 사용해서 메인 함수의 바깥에 선언하거나 final 키워드만 사용해서 메인 함수 내부에 선언하거나 인 것 같습니다. 


 자바에서 처음에 스캐너 메소드를 썼을 땐 진짜 편하다는 생각이 들었는데 enum은 또 그렇지도 않아서 역시 뭐든 장단점이 있다는 생각이 듭니다. 아직 자바 초보 단계라 더 많은 기능을 제가 몰라서 이 정도로밖에 못 쓴 것이겠지만 C/C++에 비해서는 약간 포장된 단계가 있다는 느낌을 많이 받고 있습니다. 자바를 좀 더 배워가면서 더 좋은 기능을 알게 되면 관련글을 또 쓰도록 하겠습니다. 

 

여기까지 봐 주셔서 감사합니다!

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함