최종(Java)
final (Java)Java 프로그래밍 언어에서final
키워드는 한 번만 할당할 수 있는 엔터티를 정의하기 위해 여러 컨텍스트에서 사용된다.
원스 afinal
변수는 항상 동일한 값을 포함하며,만약final
변수는 객체에 대한 참조를 가지고 있으며, 그 다음 객체의 상태는 객체에 대한 연산에 의해 변경될 수 있지만, 변수는 항상 동일한 객체(이 속성:final
비투명성(non[1] transitivity)이라고 한다.이는 어레이가 개체이기 때문에 어레이에도 적용된다.final
변수는 배열에 대한 참조를 가지고 있고, 그러면 배열의 구성요소는 배열에 대한 연산에 의해 변경될 수 있지만, 변수는 항상 동일한 배열을 가리킨다.[2]
파이널 클래스
최종 수업은 하위 수업으로 할 수 없다.이렇게 하면 보안 및 효율성 혜택을 부여할 수 있기 때문에, 자바 표준 라이브러리 클래스 중 많은 수가 다음과 같이 최종적이다.java.lang.System
그리고java.lang.String
.
예:
공중의 최종의 계급 마이 파이널 클래스 {...} 공중의 계급 이는 잘못되었다. 연장하다 마이 파이널 클래스 {...} // 금지됨
최종 방법
최종 방법은 하위 클래스에 의해 재정의되거나 숨겨질 수 없다.[3]이것은 클래스의 기능이나 일관성에 중요할 수 있는 방법을 변경하는 하위 클래스의 예기치 않은 동작을 방지하기 위해 사용된다.[4]
예:
공중의 계급 베이스 { 공중의 공허하게 하다 m1() {...} 공중의 최종의 공허하게 하다 m2() {...} 공중의 정태의 공허하게 하다 m3() {...} 공중의 정태의 최종의 공허하게 하다 m4() {...} } 공중의 계급 파생된 연장하다 베이스 { 공중의 공허하게 하다 m1() {...} // OK, Base#m1() 재정의 공중의 공허하게 하다 m2() {...} // 금지됨 공중의 정태의 공허하게 하다 m3() {...} // OK, Base#m3() 숨기기 공중의 정태의 공허하게 하다 m4() {...} // 금지됨 }
일반적인 오해는 방법을 다음과 같이 선언하는 것이다.final
컴파일러가 호출되는 모든 곳에 메서드를 직접 삽입할 수 있도록 하여 효율성을 향상시킨다(인라인 확장 참조).방법이 런타임에 로드되기 때문에 컴파일러는 이것을 할 수 없다.오직 런타임 환경과 JIT 컴파일러만이 어떤 클래스가 로드되었는지 정확히 알고 있기 때문에, 오직 그들만이 언제 인라인으로 할 것인지, 그 방법이 최종적인 것인지에 대한 결정을 내릴 수 있다.[5]
직접 실행 가능한 시스템 코드 컴파일러, 플랫폼별 시스템 코드는 예외다.정적 연결을 사용할 때 컴파일러는 컴파일 시간에 계산할 수 있는 방법과 변수가 삽입될 수 있다고 안전하게 가정할 수 있다.
최종 변수
최종 변수는 이니셜라이저 또는 할당문을 통해 한 번만 초기화할 수 있다.선언 시점에서 초기화할 필요는 없다: 이것을 "빈 최종" 변수라고 한다.클래스의 빈 최종 인스턴스(instance) 변수는 클래스가 선언된 클래스의 모든 생성자에 반드시 할당되어야 한다. 마찬가지로, 빈 최종 정적 변수는 선언된 클래스의 정적 이니셜라이저에 반드시 할당되어야 한다. 그렇지 않으면 두 경우 모두에 컴파일 시간 오류가 발생한다.[6](참고: 변수가 참조인 경우, 다른 객체를 참조하기 위해 변수를 다시 바인딩할 수 없음을 의미한다.그러나 그것이 참조하는 물체는 원래 변이된 것이라면 여전히 변이 가능하다.)
상수의 값과 달리 최종 변수의 값은 컴파일 시 반드시 알 수 있는 것은 아니다.밑줄을 사용하여 단어를 구분하여 모든 대문자로 최종 상수를 나타내는 것이 좋은 관례로 간주된다.[7]
예:
공중의 계급 구 { // pi는 보편적인 상수로서, 가능한 한 상수다. 공중의 정태의 최종의 곱절로 하다 PI = 3.141592653589793; 공중의 최종의 곱절로 하다 반지름; 공중의 최종의 곱절로 하다 xPos; 공중의 최종의 곱절로 하다 이포스; 공중의 최종의 곱절로 하다 zPos; 구(곱절로 하다 x, 곱절로 하다 y, 곱절로 하다 z, 곱절로 하다 r) { 반지름 = r; xPos = x; 이포스 = y; zPos = z; } [...] }
재할당 시도radius
,xPos
,yPos
또는zPos
컴파일 오류가 발생할 것이다.실제로 시공자가 최종 변수를 설정하지 않더라도 시공자 외부에서 설정하려고 하면 컴파일 오류가 발생한다.
최종성이 불변성을 보장하지는 않는다는 점을 설명하기 위해 다음과 같이 세 가지 위치 변수를 단일 변수로 교체한다고 가정해 보십시오.
공중의 최종의 포지션 양치류;
어디에pos
세 가지 특성을 가진 물체pos.x
,pos.y
그리고pos.z
. 그러면.pos
배정할 수 없지만 최종 소유자가 아닌 한 세 가지 속성은 배정할 수 있다.
완전 불변성과 마찬가지로 최종 변수의 사용은 특히 최적화에 큰 장점을 가지고 있다.예를 들어.Sphere
아마도 그것의 볼륨을 반환하는 기능이 있을 것이다; 그것의 반경이 일정하다는 것을 아는 것은 우리가 계산된 볼륨을 메모할 수 있게 해준다.만약 우리가 상대적으로 적은 수의 사람들만 있다면Sphere
그리고 우리는 그들의 볼륨이 매우 자주 필요하며, 성능 향상이 상당할 수 있다.a의 반지름을 만드는 중Sphere
final
개발자와 컴파일러에게 이러한 종류의 최적화가 사용하는 모든 코드에서 가능하다는 것을 알린다.Sphere
s
비록 그것은 그 법을 위반하는 것처럼 보인다.final
원칙은 다음과 같다.
을 위해 (최종의 SomeObject 오비지 : 일부 목록) { // obj로 뭔가를 하다. }
obj 변수는 루프의 각 반복과 함께 범위를 벗어나기 때문에 실제로 각 반복을 다시 클리어하여 동일한 토큰(즉, 같은 토큰)을 허용한다.obj
여러 변수를 나타내기 위해 사용되어야 한다.[8]
내포된 객체의 최종 변수
최종 변수는 불변의 물체의 트리를 만드는 데 사용될 수 있다.일단 만들어지면, 이 물체들은 더 이상 변하지 않을 것을 보장받는다.이를 이루기 위해서는 불변계급은 최종계급만 있어야 하며, 이러한 최종계급은 그 자체로 불변계형만 가질 수 있다.자바의 원시적인 종류는 문자열과 몇 가지 다른 계급과 마찬가지로 불변의 것이다.
만일 나무에 불변성이 없는 물체가 있어서 위와 같은 구조를 어긴다면 최종 변수를 통해 도달할 수 있는 것이 일정하다는 기대는 하지 않는다.예를 들어, 다음 코드는 출발지가 항상 (0, 0)이어야 하는 좌표계를 정의한다.원점은 다음을 사용하여 구현된다.java.awt.Point
하지만, 이 세분류는 그 분야를 공개적이고 수정할 수 있는 것으로 정의한다.이것은 심지어 에 도달했을 때에도origin
최종 변수만 있는 액세스 경로 위의 개체. 아래의 예 코드가 보여주는 것처럼 해당 개체는 여전히 수정할 수 있다.
수입하다 자바.와트포인트; 공중의 계급 파이널데모 { 정태의 계급 좌표계 { 사유의 최종의 포인트 기원을 이루다 = 새로운 포인트(0, 0); 공중의 포인트 getOrigin() { 돌아오다 기원을 이루다; } } 공중의 정태의 공허하게 하다 본래의(끈[] 아그) { 좌표계 좌표계 = 새로운 좌표계(); 좌표계.getOrigin().x = 15; 주장하다 좌표계.getOrigin().getX() == 0; } }
그 이유는 변수 최종을 선언하는 것은 이 변수가 언제라도 같은 물체를 가리키게 된다는 것을 의미할 뿐이기 때문이다.그러나 변수가 가리키는 객체는 최종 변수의 영향을 받지 않는다.위의 예에서 원점의 x 좌표와 y 좌표는 자유롭게 수정할 수 있다.
이러한 바람직하지 않은 상황을 예방하기 위해서는 불변의 물체의 모든 분야가 최종이어야 하며, 이러한 필드의 종류는 그 자체로 불변의 것이어야 한다는 것이 공통된 요구 사항이다.이것은 부적격이다.java.util.Date
그리고java.awt.Point
그리고 그러한 불변의 물체에서 사용되는 몇몇 다른 클래스들.
파이널 및 이너 클래스
익명의 내부 클래스가 메서드의 본문 내에 정의되면 모든 변수가 선언됨final
그 방법의 범위 내에서 내부 계층 내에서 접근 가능하다.스칼라 값의 경우 스칼라 값이 할당되면final
변수는 변경할 수 없음.객체 값의 경우 참조는 변경할 수 없다.이를 통해 자바 컴파일러는 런타임에 변수 값을 "캡처"하고 복사본을 내부 클래스의 필드로 저장할 수 있다.외부 방법이 종료되고 스택 프레임이 제거되면 원래 변수는 사라지지만 내부 계층의 개인 복사본은 클래스 자체 메모리에 유지된다.
수입하다 자바스의*; 공중의 계급 푸귀 { 공중의 정태의 공허하게 하다 본래의(끈[] 아그) { //GUI 구성 요소 초기화 최종의 제이프레임 JF = 새로운 제이프레임("헬로 월드!"); //내부 등급 본체에서 jf 액세스 가능 JF.덧셈을(새로운 JButton("날 클릭")); // 이벤트 디스패치 스레드에 포장 및 표시 스윙유틸리티.호출Later(새로운 런너블() { @오버라이드 공중의 공허하게 하다 달리다() { JF.짐을 꾸리다(); //jf가 최종적이지 않은 경우 컴파일 시간 오류가 될 수 있음 JF.setLocationRelativeTo(무효의); JF.세트비주얼(진실의); } }); } }
블랭크 파이널
자바 1.1에서 도입된 빈 결승전은 선언문에 이니셜라이저가 빠진 최종 변수다.[9][10]자바 1.1 이전에는 이니셜라이저를 갖기 위해 최종 변수가 필요했다."최종"의 정의에 의해, 빈 결승은 오직 한 번만 배정될 수 있다. 즉, 과제가 발생할 때 배정되지 않아야 한다.이를 위해 Java 컴파일러는 흐름 분석을 실행하여 빈 최종 변수에 대한 모든 할당의 경우, 변수가 할당 전에 확실히 할당 해제되고 그렇지 않으면 컴파일 시간 오류가 발생하게 된다.[11]
최종의 부울 has TwoDigits; 만일 (번호를 붙이다 >= 10 && 번호를 붙이다 < 100) { has TwoDigits = 진실의; } 만일 (번호를 붙이다 > -100 && 번호를 붙이다 <= -10) { has TwoDigits = 진실의; // 최종 변수가 이미 할당되었을 수 있기 때문에 컴파일 형식 지정. }
게다가, 빈 결승전 또한 접속되기 전에 반드시 배정되어야 한다.[11]
최종의 부울 이븐; 만일 (번호를 붙이다 % 2 == 0) { 이븐 = 진실의; } 시스템.밖으로.인쇄하다(이븐); // 다른 경우에서 변수가 할당되지 않았기 때문에 컴파일 처리.
비최종 로컬 변수도 액세스하기 전에 반드시 할당해야 한다는 점에 유의하십시오.[11]
부울 이븐; // *not* 최종 만일 (번호를 붙이다 % 2 == 0) { 이븐 = 진실의; } 시스템.밖으로.인쇄하다(이븐); // 최종 변수가 다른 경우에 할당되지 않았기 때문에 동일한 컴파일 오류.
최종 변수의 C/C++ 아날로그
C와 C++에서 유사한 구조는const
키워드이것은 상당히 다르다.final
Java의 경우 유형 한정자가 되는 데 있어 가장 기본적인 것은 다음과 같다.const
식별자(variable)의 일부만이 아니라 유형의 일부다.이것은 또한 어떤 값의 항상성이 주조(추상형 변환)에 의해 변경될 수 있다는 것을 의미하는데, 이 경우 "Constant casting"그럼에도 불구하고, 만약 객체가 원래 선언된 것이라면, 항상성을 버리고 객체를 수정하는 것은 정의되지 않은 행동을 야기한다.const
. 자바의final
최종 제한을 직접 위반하거나 우회하는 코드를 컴파일할 수 없는 엄격한 규칙이다.그러나 반성을 사용하여 최종 변수를 여전히 수정할 수 있는 경우가 많다.이 기능은 대부분 최종 멤버로 객체를 역직렬화할 때 사용된다.
또한 C와 C++ 노출 포인터 및 노출 포인터와 참조가 직접 있기 때문에 포인터 자체가 일정한지 여부와 포인터로 가리키는 데이터가 일정한지 여부를 구분한다.적용const
에서와 같이 포인터 자체에.SomeClass * const ptr
참조되는 내용은 수정할 수 있지만 참조 자체는 (주조 없이) 수정할 수 없다는 것을 의미한다.이 사용으로 인해 a의 동작을 모방하는 동작이 발생함final
Java의 변수 참조.대조적으로 참조된 데이터에만 constance를 적용할 때 다음과 같이 하십시오.const SomeClass * ptr
, (주조 없이) 내용은 수정할 수 없지만, 참조 자체는 수정할 수 있다.참조할 내용과 참조할 내용 모두 다음과 같이 선언할 수 있다.const
.
최종 키워드에 대한 C# 아날로그
C#은 언어적 특징과 기본 구문 면에서 자바와 유사한 것으로 간주될 수 있다: 자바에는 JVM이 있고, C#에는 .Net Framework; 자바에는 바이트코드가 있고, C#에는 MSL이 있으며, 자바에는 포인터(실제 메모리) 지원이 없고, C#는 동일하다.
최종 키워드와 관련하여 C#에는 두 가지 관련 키워드가 있다.
- 방법 및 클래스에 해당하는 키워드는
sealed
- 변수에 대한 등가 키워드는
readonly
[12]
C/C++ 파생 키워드 간의 주요 차이점const
그리고 C# 키워드readonly
이다const
컴파일 시간에 평가되는 동안readonly
런타임에 평가되므로 나중에(런타임에) 계산되고 고정되는 식을 가질 수 있다.
참조
- ^ Coblenz, Michael; Sunshine, Joshua; Aldrich, Jonathan; Myers, Brad; Weber, Sam; Shull, Forrest (14–22 May 2016). "Exploring Language Support for Immutability". The 38th International Conference on Software Engineering.
- ^ 자바 언어 규격 #4.12.4
- ^ JLS 8.4.3.3. 최종 방법
- ^ 최종 클래스 및 방법 작성
- ^ Java 이론 및 실습:그게 네 마지막 답이니?
- ^ 자바 언어 규격 #8.3.1.2.
- ^ http://geosoft.no/development/javastyle.html
- ^ Pattis, Richard E. "More Java". Advanced Programming/Practicum 15–200. School of Computer Science Carnegie Mellon University. Retrieved 23 July 2010.
- ^ Flanagan, David (May 1997). "Chapter 5 Inner Classes and Other New Language Features:5.6 Other New Features of Java 1.1". Java in a Nutshell (2nd ed.). O'Reilly. ISBN 1-56592-262-X.
- ^ "Chapter 4. Types, Values, and Variables". The Java® Language Specification (Java SE 8 Edition). Oracle America, Inc. 2015. Retrieved 23 Feb 2015.
- ^ a b c "Definite Assignment". The Java® Language Specification (Java SE 8 Edition). Oracle America, Inc. 2015. Retrieved 29 Oct 2016.
- ^ 자바의 결승전 C#에 해당하는 것은?