Inor

[JAVA] 상수(Constant, enum) 본문

Computer Engineering/Java

[JAVA] 상수(Constant, enum)

Inor 2017. 7. 27. 20:24

상수


 상수란 변수의 반대로 변하지 않는 값을 의미 합니다. 프로그램에서는 상수를 통해서 객체의 상태를 나타내기도 합니다. 자바는 아니지만 인턴을 하면서 Unity로 개발할 때 객체의 상태를 표현 하기도 했습니다. 객체의 상태(이동, 정지, 사망, 공격)를 정의하고 해당 객체가 그에 맞는 행동을 하도록 했습니다. 또한, 안드로이드를 개발할 때는 서버와의 통신을 할때 페이지 url, 페이지 파라미터(쿼리스트링) 등을 상수로 정의하여 사용 했습니다.




final static


 Unity에서는  C#에서 제공하는 enum(열거형)을 사용 했지만 안드로이드에서 상수를 사용 할때는 final static 키워드를 사용해서 상수를 정의 했습니다. 아래는 final static을 이용해서 상수를 정의하는 코드 입니다.

class Day {
	public final static int MONDAY = 0;
	public final static int TUESDAY = 1;
	public final static int WEDNESDDAY = 2;
	public final static int THURSDAY = 3;
	public final static int FRIDAY = 4;
	public final static int SATURDAY = 5;
	public final static int SUNDAY = 6;
}


 final static을 이용하면 간단하게 상수를 정의할 수 있습니다. final 키워드를 사용했기 때문에 수정도 불가능하고 static을 사용하기때문에 메모리에 한번만 적재 됩니다. 상수로서 충분히 기능을 하는 것 같습니다. 하지만 몇 가지 문제가 있습니다. 먼저 위와 같이 상수를 정의해서 사용하면 코드의 가독성이 떨어질 수 있습니다. 그리고 형에대한 안정성을 보장 받을 수 없습니다. 사실 가독성이란 좋은 코드의 기준이 되는 중요한 요소이지만 프로그램이 돌아가는데는 엄청 큰 문제가 되지 않습니다. (여기서는 프로그램의 실행 단계에서 가독성의 중요성이지 코드를 작성하는 단계에서의 중요성이 아닙니다. 사실상 제가 생각하는 좋은 코드의 기준들 중에도 많이 중요하게 생각하는 것이 가독성 입니다.) 하지만 형 안정성을 보장 받지 못하는 것은 컴파일 단계에서 발견하지 못한 오류가 실행 중에 발생 할 수 있습니다. 아래는 형 안정성에대한 문제가 발생 할 수 있는 코드 입니다.


class Diary{
	int today;
	
	public void setToday(int day){
		today = day;
	}
	
	public void showToday(){
		switch(today){
		case Day.MONDAY :
			System.out.println("월요일 입니다.");
			break;
		case Day.TUESDAY :
			System.out.println("화요일 입니다.");
			break;
		case Day.WEDNESDDAY :
			System.out.println("수요일 입니다.");
			break;
		}
	}
}


 showToady의 switch문을 보면 Day 클래스의 상수들을 Diary 클래스의 today 변수에서 사용하는 것을 확인 할 수 있습니다. 위 코드의 문제점이 몇 가지가 있습니다. showToday 메서드를 확인하기 전에는 today가 무엇을 위한 변수인지 확인 할 수 없습니다. 그리고 가장 큰 문제점은 실행 도중에 Day 클래스의 상수값(0~6)이 아닌 다른 값이 today에 들어갈 수 있다는 것 입니다. setToday의 매개변수 day에 0~6이 아닌 다른 int 값이 들어갈 수 있습니다. 상수값이 int 형이기 때문에 어떤 int도 들어갈 수 있기 때문에 발생하는 문제 입니다. 사실 if문을 통해서 값의 범위를 넘어가면 다시 입력 하도록 유도 할 수 있지만 그것은 좋은 코드가 아닙니다. 형에대한 안정성을 보장해주도록 위의 상수를 변경 하도록 하겠습니다. 아래는 해당 코드 입니다.




Class로 상수를 선언


class DayClass{
	public final static DayClass MONDAY = new DayClass(0);
	public final static DayClass TUESDAY = new DayClass(1);
	public final static DayClass WEDNESDDAY = new DayClass(2);
	public final static DayClass THURSDAY = new DayClass(3);
	public final static DayClass FRIDAY = new DayClass(4);
	public final static DayClass SATURDAY = new DayClass(5);
	public final static DayClass SUNDAY = new DayClass(6);
	
	int value;
	
	private DayClass(int value){
		this.value = value;
	}
	
	public void show(){
		System.out.println(value);
	}
	
	public int getValue(){
		return value;
	}
}

class DiaryClass{
	DayClass today;
	
	public void setToday(DayClass day){
		today = day;
	}
	
	public void showToday(){
		switch(today.getValue()){
		case Day.MONDAY :
			System.out.println("월요일 입니다.");
			break;
		case Day.TUESDAY :
			System.out.println("화요일 입니다.");
			break;
		case Day.WEDNESDDAY :
			System.out.println("수요일 입니다.");
			break;
		}
	}
}


 위의 코드를 보면 DayClass 클래스를 상수로 정의하고 사용 했습니다. 그렇기 때문에 가독성이 올라간 것을 확인 할 수 있습니다. DiaryClass의 today가 무슨 형인지 확인할 수 있었고 today라는 변수에 DayClass 형만 대입이 가능하기 때문에 형 안정성 또한 보장 받을 수 있습니다. 그러나 switch 문에서 바로 비교를 해서 사용할 수 없습니다. switch(today.getValue())와 같이 특정 필드(DayClass의 value 필드)와 그 값에 접근 가능한 메서드를 정의 해야 합니다.




enum


 enum(열거형)은 상수를 표현할 수 있도록 자바에서 지원하는 아주 강력한 기능 입니다. 상수를 표현 하면서 가독성이 높은 코드를 작성 할 수 있고 형 안정성도 보장 합니다. 그리고 switch 문에 enum, 그 자체를 사용 가능 합니다. 아래의 코드를 보면서 enum을 선언하는 방법과 간단한 사용 방법을 확인 해보도록 하겠습니다.


enum DayEnum{
	MONDAY, TUESDAY, WEDNESDDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

public class EnumTest{
	public static void main(String[] args){
		DayEnum today = DayEnum.MONDAY;
		switch(today){
		case MONDAY :
			System.out.println("월요일 입니다.");
			break;
		case TUESDAY :
			System.out.println("월요일 입니다.");
			break;
		case WEDNESDDAY :
			System.out.println("월요일 입니다.");
			break;
		}
	}
}


 위 코드를 보면 enum을 사용해서 간단하게 상수를 정의하는 것을 확인할 수 있습니다. 그리고 코드도 훨씬 깔끔하게 작성 됐다는 것을 확인할 수 있습니다. main 메서드의 지역 변수 today에 DayEnum형이 아닌 다른 형을 대입하면 컴파일 에러를 발생 시켜서 형 안정성 또한 보장 받을 수 있습니다. 그리고 무엇보다 switch 문에서 today 변수 자체로 비교가 가능하다는 것을 확인 할 수 있습니다. 다른 언어에도 열거형이 존재 합니다. 저도 Unity를 사용할 때 C#에서 열거형을 사용 했습니다. 하지만 자바의 enum은 다른 언어보다 조금 더 다양하게 사용이 가능하고 매우 유용합니다. 그렇기 때문에 면접에서도 자주 물어보는 주제 중에 하나 입니다. 다음에는 enum을 어떻게하면 다양하게 사용 할 수 있는지 그 방법들을 알아보도록 하겠습니다.

Comments