[Kotlin] 클래스 선언시 (소괄호), {중괄호}의 차이는? (Feat 변수 초기화)
✅ 개요
Hibernate를 이용한 엔티티 생성을 하다가
해당 내용을 정리할 필요성이 생겨서 가져왔다.
🤔
클래스를 선언할 때 (소괄호)와 {중괄호}는 어떤 역할을 할까?
각 자리에 선언되는 필드들은 어떤차이가 있을까?
✅ 예제 코드
메모라는 엔티티 클래스를 간단하게 만들었다.
소괄호 ( ) 안에 title을 선언,
중괄호 { } 안에 memoId, contents가 선언되어있다.
@Entity
@Table(name = "memo")
class Memo (
@Column(nullable = false, length = 30)
var title: String
) {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "memoId")
val memoId: Long? = null
@Column
var contents: String? = null
}
✍️ 생성자 매개변수를 지정하는 소괄호 ( )
소괄호는 주생성자의 매개변수로, Kotlin이 소괄호에 적혀있는 변수들을 기반으로 생성자를 자동 정의한다.
어디선가 Memo 엔티티를 생성할 때, 매개변수 title의 값을 반드시 넣어줘야한다.
val createdMemo = memoRepository.save(
Memo(title = "Kotlin은 무엇인가")
)
만약 모든 필드들이 초기화가 꼭 필요한 것들로만 구성되어있다면?
이 경우 아주 간단하게 엔티티를 정의하게 될것이다.
class Memo (
var title: String,
var contents: String? = null
)
위와 같이 소괄호 안에 정의만 해주어도 (구현부가 없어도) 될 정도로 코드가 간단해질 수 있다!
*** 코틀린스럽다 ***는 말을 할 수 있는 간단한 코드!
✍️ 클래스 본문, 중괄호 { }
중괄호 안에 선언되는 필드들은, 생성시에 매개변수가 필요가 없다.
단, 값을 지정해주고 싶을때 보조 생성자가 필요하다.
* constructor 키워드를 이용하면 보조 생성자를 만들 수 있다.
필수로 값이 들어오지 않기 때문에, 추후에 값을 할당하게 되는데
다양한 초기화 방법이 있다. (깊은 내용은 다음에 알아보자)
1) 즉시 초기화
선언과 동시에 초기화가 가능하다.
@Column
var contents: String? = "안녕하세요."
2) init을 통한 초기화
init블록을 사용해서 받은 매개변수에 추가적인 처리를 하면서 값을 할당해줄 수 있다.
class Memo(data: String) {
var contents: String
init {
contents = "Hello $data"
}
}
3) lateinit
나중에 초기화하도록 미리 알려주는 것.
var과 함께 사용한다. (나중에 초기화한다는 것 자체 == 변할 수 있는 값이라서 인듯)
어플리케이션이 동작중에 application.yml에 있는 값이 필요한 경우 가져오고 나중에 초기화하는것이 대표적인 예이다.
* 변수에 접근 전에 반드시 초기화 되어야한다.
class Memo {
lateinit var contents: String
}
4) optional ? 를 사용해 null초기화
PK로 사용되는 id 같은것은 DB에게 맡기는 경우가 많다.
이때 해당 변수에 ? 를 사용해 Null을 허용해주고, Null로 초기화 하는것이 대표적인 예!
@Entity
@Table(name = "memo")
class Memo () {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "memoId")
val memoId: Long? = null
}