22.01.05(수)
본 글은, 스스로 학습한것을 소화하기 위한 목적으로 작성중이므로 피드백 적극환영합니다.🐵
- Enum 클래스
이유 : 몇번 공부하면서 봤지만, 제대로 소화하지 못해서 금일 알고리즘 풀때 활용하지 못했다!
Enum 클래스는 열거체(Enumeration Type)로, 서로 연관되거나 관련이 있는 상수들의 집합을 의미한다. 모든 JDK에서 사용 불가하며, JDK 1.5버전
이상부터 사용 가능하다. Q. 그럼 JDK 1.5버전 이전에는??
public class BeforeExample {
public static void main(String[] args) {
/*
* black = 0
* brown = 1
* red = 2
* orange = 3
* yellow = 4
* green = 5
* blue = 6
* violet = 7
* grey = 8
* white = 9
*/
int color = 0;
switch (color) {
case 0:
System.out.println("색은 black입니다.");
break;
case 1:
System.out.println("색은 brown입니다.");
break;
case 2:
System.out.println("색은 red입니다.");
break;
/* 이하 생략 */
}
}
}
위 코드에서는 상수값과 그에 해당하는 의미를 주석으로 처리하고 있다. 짧은 코드에서는 크게 상관없을수도 있지만 만약, 상수를 사용하는
Switch-Case
문과 주석 사이에 1000줄의 코드가 있다면 상수의 의미를 한번에 이해하기가 어려울 것이다.
public class beforeExample {
private final static int black = 0;
private final static int brown = 1;
private final static int red = 2;
private final static int orange = 3;
private final static int yellow = 4;
private final static int green = 5;
private final static int blue = 6;
private final static int violet = 7;
private final static int grey = 8;
private final static int white = 9;
public static void main(String[] args) {
int color = black;
switch (color) {
case black:
System.out.println("색은 black입니다.");
break;
case brown:
System.out.println("색은 brown입니다.");
break;
case red:
System.out.println("색은 red입니다.");
break;
/* 이하 생략 */
}
}
}
1번 예제에서 주석과 상수 구현 함수가 함께 있지 않을때 파악이 어렵다면, 위 예제처럼
final static
을 사용하여 메모리에 한번만 할당되게 설정하여 한눈에 볼 수 있게 할 수 있다. 하지만 이런 경우에도 상수가 필요할때마다 추가하게되면 상수가 많아지게 되는데, 이 또한 각 상수들이 나열만 되어 있기 때문에 각각 어떤것과 연관되어 있는지 한눈에 파악이 어렵다.
추가적으로 만약 서로 다른 상수의 집합에서 같은 이름으로 정의된 상수가 존재한다면, 중복된 이름으로 인해 컴파일 단계에서 오류가 발생한다. 이를 방지하기 위해
class
나interface
를 활용하여 서로 다른 집합의 상수들 끼리 정의하여 중복된 이름이 있어도 오류가 발생하지 않게 방지할 수 있다.
interface COLOR {
int BLACK = 0;
int BROWN = 1;
int RED = 2;
int ORANGE = 3;
int YELLOW = 4;
int GREEN = 5;
int BLUE = 6;
int VIOLET = 7;
int GREY = 8;
int WHITE = 9;
}
interface BRUSHCOLOR {
int BLACK = 0;
int BROWN = 1;
int GREY = 2;
}
public class BeforeExample {
public static void main(String[] args) {
int color = COLOR.BLACK;
if (COLOR.BLACK == BRUSHCOLOR.BLACK) {
System.out.println("두 상수는 같다.");
}
switch (color) {
case 0:
System.out.println("색은 black입니다.");
break;
case 1:
System.out.println("색은 brown입니다.");
break;
case 2:
System.out.println("색은 red입니다.");
break;
/* 이하 생략 */
}
}
}
위처럼
interface
내에서 선언된 변수는public static final
속성을 생략할 수 있는 특징을 활용하여 코드를 보다 간결하게 리팩토링 할 수 있다. 하지만 만약 서로 다른 집합의 상수를 비교하면 컴파일 단계에서 에러가 안뜨고 런타임 단계에서 문제가 발생할 수도 있다고 한다.ex) COLOR.BLACK == BRUSHCOLOR.BLACK
(이유는 아직..모르겠다. 인텔리제이에서는 잘되는것 같은데..??🌪 인지해두고 다시 찾아보자)
class Color {
public final static Color BLACK = new Color();
public final static Color BROWN = new Color();
public final static Color RED = new Color();
public final static Color ORANGE = new Color();
public final static Color YELLOW = new Color();
public final static Color GREEN = new Color();
public final static Color BLUE = new Color();
public final static Color VIOLET = new Color();
public final static Color GREY = new Color();
public final static Color WHITE = new Color();
}
class BrushColor {
public final static BrushColor BLACK = new BrushColor();
public final static BrushColor BROWN = new BrushColor();
public final static BrushColor GREY = new BrushColor();
}
public class BeforeExample {
public static void main(String[] args) {
Color color = Color.BLACK;
if (Color.BLACK == BrushColor.BLACK) {
System.out.println("두 상수는 같다.");
}
switch (color) {
case Color.BLACK:
System.out.println("색은 black입니다.");
break;
case Color.BROWN:
System.out.println("색은 brown입니다.");
break;
case Color.RED:
System.out.println("색은 red입니다.");
break;
/* 이하 생략 */
}
}
}
각 클래스별로 상수를 집합시키고, 각각의 상수들의 타입은 자신의 상수 집합의 이름으로 셋팅하였다. 값은 자기 자신을 인스턴스화 하여 할당하였다. 같은 집합의 상수들은 같은 데이터 타입을 갖지만 각각 의 상수들은 서로 다른 데이터 값을 갖게 된다. 그러므로 컴파일 단계에서 두 상수를 비교하는 if문에서 에러가 발생한다.(서로 다른 데이터 타입은 비교할 수 없다는 내용의 오류)
3번의 예제와 비슷하지만 컴파일 단계에서 오류를 검거하여 예기치 못한 에러를 사전에 차단할 수 있다.
enum Color {
BLACK, BROWN, RED, ORANGE, YELLOW, GREEN, BLUE, VIOLET, GREY, WHITE;
}
enum BrushColor {
BLACK, BROWN, GREY;
}
public class BeforeExample {
public static void main(String[] args) {
Color color = Color.BLACK;
switch (color) {
case BLACK:
System.out.println("색은 black입니다.");
break;
case BROWN:
System.out.println("색은 brown입니다.");
break;
case RED:
System.out.println("색은 red입니다.");
break;
/* 이하 생략 */
}
}
}
A-4번의 예제를 Enum을 활용하여 바꿨을때 몇가지 장점이 있다.
(이외에 Enum 클래스의 다양한 메소드가 있지만, 그런 메소드들은 쓰면서 외워봐야겠다.)
1. 열거체를 비교할때, 실제 값 뿐만 아니라 타입까지도 체크할 수 있다.
2. 열거체의 상수값이 재정의되더라도 다시 컴파일할 필요가 없다.
3. 인스턴스 생성과 상속을 방지한다.
4. 구현의 의도가 열거임을 분명하게 보는이에게 전달 할 수있다.
참고내용 :
http://www.tcpschool.com/java/java_api_enum
https://www.nextree.co.kr/p11686/
https://techblog.woowahan.com/2527/
https://jojoldu.tistory.com/412