상수는 변하지 않는 값이다. 변수도 상수가 될 수 있다. 변수를 지정하고, 그 변수를 final
로 처리하면 한번 설정된 변수의 값은 더 이상 바뀌지 않는다. 또한 바뀌지 않는 값은 인스턴스 변수가 아닌 클래스 변수(static)으로 지정하는 것이 더 좋다.
private final static int peachCrush = 1;
private final static int rum = 2;
private final static int soju = 3;
다음의 코드를 살펴보자.
package practice;
public class ConstantDemo {
// fruit
private final static int Stock_peachCrush = 1;
private final static int Stock_rum = 2;
private final static int Stock_soju = 3;
// company
private final static int Sales_Acompany = 1;
private final static int Sales_soju = 2;
private final static int Sales_Ccompany = 3;
public static void main(String[] args) {
int type = Stock_peachCrush;
switch(type){
case Stock_peachCrush:
System.out.println(57+" kcal");
break;
case Stock_rum:
System.out.println(34+" kcal");
break;
case Stock_soju:
System.out.println(93+" kcal");
break;
}
}
}
private final static int Stock_soju = 3;
코드와 private final static int Sales_soju = 2;
코드를 보자. 앞에 접두사Stock_
과 Sales_
를 붙이지 않았더라면 soju
의 값이 3에서 2로 바뀐다. 그렇지만 final
로 선언했기에 이름 중복 문제는 방지할 수 있다.
인터페이스를 활용하여 위의 코드를 정리해보자.
package practice;
interface Stock {
int peachCrush = 1, rum = 2, soju = 3;
}
interface Sales {
int Acompany = 1, soju = 2, Ccompany = 3;
}
public class ConstantDemo {
public static void main(String[] args) {
int type = Sales.soju;
switch(type){
case Stock.peachCrush:
System.out.println(57+" kcal");
break;
case Stock.rum:
System.out.println(34+" kcal");
break;
case Stock.soju:
System.out.println(93+" kcal");
break;
}
}
}
위의 코드처럼 인터페이스를 이용하니 깔끔하게 구분되는 것을 볼 수 있다. 인터페이스를 사용할 수 있는 이유는 무엇일까? 인터페이스에서 선언된 변수는 무조건 public static final
의 속성을 갖기 때문이다.
그러나 위의 코드에서 int type = Stock.soju;
를 int type = Sales.soju;
로 바꾸면 34kacl로 출력된다. 컴파일러가 오류를 이상함을 감지하지 못하고 출력하고 있는 것이다.
enum은 열거형(enuerated type)이라고 부른다. 열거형은 서로 연관된 상수들의 집합이다. 즉 위의 Stock과 Sales가 열거인 셈이다. enum을 이용해서 코드를 수정해보자.
package practice;
enum Stock {
peachCrush, rum, soju;
}
enum Sales {
Acompany, soju, Ccompany;
}
public class ConstantDemo {
public static void main(String[] args) {
Stock type = Stock.soju;
switch(type){
case peachCrush:
System.out.println(57+" kcal");
break;
case rum:
System.out.println(34+" kcal");
break;
case soju:
System.out.println(93+" kcal");
break;
}
}
}
enum은 class, interface와 동급의 형식을 가진다. 사실상 class와 같다. 단지 enum만의 문법적 형식을 가지고 있는 것이다.
사실상 아래의 두 코드는 같은 코드이다.
// 1. enum 이용하기
enum Stock {
peachCrush, rum, soju;
}
// 2. class 이용하기
class Stock{
public static final Stock peachCrush = new Stock();
public static final Stock rum = new Stock();
public static final Stock soju = new Stock();
private Stock(){}
}
class를 이용한 코드에서 private Stock(){}
코드를 보자. 생성자의 접근자가 private이다. 이는 클래스 Stock을 인스턴스로 만들 수 없음을 의미한다. 즉, 다른 용도로 사용하는 것을 금지하고 있는 것이다.
- 코드가 단순해짐
- 인스턴스 생성, 상속을 방지함
- 키워드 enum을 사용함 → 구현의 의도가 열거임을 분명하게 나타낼 수 있음
- 연관된 값들을 저장함
- 값들이 변경되지 않도록 보장함
- enum은 클래스와 같기에 내부에 생성자, 필드, 메소드를 가질 수 있음
Reference
1. 상수와 enum