Java는 변수 (필드 / 로컬 / 매개 변수)를로 표시하여 변수에 final
재 할당되지 않도록합니다. 일부 속성 또는 전체 클래스가 변경 불가능한지 여부를 신속하게 확인할 수 있으므로 필드에 매우 유용합니다.
반면에 로컬 및 매개 변수에는 그다지 유용하지 않으며 일반적 final
으로 다시 할당되지 않는 것처럼 표시하지 않습니다 (내부 클래스에서 사용해야하는 경우는 예외) . 그러나 최근에는 가능한 한 final을 사용하는 코드를 사용하여 기술적으로 더 많은 정보를 제공한다고 생각합니다.
내 프로그래밍 스타일에 대해 더 이상 확신을 가지지 않고, final
어디에서든 적용 할 때 의 다른 장단점 , 가장 일반적인 산업 스타일 및 이유를 궁금합니다.
답변
나는 final
당신과 같은 방식으로 사용합니다. 나에게 로컬 변수와 메소드 매개 변수에 불필요한 것처럼 보이며 유용한 추가 정보를 전달하지 않습니다.
한 가지 중요한 점은 각각 단일 작업을 수행하는 방법을 짧고 깨끗하게 유지 하려고 노력하는 것입니다 . 따라서 내 로컬 변수 및 매개 변수는 범위가 매우 제한되어 있으며 단일 목적으로 만 사용됩니다. 이렇게하면 실수로 다시 할당 할 가능성이 최소화됩니다.
또한 확실히 아시다시피 final
(기본이 아닌) 변수의 값 / 상태를 변경할 수 있다고 보장하지는 않습니다. 한 번 초기화되면 해당 객체에 대한 참조 를 다시 할당 할 수 없습니다 . 즉, 기본 또는 불변 유형의 변수에서만 완벽하게 작동합니다. 치다
final String s = "forever";
final int i = 1;
final Map<String, Integer> m = new HashMap<String, Integer>();
s = "never"; // compilation error!
i++; // compilation error!
m.put(s, i); // fine
이것은 많은 경우에 여전히 코드 내부에서 발생하는 상황을 이해하기가 쉽지 않으며,이를 오해하면 실제로 감지하기 어려운 미묘한 버그가 발생할 수 있습니다.
답변
Java 프로그래밍 스타일과 생각은 훌륭합니다. 의심 할 필요는 없습니다.
다른 한편으로, 나는 지역과 매개 변수에 대해 훨씬 덜 유용하다는 것을 알았습니다. 일반적으로 다시 할당되지 않을지라도 최종으로 표시하지 않습니다 (내부 클래스에서 사용해야 할 때 명백한 예외는 제외) ).
이것이 바로 final
키워드 를 사용해야하는 이유 입니다. 당신은 상태 당신이 그것을 다시 할당되지 않을거야 알고 있지만, 아무도 그것을 모른다. final
즉시 사용하면 코드가 조금 더 명확 해집니다.
답변
가능한 곳에서 final
/ 를 사용하는 것의 한 가지 장점은 const
코드 리더의 정신 부하를 줄인다는 것입니다.
그는 값 / 참조가 나중에 변경되지 않는다는 것을 확신 할 수 있습니다. 따라서 그는 계산을 이해하기 위해 수정에주의를 기울일 필요가 없습니다.
순수한 함수형 프로그래밍 언어를 배우고 나서 이것에 관해 마음이 바뀌 었습니다. 당신은 항상 초기 값을 유지하기 위해 “변수”를 신뢰할 수 있다면 소년, 얼마나 안심.
답변
final
메서드 매개 변수와 로컬 변수에서 코드 노이즈 라고 생각 합니다. Java 메소드 선언은 상당히 길 수 있으며 (특히 제네릭의 경우) 더 이상 만들 필요가 없습니다.
단위 테스트가 올바르게 작성된 경우 “유해한”매개 변수에 할당하면 선택되므로 실제로 문제 가되지 않습니다 . 비주얼 선명도는 피보다 더 중요 할 수 단위 테스트가 불충분 한 범위를 가지고 있기 때문에 포착되지 않는 버그.
FindBugs 및 CheckStyle과 같은 도구는 매개 변수 또는 로컬 변수에 할당 된 경우 빌드를 중단하도록 구성 할 수 있습니다.
당신이 경우 물론, 필요 하면, 익명의 클래스 다음 문제를 값을 사용하지 않고 있기 때문에, 예를 들어, 그들이 최종 만들기 위해 – 그 간단한 깨끗한 솔루션입니다.
매개 변수에 추가 키워드를 추가하여 IMHO를 위장하는 명백한 효과 외에도 메서드 매개 변수에 final을 추가하면 메서드 본문의 코드가 읽기 어려워 져 코드가 더 나빠질 수 있습니다. 가급적 읽기 쉽고 간단해야합니다. 고안된 예를 들어 대소 문자를 구분하지 않는 방법이 있다고 가정 해보십시오.
없이 final
:
public void doSomething(String input) {
input = input.toLowerCase();
// do a few things with input
}
단순한. 깨끗한. 모두 무슨 일이 일어나고 있는지 알고 있습니다.
이제 ‘최종’으로 옵션 1 :
public void doSomething(final String input) {
final String lowercaseInput = input.toLowerCase();
// do a few things with lowercaseInput
}
매개 변수를 만들면 final
코더가 원래 값으로 작업하고 있다고 생각하는 것보다 코드를 더 추가하는 것을 막을 수는 있지만 코드가 더 이상 사용 input
하지 않을 수도 lowercaseInput
있습니다. t은 범위를 꺼내 (또는 지정 null
에 input
그조차 어쨌든 도움이 될 경우).
‘최종’으로 옵션 2 :
public void doSomething(final String input) {
// do a few things with input.toLowerCase()
}
이제 더 많은 코드 노이즈가 생성되었으며 toLowerCase()
n 번 호출해야하는 성능 저하가 발생 했습니다.
‘최종’으로 옵션 3 :
public void doSomething(final String input) {
doSomethingPrivate(input.toLowerCase());
}
/** @throws IllegalArgumentException if input not all lower case */
private void doSomethingPrivate(final String input) {
if (!input.equals(input.toLowerCase())) {
throw new IllegalArgumentException("input not lowercase");
}
// do a few things with input
}
코드 노이즈에 대해 이야기하십시오. 이것은 열차의 잔해입니다. 다른 코드가 잘못 호출 할 수 있기 때문에 필요한 예외 블록 인 새로운 메소드가 있습니다. 예외를 다루기 위해 더 많은 단위 테스트. 하나의 단순하고 IMHO가 바람직하고 무해한 라인을 피하십시오.
메서드가 너무 길어서 시각적으로 쉽게 받아 들여서 매개 변수에 대한 할당이 한 눈에 알 수없는 문제도 있습니다.
매개 변수에 할당하면 매번 메서드의 초기, 바람직하게는 기본 입력 확인 후 첫 번째 줄 또는 직선 으로 수행하여 전체 메서드에 대해 효과적으로 대체 하는 것이 좋은 습관 / 스타일이라고 생각합니다 . 방법. 독자들은 과제가 명확하고 (서명 선언 근처에) 일관된 위치에있을 것으로 기대하므로 final 추가가 피하려고하는 문제를 크게 완화 할 수 있습니다. 실제로 나는 매개 변수에 거의 할당하지 않지만, 그렇게하면 항상 메서드 상단에서 수행합니다.
참고 또한이 final
실제로 당신이 처음에 같은 수 있습니다 보호하지 않습니다 같다 :
public void foo(final Date date) {
date.setTime(0);
// code that uses date
}
final
매개 변수 유형이 원시적이거나 변경 불가능한 경우가 아니면 완전히 보호 할 수 없습니다.
답변
final
프로그램을 읽기 쉽도록 만들기 위해 각 로컬 변수 앞에 일식을 넣었 습니다. 나는 매개 변수 목록을 가능한 한 짧게 유지하기를 원하기 때문에 매개 변수로 만들지 않습니다. 이상적으로는 한 줄에 맞아야합니다.