TIL/Java

[Java] Effective Java 3/E 3장 item 21~25

JoJobum 2024. 1. 20.

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

댓글