수정제어자
수정제어자란 자바 프로그래밍 언어에서 final 키워드가 여러 컨텍스트에서 한 번만 할당할 수 있는 엔티티를 정의하기 위해 사용되는 것이다. final 변수가 할당되면 항상 동일한 값을 포함하게 된다. final 변수가 객체에 대한 참조를 보유하는 경우, 객체의 동작에 의해 객체의 상태가 변경될 수 있지만 변수는 항상 동일한 객체를 가리킨다(이 final 속성을 비투명성이라고 한다). 객체인 배열에도 적용된다. final 변수가 배열에 대한 참조를 보유할 경우 배열의 구성 요소는 배열에 대한 작업에 의해 변경될 수 있지만 변수는 항상 동일한 배열을 가리킨다. [1]
목적
변수, 함수, 클래스는 final로 제한함으로써 오버라이드로 인한 실수를 최소화하고 버그를 줄이기 위해 선언한다. [2]
특징
수정제어자는 클래스, 변수, 메소드 앞에 작성하여 수정할 수 없도록 한다. 생성자는 수정제어자를 사용할 수 없다. [3]
Final class[1]
final class는 서브클래스를 생성할 수 없다. final class를 사용하면 보안 및 효율성을 가질 수 있으며, java.lang.System이나 java.lang.String과 같은 자바 표준 라이브러리 클래스의 상당수가 final이다.
//Example final class public final class FinalClass{...} public class Ban extends FinalClass //금지된 사용
Final method[1]
final method는 하위 클래스에서 오버라이딩하거나 숨길 수 없다. 이것은 클래스의 기능이나 일관성에 중요할 수 있는 메소드를 변경하는 하위 클래스의 예기치 않는 행동을 방지하기 위해 사용된다.
//Example final method public class Standard { public void m1() {...} public final m2() {...} public static void m3() {...} public static final void m4() {...} }
public class Upgrade extends Standard { public void m1() {...} //사용가능(재정의) public final m2() {...} //금지된 사용 public static void m3() {...} //사용가능 (숨김) public static final void m4() {...} //금지된 사용 }
대부분 메소드를 final로 선언하면 컴파일러가 호출되는 곳마다 메소드를 직접 삽입할 수 있기 때문에 효율성이 향상된다고 오해한다. 메소드가 런타임에 로드되기 때문에 컴파일러는 이를 수행할 수 없다. 오직 런타임 환경과 JIT 컴파일러만이 어떤 클래스가 로드되었는지 정확히 알고 있기 때문에, 메소드의 final 여부에 관계없이 인라인 시점에 대한 결정을 내릴 수 있다. 플랫폼 별로 직접 실행 가능한 시스템 코드를 생성하는 시스템 코드 컴파일러는 예외다. 정적 링크를 사용할 때 컴파일러는 컴파일 시간에 계산할 수 있는 메소드와 변수가 삽입될 수 있다고 가정할 수 있다.
Final variable[1]
final variable는 초기화 또는 할당문을 통해 한 번만 초기화 할 수 있다. 선언 시점에서 초기화할 필요가 없다. 이를 blank fianl variable라고 한다. 클래스의 blank final instance variable은 선언된 클래스의 모든 생성자에 확실히 할당되어야 한다. 마찬가지로, blank final static variable는 선언된 클래스의 정적 초기화에 확실히 할당되어야 한다. 그렇지 않으면 두 경우 모두 컴파일 시간 오류가 발생한다. (참고 : 변수가 참조인 경우, 이는 변수가 다른 객체를 참조하기 위해 다시 바인딩 될 수 없음을 의미한다. 그러나 참조하는 객체는 원래 변경 가능한 경우 여전히 변경 가능하다.) 상수(constant) 값과 달리 final 변수의 값은 컴파일 시 반드시 알 수 있는 것은 아니다. 단어를 구분하기 위해 밑줄을 사용하여 최종 상수(final contant)를 모두 대문자로 표시하는 것이 좋다.
//Example final variable class Circle{ public static final double PI = 3.141592653589793; public double radius; public double Circumference(double radius) { PI = 3; //오류: final 변수로 선언된 PI를 변경할 수 없다. return 2*radius*PI; } }
public class Main { public static void main(String[] args) { Circle circle = new Circle(); System.out.println(circle.Circumference(5)); } } >>>31.41592653589793
각주
- ↑ 1.0 1.1 1.2 1.3 WIKIPEDIA , 〈Final (Java)〉, 《WIKIPEDIA》, 2020-05-11
- ↑ BANG DONGGEUN , 〈자바의 final는 언제 사용할까?〉, 《개인블로그》, 2018-08-20
- ↑ CIVIC , 〈수정 제한자(final)〉, 《개인블로그》, 2018-02-14
참고자료
- WIKIPEDIA , 〈Final (Java)〉, 《WIKIPEDIA》, 2020-05-11
- BANG DONGGEUN , 〈자바의 final는 언제 사용할까?〉, 《개인블로그》, 2018-08-20
- CIVIC , 〈수정 제한자(final)〉, 《개인블로그》, 2018-02-14