작성
·
17
0
태현님, 안녕하세요. 뭔가 하나 더 궁금해져서 질문을 드리게 되었습니다!
아래의 두 클래스가 있다고 가정해보겠습니다.
package me.sungbin.lec10
open class Base(
open number: String = "100",
) {
init {
println("Base Class")
println(number)
}
}
package me.sungbin.lec10
class Derived(
override val number: String,
) : Base() {
init {
println("Derived Class")
}
}
그리고 실제로 아래와 같이 Derived
클래스의 생성자를 호출하면 number값으로는 null이 출력됩니다.
여기서 궁금한 것은 number는 non-nullable한 타입인데 null이 왜 출력이 될까? 라는 궁금증이 생겼는데요..
그래서 GPT한테 물어보니 아래와 같은 답변을 얻을 수 있었습니다.
레퍼런스 타입(예:
String
) → JVM 기본값 null
이 출력됩니다. (Kotlin의 Non-null 보장도 생성 중(super 생성자 실행 중)에는 예외적으로 깨질 수 있습니다.)
이렇게 들으니 뭔가 이해가 된 듯 보이는데 이게 GPT 피셜이다보니 태현님의 의견이 듣고 싶어져서 질문을 남깁니다!
답변 2
0
0
안녕하세요, 인프런 AI 인턴입니다. 양성빈(Robert)님.
코틀린에서 상속을 사용하면서 발생하는 이슈에 대해 아주 좋은 질문을 주셨습니다. 말씀하신 상황은 클래스 생성자 호출 시점을 이해하는 데 매우 중요한 예시입니다.
코틀린에서는 클래스의 프로퍼티가 open
으로 선언되면 하위 클래스에서 이를 override
할 수 있습니다. 이때 상위 클래스의 init
블록에서는 하위 클래스의 override
된 프로퍼티 (number
)가 초기화되지 않은 상태에서 접근될 수 있습니다. 즉, 상위 클래스의 생성자가 호출될 때 하위 클래스의 프로퍼티가 아직 초기화되지 않았기 때문에, JVM의 기본값인 null
이 나타날 수 있습니다.
이는 코틀린에서는 특별한 경우로 간주될 수 있으며, 실제로 객체의 생성 과정에서 비동기적으로 순서 문제가 발생한 예시라고 볼 수 있습니다. 이 상황을 방지하기 위해 상위 클래스의 초기화 블록에서 open된 프로퍼티를 사용하지 않거나, 별도의 로직을 통해 접근을 제한하는 등의 해결책이 필요합니다.
이 주제에 대해 더 자세한 설명이 필요하시다면 이미 유사한 질문이 존재할 가능성이 큽니다. 아래 링크들을 참조하시면 문제 이해에 더 큰 도움이 될 것입니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.