포스트

Kotlin의 중첩 클래스 다루기


중첩 클래스의 종류

Java - 어딘가에 소속되어 있는 클래스, 여러 종류가 있었다.

  • static을 사용하는 중첩 클래스
    • 클래스 안에 static을 붙인 클래스는 밖의 클래스에 직접 참조 불가


  • static을 사용하지 않는 중첩 클래스
    • 내부 클래스 - Inner Class
      • 클래스 안에 클래스 - 밖의 클래스 직접 참조 가능
    • 지역 클래스 - Local Class
      • 메서드 내부에 클래스 정의 (사용할 일 거의 없음)
    • 익명 클래스 - Anonymous Class
      • 일회성 클래스


중첩 클래스 2가지

  • static을 사용하는 중첩 클래스
  • static을 사용하지 않는 내부 클래스 - Inner Class


Java 중첩 클래스 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class JavaHouse {

  private String address;
  private LivingRoom livingRoom;

  public JavaHouse(String address) {
    this.address = address;
    this.livingRoom = new LivingRoom(10);
  }

  public LivingRoom getLivingRoom() {
    return livingRoom;
  }

  public class LivingRoom {
    private double area;

    public LivingRoom(double area) {
      this.area = area;
    }

    public String getAddress() {
      return JavaHouse.this.address;
    }
  }
}
  • static을 사용하지 않는 경우 LivingRoomJavaHouse의 직접적인 참조를 가지고 있다.
  • static을 사용하는 경우 LivingRoomJavaHouse의 직접적인 참조가 없다.


Effective Java 3rd Edition - Item24, Item86

  • 내부 클래스는 숨겨진 외부 클래스 정보를 가지고 있어, 참조를 해지하지 못하는 경우 메모리 누수가 생길 수 있고 디버깅이 힘듦
  • 내부 클래스의 직렬화 형태가 명확하게 정의되지 않아 직렬화에 있어 제한이 있다.
  • 즉, 중첩 클래스를 작성하는 경우에는 클래스 안에 클래스에 static을 사용


Kotlin의 중첩 클래스와 내부 클래스

Kotlin의 중첩 클래스 (권장되는 방법)

1
2
3
4
5
6
7
8
9
class House(
    private val address: String,
    private val livingRoom: LivingRoom
) {

    class LivingRoom(
       private val area: Double
    )
}
  • 기본적으로 Kotlin은 밖의 클래스에 대한 연결이 없는 중첩 클래스로 작성된다.


Kotlin의 중첩 클래스 (권장되지 않는 방법)

1
2
3
4
5
6
7
8
9
10
11
12
class House(
    private val address: String,
    private val livingRoom: LivingRoom
) {

    inner class LivingRoom(
       private val area: Double
    ) {
        val address: String
            get() = this@House.address
    }
}
  • 권장 되지 않는 방법의 내부 클래스 특징
    • 내부 클래스에 inner라는 키워드를 붙여야 한다.
    • 밖의 클래스를 참조할 때는 this@밖의 클래스를 사용


Kotlin Guide

  • 기본적으로 내부 클래스가 밖의 클래스를 참조하지 않도록 되어 있다.
  • 굳이 참조하는 경우는 inner키워드를 내부 클래스에 사용해야 한다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.