Kotlin의 Inner class와 Nested class 차이, adapter의 viewHolder를 Inner classes로 선언하면 안되는 이유

관련 문서 링크 : Nested and inner classes | Kotlin (kotlinlang.org)

 

안드로이드 개발을 진행하던 중에 Inner class 사용에 대한 글을 읽었다.

Kotlin으로 개발을 진행할 때 Adater와 데이터와 레이아웃을 연결하는 ViewHolder를 사용한다.

 

inner class CalenderItemHolder(val binding: ItemCalendarBinding) : RecyclerView.ViewHolder(binding.root)

 

여태 ViewHolder를 사용할 때 inner 클래스로 선언했다.

사용 이유를 모르고 대부분의 개발자 코드에서 inner 클래스를 사용하길래 따라 사용했는데,

Inner class대신 Nested class를 사용을 권장하고 있었기에 그 차이와 이유를 알 필요가 있었다.

 

우선 알아야 할 점은 java와 kotlin의 멤버 클래스 차이다.

 

[java와 kotin에서의 inner classes, nested classes]

 

java에서는 데이터를 명시하지 않으면 inner classes로 나타낸다.

kotlin에서는 명시하지 않으면 Nested classes로 나타낸다.

 

Nested classes는 중첩 클래스로 클래스 내에 정의된 클래스이다. 

데이터를 중첩시켜서 한 번에 관리하는데 용이하다.

 

Inner classes는 내부 클래스로 자신을 둘러싼 외부 클래스가 인스턴스 변수와 메서드에 접근 가능하다.

외부 클래스의 private 멤버에 접근할 수 있다.

 

inner 클래스는 바깥의 외부 클래스가 생성되어야 생성된다.

즉 외부 클래스의 멤버변수 등이 필요하지 않은 경우에도 외부 클래스를 선언해야 한다.

 

[java에서 Inner classes가 기본 클래스인 이유]

 

java에서는 inner 클래스 사용 시 직렬화에 문제가 생긴다.

inner 클래스 사용 시 결국에 외부 클래스 정보를 추가로 보관하면서 메모리 누수가 발생할 수 있다.

따라서 java에서는 기본 클래스로 Nested classes를 선언하게 한다.

가능한 불필요한 메모리 낭비를 줄이기 위해서 기본값이 설정되는 것이다.

 

[kotlin에서 Nested classes가 기본 클래스인 이유]

코틀린은 자바를 보완해서 만들어진 언어이다.

즉 코틀린에서는 java의 문제점인 메모리 누수를 관리하는

방법을 가지고 있기에 더 효율적인 Nested classes를 선언한다고 한다.

 

두 언어 모두 개발자의 의도에 따라서 Inner로 선언할지, Nested로 선언할지 선택할 수 있지만,

언어적 특성에 따라서 기본 클래스를 설정해두면서 효율적이고 낭비가 적은 방법으로 코딩할 수 있도록 도와주는 것이다.

 

[Android RecyclerView에서 Adater 사용 시 문제점]

 

여태 ViewHolder를 선언할 때 기본 클래스인 Nested가 아닌 Inner class로 선언해주었다.

Inner 클래스로 사용한다는 것은 독립적으로 해당 내부 클래스를 사용한다는 것이다.

 

ViewHolder는 화면에 있는 사이즈만큼 view를 만드는 것이 아니라 

다음에 보일 부분까지 미리 ViewHolder를 호출해서 만들어둔다.

 

즉 ViewHolder를 Inner class로 선언하는 것은 Inner class 뿐만 아니라

외부 클래스까지 묵시적으로 참조되고 생성된다.

 

여태까지 이러한 방식으로 코딩하면서 문제가 없었던 이유는 안드로이드에서 

액티비티나 프래그먼트가 Destroy 되면 Adapter가 사라지면서 문제가 발생하지 않은 것이다.

하지만 굳이 필요 없는 부분까지 호출하면서 Inner 클래스를 사용하는 것은 좋지 않은 습관이다.

 

즉 Inner class를 꼭 사용해야 할 부분에서만 사용하되, 그렇지 않은 경우는 기본 클래스인 Nested class로 선언해야 한다.

 

개발을 하면서 불필요한 외부 클래스를 사용하지 않기 위해서 꼭 지켜야 할 사항이 되었다.