Item 21: 인터페이스는 구현하는 쪽을생각해 설계해라
디폴트 메소드를 통해 기존 인터페이스에 메소드를 추가할 수 있음
유용하다만 기존 구현체와 충돌하지 않는지에 대한 고려 필요함
Item 22: 인터페이스는 타입을 정의하는 용도로만 사용하라
상수 인터페이스는 안티 패턴임
상수 클래스는 인스턴스할 수 없는 유틸리티 클래스로 만들어 사용하자)
public class Constants {
private Constants(){} // 인스턴스화 방지
public static final int ONE = 1;
}
Item 23: 태그 달린 클래스보다는 클래스 계층 구조를 활용하라
public class TagClass {
enum Type {
HOT, COLD
}
final Type type;
String hotName;
String coldName;
public TagClass(String hotName) {
this.type = Type.HOT;
this.hotName = hotName;
}
public TagClass(String coldName) {
this.type = Type.COLD;
this.coldName = coldName;
}
}
안티 패턴
클래스 계층 구조를 어설프게 흉내낸 구조
Item 24: 멤버 클래스는 되도록 static으로 만들라
중첩 클래스
정적 멤버 클래스
다른 클래스 안에 선언됨
바깥 클래스의 private 멤버에도 접근할 수 있음
비정적 멤버 클래스
비정적 멤버 클래스는 바깥 클래스의 인스턴스와 암묵적으로 연결됨
⇒ this를 사용해 바깥 클래스의 메소드나 인스턴스의 참조를 가져올 수 있음.
바깥 인스턴스에 접근할 일 없으면 무조건 정적으로 만들자
바깥 인스턴스로의 숨은 외부 참조를 갖게 되는 것은 시간과 공간 낭비 + GC를 속여 메모리 누수를 만들기도 함
익명 클래스
선언과 동시에 인스턴스가 만들어짐
비정적 문맥에서 사용될 때만 바깥 클래스의 인스턴스 참조 가능
⇒ 제약 많음, 현재 람다가 익명클래스의 역할 흡수
지역 클래스
어디서든 선언 가능
유효범위 == 지역변수
이름, 중복 사용 가능
비정적 문맥에서만 바깥 클래스의 인스턴스 참조 가능
정적 멤버 가질 수 없음
public class CoverClass {
int coverPrivateVar;
static String coverPrivateStaticVar;
public int coverPublicVar;
public static String coverPublicStaticVar;
public CoverClass() {
System.out.println("cover class init");
}
public void coverClassShouting(){
System.out.println("coverClass's Shouting");
}
static class NestedStaticClass{
public NestedStaticClass() {
System.out.println("nested static class init");
coverPrivateStaticVar = "3";
coverPublicStaticVar = "4";
}
}
class NestedClass{
public NestedClass() {
System.out.println("nested class init");
coverPrivateVar = 1;
coverPublicVar = 2;
coverPrivateStaticVar = "1";
coverPublicStaticVar = "2";
}
public void nestedClassShouting() {
System.out.println("nestedClass's Shouting");
}
public void callCoverShouting(){
CoverClass.this.coverClassShouting(); // 정규화된 this
}
}
public void testLocalInnerClass(){
class LocalInnerClass{
public LocalInnerClass() {
System.out.println("test local inner class init");
}
void localInnerShouting(){
System.out.println("inner class's 외침");
}
}
LocalInnerClass localInnerClass = new LocalInnerClass();
localInnerClass.localInnerShouting();
}
}
public class Main {
public static void main(String[] args) throws Exception {
CoverClass cover = new CoverClass();
CoverClass.NestedClass nestedClass = cover.new NestedClass();
nestedClass.nestedClassShouting();
nestedClass.callCoverShouting();
cover.testLocalInnerClass();
CoverClass.NestedStaticClass nestedStaticClass = new CoverClass.NestedStaticClass();
}
}
실행결과
cover class init
nested class init
nestedClass's Shouting
coverClass's Shouting
test local inner class init
inner class's 외침
nested static class init
Item 25: 톱레벨 클래스는 한 파일에 하나만 담아라
하나에 담는 이점은 없는 반면에 한파일에 여러개의 톱레벨 클래스가 있으면 컴파일러가 한 클래스를 여러가지로 정의할 수 있으며, 컴파일 순서에 따라 달라지는 문제 있음
반응형
'TIL > Java' 카테고리의 다른 글
[Java] Effective Java 3/E 4장 item 15~20 (0) | 2024.01.18 |
---|---|
[Java] Effective Java 3/E 3장 item 10~14 (1) | 2023.11.14 |
[JAVA] Java Version 8 vs 17 (0) | 2023.10.21 |
[Java] Effective Java 3/E item 7~9 (1) | 2023.06.13 |
[Java] Effective Java 3/E item 4~6 (0) | 2023.05.28 |
댓글