Java에서는 모든 변수 (로컬 또는 클래스)를 선언하는 연습이 있으며 실제로는 매개 변수 final입니다.
이렇게하면 코드가 훨씬 더 장황하지만 코드를 쉽게 읽고 이해하는 데 도움이되고 의도가 명확하게 표시되어 실수를 방지 할 수 있습니다.
이것에 대한 당신의 생각은 무엇입니까?
Java에서는 모든 변수 (로컬 또는 클래스)를 선언하는 연습이 있으며 실제로는 매개 변수 final입니다.
이렇게하면 코드가 훨씬 더 장황하지만 코드를 쉽게 읽고 이해하는 데 도움이되고 의도가 명확하게 표시되어 실수를 방지 할 수 있습니다.
이것에 대한 당신의 생각은 무엇입니까?
답변:
나는 그것이 좋은 코딩 스타일과 관련이 있다고 생각합니다. 물론 final
어디에서나 많은 수정자를 사용하지 않고도 훌륭하고 강력한 프로그램을 작성할 수 있지만 생각할 때 ...
변경 해서는 안되는final
모든 것에 추가하면 코드를 작성하는 사고 과정을 잘못 해석하거나 잘못 사용할 가능성이 좁아집니다. 그들이 이전에 불변의 것을 바꾸고 싶을 때 적어도 그것은 종을 울려 야합니다.
처음에는 final
코드에서 많은 키워드 를 보는 것이 어색해 보이지만 곧 단어 자체에 대한 언급을 중단하고 간단히 생각할 것입니다. 에 (당신은 나에게서 그것을 취할 수 있습니다 ;-)
좋은 습관이라고 생각합니다. 나는 항상 그것을 사용하지 않고 있지만, 할 수 있고 무언가에 레이블을 붙이는 것이 합리적 final
입니다.
final
경우 실수로 컴파일러를 사용하면 계속 진행할 수 없습니다.
final
저장할 때마다 가능하면 변경하지 않는 변수 를 추가 할 수 있는 옵션이 있습니다 .
final
합니다. 그것은 98 %의 시간 차이를 만들지 않고, 시간의 작은 불편 함 % 1이지만, 시간의 1 %는 어리 석거나 의도하지 않은 일을하는 것을 막아줍니다.
final
내 코드를 "정리 ..."할 때 Eclipse가 어디서나 수정자를 추가하도록한다 . 어디서나 catch () 블록에서도 의미가 있으며, 말한 것처럼 잠시 후에는 알 수 없습니다. 물론 언어를 만들면 이것이 final
기본값이고 var
또는 또는 modifiable
선택적 키워드가됩니다.
집착 :
신중하게 사용하십시오.
항문 느낌이 없으면 무시하십시오.
최종 키워드를 사용하기 전에 전체 사용법을 이해해야합니다. 변수, 필드, 메소드 및 클래스에 적용 할 수 있으며 다른 영향을 미칩니다.
자세한 내용은 아래 링크 된 기사를 확인하는 것이 좋습니다.
final
특히 변수에 대한 수정은 수단 컴파일러는 일반적으로 분별하는 규칙을 적용하는 것입니다 : 확실히 (로컬 또는 인스턴스) 변수 (더 이상 아무 이하) 정확히 한 번만 할당되지도하지 않습니다. 변수를 사용하기 전에 변수를 확실히 할당하면 NullPointerException
다음 과 같은 일반적인 경우를 피할 수 있습니다 .
final FileInputStream in;
if(test)
in = new FileInputStream("foo.txt");
else
System.out.println("test failed");
in.read(); // Compiler error because variable 'in' might be unassigned
변수가 두 번 이상 할당되지 않도록하여 범위 초과 범위를 권장하지 않습니다. 이 대신에 :
String msg = null;
for(int i = 0; i < 10; i++) {
msg = "We are at position " + i;
System.out.println(msg);
}
msg = null;
이것을 사용하는 것이 좋습니다.
for(int i = 0; i < 10; i++) {
final String msg = "We are at position " + i;
System.out.println(msg);
}
일부 링크 :
가능한 모든 변수를 선언하는 것에 대해 독단적 final
입니다. 여기에는 메소드 매개 변수, 로컬 변수 및 드물게 값 오브젝트 필드가 포함됩니다. 어디에서나 최종 변수를 선언해야하는 세 가지 주요 이유가 있습니다.
그러나 최종 클래스와 메소드는 최종 변수 참조만큼 유용하지 않다고 생각합니다. final
이러한 선언과 함께 사용할 때 키워드는 단순히 자동화 된 테스트하고 예상 적이없는 수 방법으로 코드의 사용에 장애물을 제공합니다.
final
변수 및 메서드 매개 변수는 바이트 코드로 표현되지 않으므로 성능에 영향을 미치지 않습니다.
효과적인 Java에는 "Favour immutable objects"라는 항목이 있습니다. 필드를 최종으로 선언하면이를 향한 몇 가지 작은 단계를 수행하는 데 도움이되지만 물론 그보다 불변의 객체는 훨씬 더 많습니다.
객체가 변경 불가능하다는 것을 알고 있다면 동기화 걱정없이 많은 스레드 / 클라이언트간에 읽기 위해 공유 할 수 있으며 프로그램 실행 방법에 대한 추론이 더 쉽습니다.
변수에 대한 최종 키워드를 사용하면 실수를 저 지르지 못하는 상황에 처한 적이 없으므로 지금은 엄청난 시간 낭비라고 생각합니다.
실제 변수에 대한 특정 포인트를 만들고자하는 것처럼 실제 이유가 없다면 코드를 읽기 쉽기 때문에 오히려 수행하지 않을 것입니다.
그러나 코드를 읽기 어렵거나 더 길게 작성하지 못하면 꼭 사용하십시오.
편집 : 설명 (및 다운 투표를 되찾기위한 시도)로서, 상수를 최종으로 표시하지 않는다고 말하는 것이 아니라 다음과 같은 일을하지 않는다는 것입니다.
public String doSomething() {
final String first = someReallyComplicatedExpressionToGetTheString();
final String second = anotherReallyComplicatedExpressionToGetAnother();
return first+second;
}
그것은 단지 내 의견으로는 코드를 읽기 어렵게 만듭니다.
또한 모든 최종 작업은 변수를 다시 할당하지 못하게하고 불변 또는 이와 유사한 것을 만들지 않는다는 것을 기억해야합니다.
final
(그리고 일반적으로 불변의 객체가) 수와 버그의 영향에 크게 기여 요인이 있었다.
최종 키워드 를 사용하는 것에 대한 가장 큰 논쟁 중 하나는 "불필요"하고 "공간 낭비"라는 것입니다.
우리가 여기에 많은 훌륭한 글에서 지적한 "최종"의 많은 이점을 인정한다면, 더 많은 타이핑과 공간이 필요하다는 것을 인정하면서 Java는 기본적으로 변수를 "최종"으로 만들었을 것입니다. 코더가 원하는 경우
final
"너무 오래 쓰기", "코드를 더 복잡하게 만든다" 는 것 외에는 논쟁이 없습니다 . 에 대한 몇 가지 주장이 final
있습니다. 직접 입력하지 않으려면 저장시 자동으로 추가 할 수 있습니다.
final
객체 속성에 항상 사용 합니다.
final
객체 속성에 사용할 경우 키워드는 가시성 의미를 가지고있다. 기본적으로 생성자가 반환하기 전에 최종 객체 속성 값을 설정합니다. 즉, this
참조가 생성자를 이스케이프 하지 않고 모든 속성에 사용 final
하는 한 객체는 (Java 5 의미론에서) 올바르게 구성되도록 보장되며 불변이므로 안전하게 게시 할 수 있습니다 다른 스레드에.
불변의 객체는 단순한 스레드 안전성이 아닙니다. 어떤 공간 때문에 그들은 또한, 프로그램의 상태 변화에 대한 이유를 쉽게 많이 만들 수 있습니다 지속적으로 사용 된 경우 변경 철저에만 것들로 제한, 의도적이고 해야 변경합니다.
때로는 방법을 최종적으로 만들지 만 자주는 아닙니다. 나는 거의 수업을 마무리하지 않습니다. 필요가 거의 없기 때문에 일반적으로이 작업을 수행합니다. 나는 일반적으로 상속을 많이 사용하지 않습니다. 대신 인터페이스와 객체 구성을 사용하는 것이 좋습니다. 이는 종종 테스트하기가 더 쉬운 디자인에 적합합니다. 구체적인 클래스 대신 인터페이스에 코드를 작성할 때 테스트 할 때 상속을 사용할 필요 가 없습니다. jMock과 같은 프레임 워크를 사용하면 콘크리트 클래스보다 인터페이스를 사용하여 모의 객체를 훨씬 쉽게 만들 수 있습니다.
나는 대부분의 수업을 최종적으로해야한다고 생각하지만 아직 아직 정식 교육을받지 못했습니다.
나는 직업을 위해 많은 코드를 읽어야한다. 인스턴스 변수에 final을 누락시키는 것은 나를 성가 시게하는 가장 중요한 것 중 하나이며 코드를 불필요하게 이해하는 것을 어렵게 만듭니다. 돈 때문에 지역 변수에 대한 최종 결과는 명확성보다 더 복잡합니다. 언어는 기본 언어로 설계되었지만 실수로 살아야합니다. 때로는 if-else 트리를 사용하여 루프 및 명확한 할당에 특히 유용하지만 대부분 메서드가 너무 복잡하다는 것을 나타내는 경향이 있습니다.
final 은 분명히 상수에 사용하고 불변성을 강제해야하지만 메소드에는 또 다른 중요한 용도가 있습니다.
효과적인 Java 에는 의도하지 않은 상속의 함정을 지적하는 전체 항목이 있습니다 (항목 15). 상속을 위해 클래스를 디자인하고 문서화하지 않은 경우 클래스에서 상속하면 예기치 않은 문제가 발생할 수 있습니다 (항목이 좋은 예를 제공함). 따라서 권장되지 않은 클래스 및 / 또는 메서드에서 final 을 사용하는 것이 좋습니다 .
그것은 드라코 니안처럼 보일지 모르지만 말이됩니다. 다른 사람이 사용하기 위해 클래스 라이브러리를 작성하는 경우 설계되지 않은 것에서 상속하지 않기를 원합니다. 역 호환성을 위해 클래스의 특정 구현에 자신을 고정시킬 것입니다. 팀에서 코딩하는 경우 팀의 다른 구성원이 실제로 필요한 경우 결승 을 제거하지 못하도록 막을 방법이 없습니다 . 그러나 키워드는 그들이하는 일에 대해 생각하게하고 그들이 상속하는 클래스가 그것을 위해 설계된 것이 아니라고 경고하므로주의해야합니다.
Java에서 변수와 함께 사용될 때 Final은 C ++에서 상수를 대체합니다. 따라서 final 및 static이 변수에 사용되면 변경할 수 없게됩니다. 동시에 이주 된 C ++ 프로그래머들을 매우 행복하게 만든다 ;-)
참조 변수와 함께 사용하면 개체를 조작 할 수 있지만 개체를 다시 참조 할 수 없습니다.
final을 메소드와 함께 사용하면 서브 클래스에서 메소드를 대체 할 수 없습니다.
사용법이 명확 해지면주의해서 사용해야합니다. 방법에 final을 사용하면 다형성에 도움이되지 않으므로 주로 디자인에 달려 있습니다.
변수의 값이 절대로 변경되지 않아야한다는 것을 확신 할 때 변수에 대해서만 사용해야합니다. 또한 SUN.에서 권장하는 코딩 규칙을 준수해야합니다. 예 : final int COLOR_RED = 1; (밑줄로 분리 된 대문자)
참조 변수를 사용하면 특정 객체에 대한 불변의 참조가 필요한 경우에만 사용하십시오.
가독성 부분과 관련하여 최종 수정자를 사용할 때 주석이 매우 중요한 역할을하도록합니다.
나는 지역 변수에 그것들을 사용하지 않으며, 추가 된 자세한 정보에 대한 지적은 거의 없습니다. 변수를 다시 할당해야한다고 생각하지 않더라도 다른 사람이 생각하는 코드를 변경하면 다음 사람과 거의 차이가 없으며 코드가 변경되므로 최종 변수를 만드는 원래 목적이 더 이상 유효하지 않을 수 있습니다. 그것이 명확성을위한 것이라면, 나는 그것이 세부의 부정적인 영향으로 인해 실패한다고 생각합니다.
상수의 경우를 제외하고는 거의 이점이 없으므로 멤버 변수에도 거의 동일하게 적용됩니다.
또한 불변성에 대한 가장 좋은 지표는 문서화되거나 객체를 변경할 수있는 방법이 없다는 것이므로 불변성과 관련이 없습니다 (클래스를 최종적으로 만드는 것뿐만 아니라 불변입니다).
그러나 이봐, 그건 내 의견이다 :-)
논쟁에 대해서는 필요하지 않다고 생각합니다. Mostley는 단지 준비 력을 상하게했다. 인수 변수를 다시 서명하는 것은 어리석은 바보이므로 어쨌든 상수로 취급 될 수 있다고 확신해야합니다.
이클립스가 마지막 빨간색으로 표시된다는 사실은 코드에서 변수 선언을 쉽게 발견 할 수있게 해주므로 대부분의 시간 동안 판독 능력을 향상시킵니다.
나는 모든 변수가 최종적이어야한다는 규칙을 시행하려고합니다. 그렇지 않은 극단적 인 이유가 없습니다. "이 변수는 무엇입니까?"라고 대답하는 것이 훨씬 쉽습니다. 당신이 initilization을 찾아야한다고 확신한다면 그것이 바로 그 질문입니다.
나는 실제로 최근에 비 최종 변수에 대해 다소 긴장합니다. 실에 칼을 걸고 머리를 굽거나 부엌 서랍을 두는 것의 차이점과 같습니다.
최종 변수는 값을 설정하는 좋은 방법입니다.
비 최종 변수는 버그가 발생하기 쉬운 알고리즘의 일부에 바인딩됩니다.
좋은 기능 중 하나는 알고리즘에서 변수를 사용하는 옵션이 대부분의 경우 해결 방법이 대신 메소드를 작성하는 것인데, 이는 일반적으로 코드를 크게 향상시킵니다.
나는 잠시 동안 코딩을 해왔고 가능할 때마다 final을 사용했습니다. 변수 (메소드, 메소드 매개 변수 및 클래스 속성)를 위해 잠시 동안이 작업을 수행 한 후 변수의 90 % 이상이 실제로 최종이라고 말할 수 있습니다. 나는 당신이 원하지 않을 때 변수를 수정하지 않으면 (이전에는 때로는 고통 스럽습니다) 코드에 여분의 타이핑과 여분의 "최종"키워드를 지불한다고 생각합니다.
즉, 언어를 디자인한다면 다른 키워드로 수정하지 않는 한 모든 변수를 최종적으로 만들 것입니다.
나는 클래스와 메소드에 final을 많이 사용하지 않는다고 생각했다. 클래스가 유틸리티 클래스가 아닌 경우 (이 경우 개인 생성자가 하나만 있어야 함) 다소 복잡한 디자인 선택입니다.
또한 Collections.unmodifiable ...을 사용하여 필요할 때 수정할 수없는 목록을 만듭니다.
이벤트 리스너에 익명 로컬 클래스를 사용하는 것은 Java에서 일반적인 패턴입니다. final 키워드의 가장 일반적인 용도는 범위 내의 변수가 짝수 리스너에 액세스 할 수 있도록하는 것입니다.
그러나 코드에 많은 최종 진술을 입력 해야하는 경우. 그것은 당신이 잘못하고있는 좋은 힌트 일 수 있습니다.
위에 게시 된 기사는 다음 예제를 제공합니다.
public void doSomething(int i, int j) {
final int n = i + j; // must be declared final
Comparator comp = new Comparator() {
public int compare(Object left, Object right) {
return n; // return copy of a local variable
}
};
}
클래스를 final로 표시하면 런타임 대신 컴파일 타임에 일부 메소드 바인딩이 발생할 수 있습니다. 아래의 "v2.foo ()"를 고려하십시오. 컴파일러는 B가 서브 클래스를 가질 수 없다는 것을 알고 있으므로 foo ()를 재정의 할 수 없으므로 호출 할 구현이 컴파일 타임에 알려집니다. 클래스 B가 final로 표시되지 않으면 실제 v2 유형은 B를 확장하고 foo ()를 대체하는 클래스 일 수 있습니다.
class A {
void foo() {
//do something
}
}
final class B extends A {
void foo() {
}
}
class Test {
public void t(A v1, B v2) {
v1.foo();
v2.foo();
}
}
상수에 final 을 사용 하는 것이 좋습니다. 그러나 메소드 또는 클래스에는 사용하지 않을 것입니다 (또는 적어도 잠시 동안 생각하십시오) . 불가능하지는 않지만 테스트를 더 어렵게 만듭니다 . 클래스 또는 메소드를 최종적으로 만들어야하는 경우이 클래스가 일부 인터페이스를 구현해야하므로 동일한 인터페이스를 구현 하는 모의를 가질 수 있습니다 .