자바 최종 수정 자
나는의 효과를 오해한다고 들었다 final
. final
키워드 의 효과는 무엇입니까 ?
다음은 내가 생각하는 것에 대한 간략한 개요입니다.
Java 최종 수정 자 (일명 집계 관계)
기본 변수 : 한 번만 설정할 수 있습니다. (메모리 및 성능 향상)
개체 변수 : 수정 될 수 있으며 최종적으로 개체 참조에 적용됩니다.
필드 : 한 번만 설정할 수 있습니다.
메서드 : 재정의하거나 숨길 수 없습니다.
클래스 : 확장 할 수 없습니다.
가비지 콜렉션 : Java 세대 별 가비지 콜렉션 마크 스윕을 강제로 이중 스윕합니다.
캔과 캔트
- 클론이 실패하게 만들 수 있음 (이는 모두 좋고 나쁨)
- 불변의 프리미티브를 const로 만들 수 있습니다.
- 공백을 불변으로 만들 수 있음-생성시 초기화 (읽기 전용)
- 객체를 얕게 불변으로 만들 수 있습니다.
- 범위 / 가시성을 변경 불가능하게 만들 수 있습니다.
- 메서드 호출 오버 헤드를 줄일 수 있습니다 (가상 테이블이 필요하지 않기 때문에).
- 최종적으로 사용되는 메서드 인수를 만들 수 있습니다 (thy가 아닌 경우에도)
- 객체를 스레드로부터 안전하게 만들 수 있습니다 (객체가 final로 정의 된 경우 메서드 인수를 final로 만들지 않음).
- 모의 테스트를 할 수 있습니다 (당신이 그것에 대해 할 수있는 것이 아니라 버그가 의도 된 것이라고 말할 수 있습니다)
- 친구를 사귈 수 없음 (다른 친구와 함께 변경할 수 있으며 휴식을 위해 변경할 수 없음)
- 나중에 변경할 수 없도록 변경된 변경을 만들 수 없습니다 (하지만 수정과 같은 공장 패턴을 사용할 수 있음).
- 배열 요소를 불변으로 만들 수 없습니다.
- 개체의 새 인스턴스를 만들 수 없습니다 (좋고 나쁨).
- 직렬화를 작동시킬 수 없습니다.
에 대한 대안은 없지만 final
wrapper + private 및 enum이 있습니다.
각 포인트에 차례로 응답 :
기본 변수 : 한 번만 설정할 수 있습니다. (메모리 및 성능 향상)
예, 그러나 메모리 이득 및 성능 이득은 없습니다. (귀하의 예상 성능 향상은에서가 아니라 한 번만 설정하여 발생 final
합니다.)
개체 변수 : 수정 될 수 있으며 최종적으로 개체 참조에 적용됩니다.
예. (그러나이 설명은 나머지 Java 언어가 객체 / 참조 이중성을 처리하는 방식과 완전히 일치한다는 점을 놓치고 있습니다. 예를 들어 객체가 매개 변수로 전달되고 결과로 반환되는 경우)
필드 : 한 번만 설정할 수 있습니다.
실제 답은 변수와 동일합니다.
메서드 : 재정의하거나 숨길 수 없습니다.
예. 그러나 여기서 진행되는 것은 final
키워드가 final
필드 / 변수 에 대해 다른 것을 의미하기 위해 다른 구문 컨텍스트에서 사용된다는 것 입니다.
클래스 : 확장 할 수 없습니다.
예. 그러나 위의 참고도 참조하십시오.
가비지 콜렉션 : Java 세대 별 가비지 콜렉션 마크 스윕을 강제로 이중 스윕합니다.
이건 말도 안돼. final
키워드는 아무런 관련성이 없다 무엇이든지 가비지 컬렉션에 있습니다. final
마무리와 혼동 을 일으킬 수 있습니다 ... 그들은 관련이 없습니다.
그러나 종료 자조차도 추가 스윕을 강요하지 않습니다. 최종화가 필요한 객체는 메인 GC가 끝날 때까지 한쪽에 설정됩니다. 그런 다음 GC는 객체에서 finalize 메소드를 실행하고 플래그를 설정하고 계속합니다. 다음에 GC가 실행될 때 개체는 일반 개체로 처리됩니다.
- 도달 할 수있는 경우 표시되고 복사됩니다.
- 도달 할 수없는 경우 표시되지 않습니다.
(귀하의 특성화- "Java 세대 별 가비지 컬렉션 마크 스윕"이 왜곡됩니다. 가비지 컬렉터는 "마크 스윕"또는 "세대"( "복사"의 하위 클래스) 일 수 있습니다. 둘 다일 수는 없습니다. Java는 일반적으로 사용합니다. 세대 별 수집, 비상시에만 마크 스윕으로 돌아갑니다 (예 : 공간이 부족하거나 낮은 일시 중지 수집기가 따라 잡을 수없는 경우).)
클론이 실패하게 만들 수 있음 (이는 모두 좋고 나쁨)
나는 그렇게 생각하지 않는다.
불변의 프리미티브를 const로 만들 수 있습니다.
예.
공백을 불변으로 만들 수 있음-생성시 초기화 (읽기 전용)
예 ... 전에 사용 된 "blank immutable"이라는 용어는 들어 본 적이 없습니다.
객체를 얕게 불변으로 만들 수 있습니다.
객체 가변성은 관찰 가능한 상태가 변경 될 수 있는지 여부에 관한 것입니다. 따라서 속성을 선언 final
하면 객체가 불변으로 작동 할 수도 있고 그렇지 않을 수도 있습니다. "얕은 불변"이라는 개념 이외에도, "얕은"이 무엇인지에 대한 개념은 클래스 의미론에 대한 깊은 지식 없이는 매핑 될 수 없기 때문에 잘 정의되어 있지 않습니다.
(명확하게 말하면 변수 / 필드의 가변성은 JLS의 맥락에서 잘 정의 된 개념입니다. JLS의 관점에서 정의되지 않은 객체의 가변성 개념 일뿐입니다.)
범위 / 가시성을 변경 불가능하게 만들 수 있습니다.
Terminology error. Mutability is about object state. Visibility and scope are not.
Can make method invocation overhead smaller (because it does not need virtual table)
In practice, this is irrelevant. A modern JIT compiler does this optimization for non-final methods too, if they are not overridden by any class that the application actually uses. (Clever stuff happens ...)
Can make method arguments used as final (even if thy are not)
Huh? I cannot parse this sentence.
Can make objects threadsafe
In certain situations yes.
(if object is defined as final, it wont make method arguments final)
Yes, if you mean if class is final. Objects are not final.
Can make mock tests (not that you could do anything about it - you can say bugs are intended)
Doesn't parse.
Can't make friends (mutable with other friends and immutable for rest)
Java doesn't have "friends".
Can't make mutable that is changed to be immutable later (but can with factory pattern like fix)
Yes to the first, a final
field can't be switched from mutable to immutable.
It is unclear what you mean by the second part. It is true that you can use a factory (or builder) pattern to construct immutable objects. However, if you use final
for the object fields at no point will the object be mutable.
Alternatively, you can implement immutable objects that use non-final fields to represent immutable state, and you can design the API so that you can "flip a switch" to make a previously mutable object immutable from now onwards. But if you take this approach, you need to be a lot more careful with synchronization ... if your objects need to be thread-safe.
Can't make array elements immutable aka deeply immutable
Yes, but your terminology is broken; see comment above about "shallow mutability".
Can't make new instances of object (this is both good and bad)
No. There's nothing stopping you making a new instance of an object with final fields or a final class or final methods.
Can't make serialization work
No. Serialization works. (Granted, deserialization of final
fields using a custom readObject
method presents problems ... though you can work around them using reflection hacks.)
There are no alternatives to final,
Correct.
but there is wrapper + private
Yes, modulo that (strictly speaking) an unsynchronized getter for a non-final field may be non-thread-safe ... even if it is initialized during object construction and then never changed!
and enums.
Solves a different problem. And enums
can be mutable.
Final keyword is usually used to preserve immutability. To use final for classes or methods is to prevent linkages between methods from being broken. For example, suppose the implementation of some method of class X assumes that method M will behave in a certain way. Declaring X or M as final will prevent derived classes from redefining M in such a way as to cause X to behave incorrectly.
ReferenceURL : https://stackoverflow.com/questions/4012167/java-final-modifier
'programing' 카테고리의 다른 글
C에서 반환 값 최적화 및 복사 제거 (0) | 2021.01.15 |
---|---|
WinForms C #의 우아한 로그 창 (0) | 2021.01.15 |
git : 권한 문제와 관련된 푸시 할 수 없음 (패커 풀기 오류) (0) | 2021.01.15 |
C의 printf 함수 코드 (0) | 2021.01.15 |
파이썬에서 파일을 읽으려고 할 때 예외를 처리하는 좋은 방법은 무엇입니까? (0) | 2021.01.15 |