final이란?
final 변수는 값이 변경될 수 없는 상수이다.
public static final double PI = 3.14;
이러한 형태로 변수를 final로 선언하며 오직 한번만 값을 할당할 수 있다.
final키워드는 변수, 메서드, 클래스에 적용할 수 있다.
final 변수
final 변수는 원시타입, 객체타입, 메서드인자, 멤버변수 이렇게 세부적으로 나눌 수 있다.
원시타입의 경우 로컬 원시 변수에 final로 선언하면 한번 초기화된 변수는 변경할 수 없는 상수값이 된다.
final int x = 1;
x = 3;//오류발생
이렇게 한번 assign되면 값을 변경할 수 없게 된다.
객체타입은 객체변수에 final로 선언하면 그 변수에 다른 참조값을 지정할 수 없다.
단, 객체 자체가 immutable 하다는 의미는 아니다. 객체의 속성은 변경이 가능하다.
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로 선언하면 생성자 호출시 한번만 초기화 할 수 있다는 의미로 사용된다.
초기화 된 이후에는 읽기만 허용되면 값을 다시 설정할 수 없다.
public class Employer {
protected final int salary;
public Employer() {
this.salary = 2400;
}
}
salary 멤버변수에 final 키워드를 명시했기 때문에 생성자에서 한번만 초기화할 수 있고 이후 다른 메서드에서는
읽기만 할 수 있다.
public class Employer {
protected final int salary;
public Employer() {
this.salary = 2400;
}
public int setSalary(int newSalary) {
this.salary = newSalary;//오류발생
}
}
public class Employer {
protected final int salary = 1000;
public Employer() {
this.salary = 2400;//오류발생
}
}
이렇게 final 멤버변수로 설정되어있는 salary를 setSalary 메서드로 수정하려고 하면 오류가 발생한다.
그리고 아래에 있는 클래스처럼 이미 멤버변수에 값이 있는 상태라면 생성자에서도 초기화 할 수 없다.
이렇게 인스턴스 생성시에 설정되고 바뀌지 않을 값에 final키워드를 붙여주면 의도하지 않은 멤버변수 변경을
막을 수 있다.
또한, 변하지 않은 멤버변수를 final로 선언해두면 자바 컴파일러가 해당 멤버변수를 Read-Only로 인식하여
레지스터 같은 곳에 값을 캐싱 할수도 있어 성능향상을 노려볼 수도 있다.
final 메서드
메서드를 final로 선언하면 상속받은 클래스에서 오버라이드가 불가능해진다.
구현한 코드를 하위클래스에서 변경하지 않도록 할 때 사용한다.
public Class Pet {
public final void makeSound() {
System.out.println("bark!");
}
public void walk() {
System.out.println("walk");
}
}
//subClass
public Class Dog extends Pet {
@Override
public void makeSound() {
System.out.println("bark!!");
} //오류발생
@Override
public void walk() {
System.out.println("run!");
}
}
위와같이 final로 선언된 makeSound는 재정의 할 수없다.
이렇게 재정의하면 안되는 메서드인 경우는 final로 막아줄 수 있다.
final 클래스
클래스에 final을 선언하면 상속자체가 안된다. 클래스 그대로 사용해야 하고 Util형식의 클래스나 여러 상수값을
모아둔 Constants 클래스를 final로 사용한다.
public class Pet{
}
//Sub class
public class Dog extends Pet{
} //오류발생
final 클래스 상수클래스
상수값을 모아준 클래스는 굳이 상속할 이유가 없다.
public final class Constants {
public static final int SIZE = 10;
}
final 클래스 Util 형식 클래스
JDK에서 String도 fianl클래스로 선언되어 있다. 자바의 코어 라이브러리이기 때문에 side-effect가 있으면 안되기
때문이다. 다른 개발자가 상속해서 새로운 SubString을 만들어 다른곳에서 사용하게 되면 유지보수나 정상실행이
어려워 질수 있다.
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
}
레퍼런스
● 패스트캠퍼스 올인원 패키지 - 자바 객체지향프로그래밍
'JAVA' 카테고리의 다른 글
Class 클래스 (0) | 2021.02.04 |
---|---|
Object 클래스 (0) | 2021.02.03 |
템플릿 메서드(Template Method) (0) | 2021.02.02 |
싱글톤 패턴(Singleton Pattern) (0) | 2021.02.01 |
인터페이스(Interface) (0) | 2021.01.31 |