1. 만약 작업(Job)이라는 객체가 있고 그 객체가 state라는 변수를 가지고있다.
2. 만약 Job의 상태가 완료라면 job.setState("Completion")이라고 하기로했고, 저 코드는 1000번 정도 쓰였다.
3. 헌데, 고객사에서 상태가 완료되면 "Finish"로 해달라는 요청이 왔고 이를 해결하기 위해서 1000번을 다 수정해줘야한다.
4. 여기서 만약 final String COMPLETION_STATE = "Completion" 이라고 설정해 두고,
job.setState(COMPLETION_STATE)라고 선언했다면, Completions을 finish 로만 바꾸면 모든 코드가 수정된 효과를 가질 수 있다.
5. 결정적으로 변하지 않는 값을 상수로 해두면, 좀더 직관적인 코드를 완성할 수 있기때문에 되도록 저런 변수는 상수로 처리하는 것이 바람직한 코딩 스타일이다.
또한 클래스도 상수가 될 수 있다.
final Test t1 = new Test();
t1 = new Test(); // 오류
t1.num = 10; // 이건 가능하다.
위와 같이 상수로 선언된 변수에 새로운 값을 할당할 수 없다.
하지만 클래스 안에 데이터는 변경이 가능하다.
리터럴이란?
리터럴은 데이터 그 자체를 뜻 한다.
프로그램에서 사용하는 숫자, 문자, 논리값을 뜻함
int a = 10
위에서 10과 같이 변하지 않는 데이터(boolean, char, double, long, int)를 리터럴(literal)이라고 부른다.
그렇다면 클래스는 인스턴스가 될 수 있을까? -> 될 수 없다. -> 값이 언제 바뀔지 모르기 때문이다.
하지만 예외로 객체 리터럴이 존재 하는데 이들은 한번 생성하면 객체 안의 데이터가 변하지 않는다. -> 만약 변할 상황이면 새로운 객체를 생성한다. -> 그 예로 String, Color 같은 클래스가 있다.
리터럴은 상수풀에 있음
상수 풀이란?
위와 같이 하드디스크에 있는 프로그램이 메모리로 로드될때, 상수, 리터럴, static변수 와같은 것들은 미리 메모리를 잡고 위치해있다.
로직이 실행되면서 메모리에 등록되는 것이 아니라 프로그램이 처음으로 메모리에 로드되는 순간 상수풀에 자리를 잡는다.
final String literal = "Hello";
final String object = new String("Hello");
Assert.assertTrue(literal.equals(object));
Assert.assertFalse(literal == object);
첫 번째 Hello 는 상수풀에 저장된다.
두 번째 Hello 는 힙영역에 저장된다.
equals는 true가 나오고 ==는 false가 나온다.
리터럴로 선언 되었을 경우 함수 풀에 저장되는 과정은 아래와 같다.
먼저 intern()메소드를 호출해서 현재 함수 풀(constant pool)에 해당 문자열이 있는지 확인한다.