코틀린에서 변수는 2가지로 나뉘어 진다.

 

//가변 타입 변수
var 변수명: 타입

//읽기 전용 변수(불변 타입)
val 변수명: 타입

 

val

  • 값을 초기화만 가능하고, 변경은 불가능(변경 시, compile 에러 발생)
    *java에서 final과 같음.
  • 컴파일러가 코드 문맥을 확인시 val 변수가 한번만 초기화 되는것이 맞다면 개발자가 상황에 따라 val를 여러 값으로 초기화(할당) 할 수 있음.
  • 변수의 참조가 가리키는 객체의 내부 값은 변경이 가능.
 //코드 문맥에 따라 val 변수가 1번만 초기화 되는것이 맞다면 코드 상으로는 여러 값을 초기화 가능(예시 처럼 조건문 사용시,)
  val name: String 
  
  if (isSuccess()){ 
    name = "Anroid" 
  }else{ 
    name = "iOS"
  }
  println("name : $name")
  
  //변수의 참조가 가리키는 객체의 내부 값은 변경이 가능
  //ArrayList 는 MutableList 인터페이스를 상속받은 구현체임
  val nameArray = arrayListOf("Kotlin")
  nameArray.add("Java")
  println("nameArray : $nameArray")
  
  //더 직관적인 예시
  //mutableListOf는 가변 객체
  val numbers = mutableListOf(1, 2, 3, 4)
  numbers.add(5)  // 리스트에 5를 추가할 수 있음
  numbers[0] = 0  // 첫 번째 요소를 0으로 변경할 수 있음
  println(numbers)  // 출력: [0, 2, 3, 4, 5]
  
  //ListOf는 불변 객체
  val numbers = listOf(1, 2, 3, 4)
  // numbers.add(5)  // 오류: Unresolved reference: add
  // numbers[0] = 0  // 오류: Val cannot be reassigned
  println(numbers)  // 출력: [1, 2, 3, 4]

 

var

  • 값을 초기화한 후, 변경 가능(가변 변수)
    *다른 타입의 값을 넣을 수는 없음.(형변환은 가능)
//초기화 후 값 변경 가능
  var name1 = "kotlin" 
  name1 = "java"
  println("name1 : $name1")
  
  //초기화 시 타입을 지정 했다면 다른 타입의 값을 넣는 것은 불가능
  var name2 = "kotlin" 
  name2 = 77 //Type mismatch 에러 발생

 

const

  • val와 같이 불변 타입 선언을 위함.

val 와 const의 차이점

  • const val는 컴파일 시점에 값을 할당하지만, val은 런타임 시점에 값을 할당함. 
    *즉 val은 불완전한 불변성을 가지고 있음.
  • val은 java에서 final. const val은 java에서 static final을 의미.
  • val은 불완전한 불변성을 가지고 있기에, const val 사용을 추천.
// val 키워드를 통해 상수를 선언
object Constants {
    const val NAME = "Rin"
}

fun testValWithoutConst() {
    val name = Constants.NAME
}

 

컴파일러는 컴파일 시점에 이미 NAME 상수가 어떤 값을 가지고 있는지 알 수 있다. 때문에 값으로 대체가 가능하다.

즉 NAME이 "Rin"으로 인라인 되면서, 값을 참조할 때마다 상수에 접근하면서 발생하는 오버헤드를 줄일 수 있다.