java-get-together / effective-java

이펙티브 자바 스터디
0 stars 0 forks source link

Chpater 04. Item22~24 [Q&A] #8

Open y00njinuk opened 1 year ago

y00njinuk commented 1 year ago
jhjhj0366 commented 1 year ago

바깥 클래스에 대한 gc 작업이 왜 안되는걸까? (p.148 Line 1)

(아... 막상 정리하고 보니, 글이 약간 질문에 벗어난 것 같지만.... non-static 으로 선언하여 클래스를 사용하면, 외부 클래스를 fianl로 잡고 있어서, gc 가 안됩니다. 정확히 gc가 안되는 과정과 이유에 대해서는 추후 다시 찾아서 보충하겠습니다. 👀)

중첩 클래스는 크게 staticnon-static으로 나뉜다. 왜 가능하면 static으로 선언하라고 하는 것일까?

그 이유는 인스턴스 연결로 인한 낭비 때문 non-static 특징 중 하나는 바깥 클래스의 인스턴스와 연결되어 있다는 것인데

연결을 직접 확인해보면 ...

  1. 아래와 같은 클래스를 선언하고
    class Outer {
    static class StaticNested {}
    class NonStaticNested {}
    }
  2. 컴파일된 class 파일을 아래의 명령어를 이용하여 disassembles 해봅시다.
    javap -p "작성한_코드의_클래스_파일"
  3. 결과 확인
    • non-static → 외부 참조 저장 O
    • static → 외부 참조 저장 X

image

✅ 참고 javap의 -p 옵션은 모든 클래스와 멤버를 보여줌(-private 옵션과 같음)

바깥 객체 참조 유지로 인한 낭비

static을 생략한 모든 inner 객체는 내부적으로 바깥 객체에 대한 참조를 유지하게 됨

참고 글

https://woowacourse.github.io/javable/post/2020-11-05-nested-class/

https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javap.html

https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

this-is-spear commented 1 year ago

비정적 내부 클래스를 호출해서 사용한다면 외부 클래스 인스턴스를 호출해서 사용해야 하는군요!!

void foo(){
    A a = new A();
    A.B b = a.new B();
}
//or
void foo(){
    A.B b = new A().new B();
}

비정적 내부 클래스는 코드 가독성 측면에서도 매우 불리한 방식인 것 같습니다. @jhjhj0366 유익한 글 감사합니다 🙇‍♂️