코틀린에서는 클래스에 하나의 primary constructor와 원하는 만큼의 secondary constructors가 있을 수 있습니다. Java와의 차이점은 코틀린의 primary constructor가 클래스의 헤더에 선언되어 매개변수와 수정자를 포함할 수 있다는 것입니다. Secondary 생성자는 항상 다른 secondary 생성자, primary constructor 또는 상위 클래스의 생성자(super 키워드 사용)를 호출해야 합니다.
주요 특징:
: super(...)를 통해 이를 명시적으로 호출해야 합니다.super(...) 또는 다른 secondary/primary constructor를 통해 호출됩니다.상속 사용 예:
open class A(val a: Int) { constructor(a: Int, str: String) : this(a) { println("Secondary in A: $str") } } class B : A { constructor(a: Int) : super(a) { println("Secondary in B") } constructor(a: Int, s: String) : super(a, s) { println("Secondary #2 in B") } }
Java와의 접근 방식 차이:
코틀린에서 자식 클래스를 만들 때, 기본 클래스에 특정 생성자만 있을 경우 상위 생성자를 명시적으로 호출하지 않을 수 있습니까?
답변: 아니요, Java와는 달리 코틀린에서는 상위 생성자를 호출하는 것이 필수이며, 이는 클래스의 "헤드"에서 또는 : super() 키워드 뒤에 명시적으로 지정해야 합니다.
오류 예시:
open class Base(val x: Int) class Derived : Base // 컴파일 오류!
이야기
마이크로서비스 프로젝트에서 코틀린으로 마이그레이션한 후 상위 생성자의 명시적 호출을 잊어버렸습니다: 필수 매개변수를 가진 상위 클래스 생성자가 호출되지 않아 서비스가 컴파일되지 않았고, 서명 수정이 필요했습니다.
이야기
안드로이드 프로젝트에서 깊은 계층 구조(Activity → BaseActivity → CustomActivity)가 있었고, secondary constructor를 추가하면서 매개변수를 잃어버リ, 잘못된 기본 생성자가 호출되어 일부 필드가 null로 남아 런타임 중 NPE로 앱이 종료되었습니다.
이야기
오픈 소스 라이브러리 코드에서 자식 클래스의 secondary constructor가 우연히 primary constructor를 우회하여 초기화 경로가 두 개가 되는 바람에 때때로 필드가 초기화되거나 그렇지 않은 문제가 발생했습니다. 이 오류는 복잡한 버그 리포트를 통해 오랜 시간이 지나서야 발견되었습니다.