정적이 아닌 내부 클래스에 사용 가능한 속성 액세스가 높은 커플 링을 초래하므로 코드 품질이 낮아지고 (익명 및 로컬이 아닌 ) 내부 클래스는 일반적으로 정적이어야 한다고 가정하는 것이 정확 합니다.
내부 클래스를 비 정적으로 만드는 결정에 대한 디자인의 의미는 Java Puzzlers , Puzzle 90 (아래 인용의 굵은 글꼴은 내 것임)에 나와 있습니다.
멤버 클래스를 작성할 때마다 스스로에게 물어보십시오.이 클래스에는 실제로 엔 클로징 인스턴스가 필요합니까? 대답이 '아니요'인 경우 확인하십시오 static
. 내부 수업은 때때로 유용하지만 , 프로그램을 이해하기 어렵게하는 복잡한 문제를 쉽게 도입 할 수 있습니다. 그들은 제네릭 (퍼즐 89), 리플렉션 (퍼즐 80), 상속 (이 퍼즐)과 복잡한 상호 작용을 합니다. 당신이 선언하면 Inner1
될 static
문제가 사라집니다. 당신은 또한 선언하면 Inner2
될 static
멋진 보너스를 참 : 실제로 프로그램이 무엇을하는지 이해할 수있다.
요약하면, 한 클래스가 다른 클래스의 내부 클래스와 서브 클래스 인 경우는 거의 없습니다. 더 일반적으로, 내부 클래스를 확장하는 것이 거의 적절하지 않습니다. 필요한 경우 둘러싼 인스턴스에 대해 길고 열심히 생각하십시오. 또한 static
중첩 클래스가 아닌 클래스를 선호합니다 static
. 대부분의 멤버 클래스는 선언 할 수 있으며 선언해야합니다 static
.
관심이 있으시면 Stack Overflow에서이 답변에 Puzzle 90에 대한보다 자세한 분석 이 제공됩니다 .
위의 내용은 본질적으로 Java 클래스 및 객체 자습서 에서 제공되는 확장 된 버전의 지침입니다 .
둘러싸는 인스턴스의 비공개 필드 및 메서드에 액세스해야하는 경우 비 정적 중첩 클래스 (또는 내부 클래스)를 사용하십시오. 이 액세스가 필요하지 않은 경우 정적 중첩 클래스를 사용하십시오.
그래서, 질문에 대한 대답은 당신이 묻는 즉 튜토리얼 당이다, 유일한 설득력 이유 클로징 인스턴스의 비공개 필드 및 메소드에 액세스 할 때 비 정적을 사용할 수있다 필요 .
튜토리얼 문구는 다소 광범위합니다 (이것이 Java Puzzlers가 그것을 강화하고 좁히려 고 시도하는 이유 일 수 있습니다). 특히, 엔클로저 인스턴스 필드에 직접 액세스 하는 것은 필자의 경험에서 실제로 필요한 적이 없었습니다. 이를 생성자 / 메소드 매개 변수로 전달하는 것과 같은 대체 방법은 항상 디버그 및 유지 관리가 쉬워졌습니다.
전반적으로, 둘러싼 인스턴스의 필드에 직접 액세스하는 내부 클래스를 디버깅하는 나의 (아주 고통스러운) 만남은이 연습이 관련된 알려진 악과 함께 전역 상태의 사용과 유사하다는 강한 인상을 남겼 습니다.
물론 Java는 그러한 "quasi global"의 손상이 둘러싼 클래스에 포함되도록 만들지 만 특정 내부 클래스를 디버깅해야 할 때 그러한 밴드 보조가 고통을 줄이는 데 도움이되지 않는 것처럼 느꼈습니다. 특정 번거로운 대상의 분석에 전적으로 초점을 맞추는 대신 "외국 적"의미 및 세부 사항을 명심하십시오.
완전성을 위해 위의 추론이 적용되지 않는 경우 가 있을 수 있습니다 . 예를 들어 map.keySet javadocs를 읽을 때 마다이 기능은 긴밀한 결합을 제안하며 결과적으로 비 정적 클래스에 대한 인수를 무효화합니다.
Set
이 맵에 포함 된 키 의 뷰를 반환합니다 . 세트는 맵에 의해 지원되므로 맵에 대한 변경 사항이 세트에 반영되며 그 반대도 마찬가지입니다.
위의 방법으로 어떻게 든 관련 코드를 유지 관리, 테스트 및 디버그하기가 더 쉬울 수는 없지만 의도 한 기능으로 인해 합병증이 일치 / 정당화 될 수 있다고 주장 할 수 있습니다.