변수를 정의할 때 final을 써주면, 그 변수는 '상수'가 됩니다. 즉, 한 번 정의하고 나서 다시 바꿀 수 없다는 것이다.
사용 방법이 경우에 따라 미세하게 다르니, 각 상황을 예시를 통해 보자!
+22.01.25
메소드와 클래스도 final을 사용할 수 있다. 여기서 주의할 점은 final 변수, 메소드, 클래스는 상속할 수 없다.
기본형
final double pi = 3.141592;
pi = 2.54;
이 코드는 오류가 나온다. final로 정의된 변수의 값을 바꿀 수 없기 때문이다. π(pi)처럼 바꾸지 않는, 바꾸지 말아야 할 값이 있으면 final을 써주면 된다.
참조형
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public static void main(String[] args) {
final Person p1 = new Person("박효신");
p1.setName("임창정");
System.out.println(p1.getName());
}
}
임창정
이 코드는 문제 없이 실행된다. p1을 final로 정의했는데 왜 그럴까?
final은 p1에 해당하는 것이지, p1의 인스턴스 변수에 해당하는 것이 아니기 때문이다. 따라서 p1의 이름을 못 바꾸도록 만들고 싶으면 Person 클래스 내에서 name을 final로 정의해주면 된다.
public class Person {
private final String name;
public Person(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public static void main(String[] args) {
final Person p1 = new Person("김신의");
p1.setName("문종모");
System.out.println(p1.getName());
}
}
java: cannot assign a value to final variable name
이제 오류가 나온다. final 변수는 한번만 설정해줄 수 있기 때문에 처음에 생성자에서 인스턴스 변수 name을 설정해줬는데, setName 메소드에서 바꿔주려고 하니까 문제가 생기는 것이다.
예제
이전에도 사실 객체에 해당하는 final 변수를 본적이 있다. 배열의 length 변수이다.
int[] numberList = new int[7];
System.out.println(numberList.length);
7
length는 사실 final 변수이다. 처음에 배열의 크기가 주어질 때 값이 정해지고, 그 후에는 바꿀 수 없다.
int[] numberList = new int[7];
numberList.length = 10;
이렇게 새로운 값을 지정해주려고 하면 오류 메시지가 나온다.
cannot assign a value to final variable length
length가 final 변수이고, 따라서 값을 바꿀 수 없다는 뜻이다.
추가 참고 학습 자료
public class MyClass {
// final variable.
// 한 번 정한 값 변경 불가.
// 선언과 동시에 초기화 또는 생성자에서 값을 넣어주어야 함.
// case 1. 오류. 초기화 필요
public final int finalVar1;
// case 2. 초기화 함. 오류 없음.
public final int finalVar2 = 0;
// case 3. 생성자에서 초기화. 오류 없음.
public final int finalVar3;
// case 4. 오류. 생성자가 아닌 곳(setVar4() - 일반 메소드)에서 초기화 하려 함.
public final int finalVar4;
// static variable
// 클래스 변수. 인스턴스(생성자를 통해 만드는)가 아닌 이 전체 클래스와 관련된 변수
// case 5. 선언만 하는 것 오류 없음.
public static int staticVar1;
// case 6. 오류. 이 영역(클래스, 인스턴스의 변수를 선언하는 곳)에선 할당, 메소드 호출과 같은 명령어를 수행할 수 없음.
staticVar1 = 0;
// static finalvariable
// case 7. 오류. case1과 같은 이유로 오류 발생
public static final int STATIC_FINAL_INT_1;
// case 8. 오류. case 3과 비교. static 변수는 인스턴스 생성(생정자를 통한)과 관련이 없기 때문에 생성자 에서도 초기화 할 수 없음.
public static final int STATIC_FINAL_INT_2;
// case 9. 선언과 동시에 초기화. 오류 없음.
public static final int STATIC_FINAL_INT_3 = 0;
public MyClass() {
this.finalVar3 = 0; // case 3의 초기화
setVar4(); // case 4의 메소드 호출
STATIC_FINAL_INT_2 = 0; // static final변수는 생성자에서 초기화 불 가능.
}
private void setVar4() {
// final변수에는 값을 할당할 수 없음
finalVar4 = 0;
}
}
'TIL > Java' 카테고리의 다른 글
[Java] 인스턴스 변수 vs 클래스 변수 (0) | 2022.01.07 |
---|---|
[Java] 예외(Exception) - 코드 안전하게 만들기(try-catch 예외 처리) (0) | 2022.01.07 |
[Java] 기본형vs참조형 / null 퀴즈 (0) | 2022.01.07 |
[Java] null (0) | 2022.01.07 |
[Java] 기본형 vs 참조형 (0) | 2022.01.07 |