티스토리 뷰
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);
}
}
위와 같이 final과 static 키워드를 사용해서 메인 함수의 바깥에 선언하거나 final 키워드만 사용해서 메인 함수 내부에 선언하거나 인 것 같습니다.
자바에서 처음에 스캐너 메소드를 썼을 땐 진짜 편하다는 생각이 들었는데 enum은 또 그렇지도 않아서 역시 뭐든 장단점이 있다는 생각이 듭니다. 아직 자바 초보 단계라 더 많은 기능을 제가 몰라서 이 정도로밖에 못 쓴 것이겠지만 C/C++에 비해서는 약간 포장된 단계가 있다는 느낌을 많이 받고 있습니다. 자바를 좀 더 배워가면서 더 좋은 기능을 알게 되면 관련글을 또 쓰도록 하겠습니다.
여기까지 봐 주셔서 감사합니다!
- Total
- Today
- Yesterday
- 애플
- greedy
- 캐나다생활
- 하드웨어
- 알고리즘
- 문제풀이
- 스위프트플레이그라운드
- DFS
- 컴퓨터사이언스
- BFS
- 해커랭크
- c언어
- 아이패드
- 캐나다
- c++
- 기초
- 컴퓨터공부
- 프로그래머스
- 깊이우선탐색
- 그리디
- 백준
- 다이나믹프로그래밍
- 영어공부
- C언어기초
- 프로그래밍
- dp
- 코딩공부
- 너비우선탐색
- hackerrank
- 컴퓨터
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |