'최종'키워드가 업계에서 왜 그렇게 많이 사용되지 않습니까? [닫은]


14

final몇 년 전에 Java 에서 키워드 의 기능을 발견 한 후 사람들이 읽기 전용 변수를 쉽게 볼 수 있기 때문에 코드를 더 읽기 쉽게 만들 수있었습니다. 또한 JIT에 약간의 향상을 제공 할 수 있으며 매우 제한적이지만 특히 안드로이드 플랫폼과 같은 임베디드 장치를 대상으로 할 때 해를 끼치 지 않습니다.

그러나 무엇보다도 변경 사항에 대한 디자인을보다 강력하게 만들고 코드 기반을 수정해야 할 때 다른 커미터를 안내하는 데 기여합니다.

그러나 일부 JDK 소스 코드를 탐색하는 동안 클래스, 메소드 또는 변수에 대해이 키워드를 우연히 발견하지 못했습니다. 검토해야하는 다양한 시스템에도 동일하게 적용됩니다.

이유가 있습니까? 내부에서 모든 것을 변경할 수있게하는 것이 일반적인 디자인 패러다임입니까?


마이크로 최적화에, 설정 final필드는 동일한 쓰기 등의 의미를 가지고 volatile이 원하는 항상 무엇을, 나중에 읽기 휘발성 읽기의 의미를 가질 필요가 다음 필드, 그리고
래칫 괴물

5
@ratchet : 이것은 함수형 프로그래밍에서와 같이 클래스를 불변으로 만드는 것에 관한 것입니다.
Jonas

@ Kwebble : 더 중요한 것은 개별 String 인스턴스 가 변경 불가능 하다는 것 입니다.
MatrixFrog

답변:


9

당신이 그것을 보지 못하는 이유는 JDK가 확장되도록 설계 되었기 때문입니다 (모든 프로그램이 기반이되는 기초입니다). 응용 프로그램 코드가 그것을 사용하는 것은 드문 일이 아닙니다. 또한 라이브러리는 확장을 위해 종종 디자인되기 때문에 라이브러리 코드에서도 많은 것을 기대하지는 않습니다.

좋은 오픈 소스 프로젝트를 살펴보면 더 많은 것을 찾을 수 있다고 생각합니다.

Java에서 보는 것과는 달리 .NET 세계에서는 sealed기본적으로 클래스가 클래스에 적용되는 것과 유사해야하며 개발자가 명시 적으로 봉인을 해제해야한다는 주장을 여러 번 들었습니다. 그것.


2
필자는 객체 변수를 분명히 "한 번 생성하고 무시하지 않는"JDK 클래스의 많은 개인 또는 보호 멤버를 언급하기까지했습니다. 특히 스윙 패키지. 널 포인터로 대체하면 구성 요소를 사용할 때 오류가 발생하기 때문에 '최종'에 대한 완벽한 후보입니다.
Aurelien Ribon

1
@ Aurélien : 기분이 나아질 경우 .NET Framework의 많은 클래스는 자체 기능으로 프레임 워크 클래스를 확장하려는 일부 사용자의 불만에 봉인 됩니다. 그러나 확장 방법
Robert Harvey

1
나는 이것이 확장을 피하는 것보다 불변성에 관한 것이라고 생각합니다. 즉, final메소드가 아닌 on 필드를 사용 합니다. 불변 클래스는 확장되도록 설계 될 수도 있습니다.
Jonas

15

사용의 문제 final읽기 전용 뭔가를 전달하기 위해 그것은 단지 정말 기본 유형이 원하는 작동한다는 것입니다 int, char등 모든 자바 객체가 실제로 (가지) 포인터를 사용하여 참조한다. 결과적으로 final객체 에서 키워드 를 사용할 때 참조 는 읽기 전용이며 객체 자체는 여전히 변경 가능 하다는 것만 말하는 것입니다 .

실제로 객체를 읽기 전용으로 설정 한 경우 더 많이 사용되었을 수 있습니다. C ++에서는 이것이 정확히하는 일 const이며 결과적으로 훨씬 유용하고 많이 사용되는 키워드입니다.

final키워드를 많이 사용하는 곳 은 다음과 같은 것들로 인한 혼란을 피하기 위해 매개 변수를 사용하는 것입니다.

public void someMethod(FancyObject myObject) {
    myObject = new FancyObject();
    myObject.setProperty(7);
}
...
public static void main(final String[] args) {
    ...
    FancyObject myObject = new FancyObject();
    someOtherObject.someMethod(myObject);
    myObject.getProperty(); // Not 7!
}

이 예제에서는 왜 이것이 작동하지 않는지 분명해 보이지만 someMethod(FancyObject)크고 복잡한 혼란이 발생할 수 있습니다. 왜 피하세요?

또한 Sun (또는 이제는 Oracle이라고 생각합니다) 코딩 표준의 일부입니다.


1
finalJava API 클래스에서 더 많이 사용했다면 대부분의 객체는 많은 스칼라 라이브러리에서와 같이 변경할 수 없었습니다. 그런 다음 객체 필드를 final만들면 클래스를 변경할 수없는 경우가 많습니다. 이 디자인은 이미 BigDecimal및 에서 사용되었습니다 String.
Jonas

@Jonas 나는 "사람들이 읽기 전용 변수가 무엇인지 쉽게 볼 수 있기 때문에"schmmd의 답변에서 포인트 4에 관한 질문을 읽었으며 그에 따라 대답했습니다. 어쩌면 나는 그 가정을 대답에 포함시켜야했을 것입니다.
Gyan 일명 Gary Buys

매개 변수를 재 할당 할 시간이 있음을 명심하십시오. 예를 들어 문자열 매개 변수를 다듬는 것입니다.
Steve Kuo

@Steve 나는 보통 그 상황에서 할당 할 새 변수를 만듭니다.
Gyan 일명 Gary Buy

1
@ 게리, 적어도 매개 변수를 다시 할당하여 버그 / 혼란이 발생하는 경우는 거의 없습니다. 나는 오히려 무료 코드를 혼란스럽게 만들고 버그를 일으키는 매개 변수를 다시 할당 할 수있는 원격 기회를 받아들입니다. 코드를 작성 / 수정할 때주의하십시오.
Steve Kuo

4

final키워드가 가독성을 향상시키는 데 동의합니다 . 언제 객체가 불변인지 이해하기가 훨씬 쉽습니다. 그러나 Java에서는 매개 변수에 사용될 때 특히 장황합니다. 이것은 사람들이 장황하기 때문에 그것을 사용해서는 안된다는 말이 아니라 장황하기 때문에 그것을 사용하지 않는다는 것입니다.

스칼라와 같은 다른 언어를 사용하면 최종 선언 ( val ) 을 훨씬 쉽게 만들 수 있습니다. 이러한 언어에서 최종 선언은 변수보다 더 일반적 일 수 있습니다.

최종 키워드는 여러 가지 용도로 사용됩니다. 귀하의 게시물은 대부분 항목 2와 3을 다룹니다.

  1. 최종 수업 (JLS 8.1.1.2)
  2. 최종 필드 (JLS 8.3.1.2)
  3. 최종 방법 (JLS 8.4.3.3)
  4. 최종 변수 (JLS 4.12.4)

2

우선 , 공식 Java Code Conventions의 특정 사용을 선호하거나 금지하지 않습니다 final. 즉, JDK 개발자는 원하는 방식을 자유롭게 선택할 수 있습니다.

나는 그들의 마음을 읽을 수는 없지만 나에게 사용의 유무에 대한 선호 final는 초점의 문제였습니다. 의 문제 I 철저하게 코드 여부를 집중할 수있는 충분한 시간이 있는지 .

  • 내 프로젝트 중 하나에서 하루 에 평균 100 줄의 코드를 소비 할 수 있다고 가정 해보십시오 . 이 프로젝트에서 저는 final코드에서 이미 명확하게 표현 된 것들을 가릴 수있는 쓰레기로 명확하게 인식했습니다 . JDK 개발자도 해당 범주에 속합니다.
     
    반면에 다른 프로젝트에서는 100 라인의 코드에서 평균 1 시간 을 보냈습니다 . 거기에서 나는 나 final자신과 다른 사람의 코드에서 마치 총처럼 쏘는 것을 발견했다. 왜냐하면 그것은 내 앞에 그것을 쓴 사람의 의도를 감지하는 가장 빠른 방법이었고, 마찬가지로 내 자신의 의도를 전달하는 가장 빠른 방법이기 때문이다. 나중에 내 코드에서 작업 할 사람.

또한 JIT에 약간의 향상을 제공 할 수 있으며 매우 제한적이지만 해를 끼칠 수 없습니다.

위와 같은 추론은 미끄 럽습니다. 조기 최적화 는 해를 끼칠 수 있습니다. 도널드 크 누스는 그것을 "모든 악의 근원" 이라고 부르기까지한다 . 당신을 함정에 빠뜨리지 마십시오. 바보 코드를 작성하십시오 .


2

최근에 Eclipse IDE에서 "작업 저장"기능의 기쁨을 발견했습니다. 코드를 다시 포맷하고 누락 된 @Override주석을 삽입 하고 표현식에서 불필요한 괄호를 제거하거나 final적을 때마다 자동으로 키워드를 배치하는 등의 멋진 작업을 수행 할 수 있습니다 ctrl + S. 나는 그 방아쇠 중 일부를 활성화하고, 소년, 그것은 많은 도움이됩니다!

많은 트리거가 내 코드의 빠른 온 전성 검사처럼 작동한다는 것이 밝혀졌습니다.

  • 메서드를 재정의하려고했지만 히트 할 때 주석이 표시되지 ctrl + s않습니까? -아마도 어딘가에 매개 변수 유형을 망쳤습니다!
  • 저장시 코드에서 일부 괄호가 제거 되었습니까? -프로그래머가 논리를 표현하기가 너무 어려울 수 있습니다. 그렇지 않으면 왜 먼저 괄호를 추가합니까?
  • 해당 매개 변수 또는 로컬 변수가 아닙니다 final. 값을 변경 해야 합니까 ?

변수가 적을수록 디버그 할 때 발생하는 문제가 줄어 듭니다. 변수가 5에서 7로 어떻게 바뀌는지를 알기 위해 몇 번이나 변수 값을 따랐습니까? "도대체 어떻게 될 수 있니?!" 당신은 자신에게 묻고 논리에서 실수를 저지른 것을 발견하기 위해 무수한 방법으로 들어오고 나가는 몇 시간을 보냅니다. 그리고 그것을 고치려면 플래그 하나, 몇 가지 조건을 추가하고 여기 저기 값을 신중하게 변경해야합니다.

오, 난 디버깅이 싫어! 디버거를 실행할 때마다 시간이 다 된 것 같은 느낌이 들며 , 적어도 내 어린 시절의 꿈 중 일부 를 실현하기 위해 필사적으로 그 시간이 필요 합니다! 디버깅으로 지옥에! final더 이상 신비로운 가치 변화가 없음을 의미합니다. 더 많은 finals => 내 코드에서 덜 희미한 부분 => 더 적은 버그 => 좋은 일을하는 데 더 많은 시간!

final클래스와 메소드에 관해서는 실제로 신경 쓰지 않습니다. 나는 다형성을 좋아합니다. 다형성이란 재사용은 코드가 적다는 것을 의미하고 버그가 적다는 것을 의미합니다. JVM은 어쨌든 가상화 및 메소드 인라인으로 꽤 잘 작동하므로 성능이 좋지 않은 코드의 재사용 가능성을 없애는 데는 가치가 없습니다.


final코드에서 모든 것을 보는 것은 처음에는 다소 혼란스럽고 익숙해지기까지 시간이 걸립니다. 내 팀 동료 중 일부는 여전히 많은 final키워드 를보고 매우 놀랐습니다 . IDE에 특수 구문 색상을 설정하기를 바랍니다. 코드를 읽을 때 너무 산만하지 않도록 주석과 같은 회색 음영으로 바꾸어 드리겠습니다. Eclipse는 현재에 대해 별도의 색상 return과 다른 모든 키워드를 갖지만에 대한 것은 아닙니다 final.


1
OCaml 또는 F #과 같은 기능적 언어를 살펴볼 수도 있습니다. 이러한 언어는 디버깅이 훨씬 덜 필요한 경향이 있는데, 기본적으로 모든 것이 읽기 전용이기 때문입니다. 일단 할당되면 기능 언어의 변수는 변경되지 않습니다.
Abel

1
예, 알고 있으며 실제로 ML 코드를 작성하는 경우가 있습니다. 여기서 영감을 얻었습니다.) 사용하는 언어가 아니라 적용하는 원칙과 기술에 관한 것입니다. 하나는 하스켈과 모든 필수 갈 수 do표기 : 물론을, 자바는 기능적인 스타일에 작성하지만 적어도 당신이 강력한 코드 - 그리고 쓸 수에 가장 적합한 언어가 아닙니다 이의 정말 걱정 무엇을.
Andrew Андрей Листочкин
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.