final 이란?
자바 언어에서 final은 오직 한 번만 할당할 수 있는 entity를 정의할 때 사용된다. final로 선언된 변수가 할당되면 항상 같은 값을 가진다. 만약 final 변수가 객체를 참조하고 있다면, 그 객체의 상태가 바뀌어도 final 변수는 매번 동일한 내용을 참조한다.
즉, 한 번 값을 넣어두면 바뀌지 않는다.
final은 클래스, 메소드, 변수 각각에 붙을 수 있다.
public final class Pet {
}
//Pet 클래스가 final 클래스로 선언되어 상속할 수 없음
public class Dog extends Pet {
}
클래스를 final로 선언하면 상속 자체가 안된다.
자바에서 기본적으로 제공하는 라이브러리 클래스나 여러 상수 값을 모아둔 Constants 클래스를 final로 선언한다.
public class Pet {
public void run() {
System.out.println("go!");
}
}
public class Dog extends Pet {
//final로된 메소드는 override할 수 없음
public void run() {
}
}
메소드를 final로 선언하면 상속받은 클래스에서 Override가 불가능하다.
Dog 객체는 Pet의 run() 메소드를 재정의할 수 없다.
따라서 구현한 코드의 변경을 원하지 않을 때 사용하면 좋다.
public void test() {
final int x = 1;
//x = 3; //한 번 assign되면 변경 불가능
}
final 원시 변수는 한 번 값을 할당하면 수정할 수 없다.
즉, 한 번 초기화된 변수는 변경할 수 없는 상수값이 된다.
public void test() {
final Pet pet = new Pet();
//pet = new Pet(); //다른 객체로 변경 불가능
pet.setWeight(3); //객체 필드는 변경할 수 있음
}
객체 변수에 final로 선언하면 그 변수에 다른 참조 값을 지정할 수 없다.
원시 타입과 동일하게 한 번 쓰여진 변수는 재변경 불가능하다.
단, 객체의 속성은 변경 가능하다.
public class Pet {
int weight;
public void setWeight(final int weight) {
//weight = 1; //final 인자는 메소드 안에서 변경할 수 없음
}
}
메소드 인자에 final 키워드를 붙이면 메소드 안에서 변수 값을 변경할 수 없다.
final과 static은 함께 쓰이는 경우가 많다.
그 이유가 뭘까?
static 이란?
static은 변수나 메소드 앞에 붙는데, 객체 생성 없이 사용할 수 있는 변수와 메소드를 생성하고자 할 때 사용한다.
공용 데이터에 해당하거나 인스턴스 필드를 포함하지 않는 메소드를 선언하고자 할 때 사용한다.
일반적으로 static을 붙이면 메모리에 딱 한 번만 할당되어 메모리를 효율적으로 사용할 수 있다. (메모리를 딱 한 번만 할당한다는 것은 같은 주소값을 공유한다는 의미)
✅ static과 final
final만으로는 상수를 의미할 수 없다.
static final double PI = 3.14;
static + final 로 선언된 PI 값은 3.14라는 불변의 값을 가진다.
해당 값은 객체마다 저장될 필요가 없으며(static의 성질) + 여러 값을 가질 수 없다(final의 특징);
[ 정리 ]
static - 객체마다 가질 필요가 없는 공용으로 사용하는 필드 혹은 인스턴스 필드를 포함하지 않는 메소드
final - 한 번 값이 정해지고 나면 값을 바꿀 수 없는 필드
static final - 모든 영역에서 고정된 값으로 사용하는 상수