[android : kotlin] 코틀린 const, final, companion object 개념과 사용방법 및 예제
코틀린 const
const는 상수이며 자바에서 static final과 동일한 역할을 한다.
자바에서
final static String PRE_STATUS = "FIRST";
코틀린에서는
const val PRE_STATUS: String = "FIRST"
안드로이드 스튜디오에서 비어있는 Fragment 레이아웃을 생성하게되면 자동으로 생성되는 코드이다. (MyFragment1.kt)
const val를 사용하여 클래스 밖 최 상단에 파라미터 2개가 선언되어 있다.
ARG_PARAM1과 ARG_PARAM2는 읽기 전용이며, 값을 변경할 수 없다. 그리고 getter()가 없다.
package edu.kotlin.study
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
class MyFragment1 : Fragment() {
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_my1, container, false)
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment MyFragment1.
*/
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
MyFragment1().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}
위 예제 코드 처럼 전역변수로 선언하거나 아래 코드 처럼 companion object 안에서만 const 선언이 가능하다. const키워드가 붙은 필드는 @JvmField가 붙은 정적 필드가 된다. 보통 클래스는 동적으로 객체를 생성한다. 그러나 정적으로 고정하고 싶은 경우가 있다. 자바에서는 static으로 변수와 객체를 선언하면 된다. 코틀린에서는 정적으로 처리하기 위해 컴페니언 객체로 사용한다. 프로그램 실행 시 고정적으로 가지는 메모리로 객체 생성 없이 사용가능하다. 하지만 자주 사용되지 않는 변수나 객체를 만들면 메모리 낭비가 된다.
companion object {
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
@JvmStatic
fun newInstance(param1: String, param2: String) =
MyFragment1().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
@JvmField
해당 필드는 자바에서 정적 메서드로 사용하도록 하며, getter와 setter을 작성하지 않는다.(불필요)
@JvmStatic
해당 필드는 자바에서 정적 메서드를 갖도록 하며, 해당 필드를 private로 선언하고 getter과 setter을 작성한다.
코틀린 문서에서 정적 필드는 @JvmField로 설명하고 정적 메서드는 @JvmStatic으로 설명한다.
fun main() {
println(UserInfo.language)
UserInfo.language = "ENGLISH"
println(UserInfo.language) //정적변수임으로 호출가능
UserInfo.work()
//println(UserInfo.name) // name은 컴패니언 객체가 아니므로 오류가 난다.데이터 초기화 필요
println(UserInfo(0).name)
println(UserInfo(1,"Who are you").name)
}
//컴패니언 객체는 실제 객체의 싱글톤(singleton)으로 정의된다.
class UserInfo {
var id: Int = 0
var name: String? = "IU"
constructor(_id: Int, _name: String="No comment") {
this.id = _id
this.name = _name
}
companion object {
var language: String = "KOREAN"
fun work() {
println("Working here.....$language")
}
}
}
[실행결과]
KOREAN
ENGLISH
Working here.....ENGLISH
No comment
Who are you
[REFERENCE]