Java | Inner class와 static

yeonk·2023년 3월 26일
1

java

목록 보기
1/3
post-thumbnail

시작하기 전에


우테코 레벨1 자동차 경주 미션을 할 때 Car 클래스 내부에 inner class로 Name 클래스를 구현하였다.

그런데 인텔리제이에서 Inner class may be static 라는 경고가 나왔고, 리뷰어가 static 을 사용한 이유에 대해 질문하셨다.

그래서 궁금증이 생겼고 공부해보게 되었다.






중첩 클래스(Nested Class)


Inner class에 대해서 알아보기 전에 중첩 클래스에 대해 먼저 알아보자.

오늘 중점적으로 알아보고자 하는 것은 중첩 클래스가 아니기 때문에 종류만 간단하게 알아본다. 중첩 클래스는 아래와 같이 분리할 수 있다.


  • 내부 클래스 (Inner Classes, Non-Static Nested Class)

    • 비정적 멤버 클래스 (Inner classes)

    • 지역 클래스 (Method local Inner classes)

    • 익명 클래스 (Anonymous Inner classes)


  • 정적 멤버 클래스 (Static Nested Classes)



이제 우리는 내부 클래스에 static을 붙여서 사용하냐 마냐가 아니라 비정적 멤버 클래스와 정적 멤버 클래스 중 어떤 것을 사용해야할까? 라고 생각해볼 수 있겠다.

(사실 용어의 차이긴 하지만 이렇게 구분을 해야 이해하기 더 쉽지 않을까?)

어쨌든 오늘은 중첩 클래스 중 비정적 멤버 클래스와 정적 멤버 클래스에 대해 알아볼 것이다.






비정적 멤버 클래스


class Outer { // 바깥 클래스
	class Inner {}; // 비정적 멤버 클래스
}

비정적 멤버 클래스의 특징은 아래와 같다.

  • 비정적 멤버 클래스의 인스턴스는 바깥 클래스의 인스턴스와 암묵적으로 연결된다.

  • 비정적 멤버 클래스의 인스턴스 메서드에서 바깥 인스턴스의 메서드 호출과 바깥 인스턴스의 참조를 가져올 수 있다.

  • 비정적 멤버 클래스의 인스턴스와 바깥 인스턴스 사이의 관계는 멤버 클래스가 인스턴스화 될 때 확립되며, 변경이 불가하다.

    • 이 때, 관계 정보는 비정적 멤버 클래스의 인스턴스 안에 만들어져 메모리 공간을 차지하고, 생성 시간도 더 걸린다.






정적 멤버 클래스


class Outer { // 바깥 클래스
	static class Inner {}; // 정적 멤버 클래스
}
  • 바깥 클래스 안에 선언하며, static을 붙여 사용한다.

  • static이 붙은 멤버들을 사용할 수 있다.

  • 외부 인스턴스 멤버에 직접 참조가 불가능하다.






외부 참조


멤버 클래스에 static을 생략하면 바깥 인스턴스로의 숨은 외부 참조를 갖게 된다.

  • 멤버 클래스에서 static을 생략하고 바깥 클래스의 멤버를 사용하지 않더라도 외부 참조는 존재한다.

  • 외부 참조의 문제점

    • 참조를 저장하기 위한 시간과 공간이 소비된다.

    • 가비지 컬렉션이 바깥 클래스의 인스턴스를 수거하지 못한다(메모리 누수).

    • 참조가 눈에 보이지 않기 때문에 문제 발생 시 원인 발견이 어려워진다.






결론


멤버 클래스의 인스턴스 각각이 바깥 인스턴스를 참조한다면 비정적으로, 그렇지 않으면 정적으로 만들어야 한다.

  • 개념상 중첩 클래스의 인스턴스가 바깥 인스턴스와 독립적으로 존재할 수 있다면 정적 멤버 클래스로 만들어야 한다.

  • 멤버 클래스에서 바깥 인스턴스에 접근할 일이 없다면 무조건 static을 붙여서 정적 멤버 클래스로 만들자.

  • 만약 static 키워드를 붙이고 싶지 않거나, 바깥 클래스와 중첩 클래스의 관계가 변경될 가능성이 있다면 중첩 클래스가 아닌 별도의 클래스로 작성한다.






참고 자료







0개의 댓글