[Kotlin] 지연초기화, 널 세이프티

[Kotlin] 지연초기화, 널 세이프티

지연초기화와 널 세이프티에 대해서 알아보자


01) 지연초기화

  • 지연초기화란 변수나 상수값을 나중에 초기화 할 수 있는 것이다.

  • 코틀린은 클래스를 설계할 때 안정성을 위해 반드시 변수의 값을 초기화할것을 권장한다.
  • 이 때 클래스를 설계할 때 초기의 값을 나중에 대입하기 위한 문법이다.

Kotlin의 지연초기화

lateinit : 변수를 지연 초기화 하기 위해 사용
lazy : 상수를 지연 초기화 하기위해 사용

지연초기화의 장점

  • 저사향으로 제한되어있는 환경에서 메모리를 효율적으로 사용 가능하다.

예시코드

  • 변수의 지연초기화
    fun main(){
        var s1 = Student()
        s1.name = "참새"
        s1.displayInfo()
      
        s1.age = 10
        s1.displayInfo()
    }
      
    class Student {
        lateinit var name:String //name값을 지연초기화 하기위해 lateinit 사용
        var age:Int = 0
      
        fun displayInfo() {
            println("이름은: ${name} 입니다.")
            println("나이는: ${age} 입니다.")
        }
    }
    
    • 고급사용
    fun main(){
        var s1 = Student()
        s1.name = "참새"
        s1.displayInfo()
      
        s1.age = 10
        s1.displayInfo()
    }
      
    class Student {
        lateinit var name:String
        var age:Int = 0
      
        fun displayInfo() {
    				if(this::name.isInitialized) { //값이 초기화 되어있는지 확인
    	        println("이름은: ${name} 입니다.")
    	        println("나이는: ${age} 입니다.")
    				} else {
    					println("name변수를 초기화해주세요.")
    				}
        }
    }
    
  • 상수의 지연초기화
    fun main(){
        var s1 = Student()
        s1.name = "참새"
        s1.displayInfo()
      
        s1.age = 10
        s1.displayInfo()
    }
      
    class Student {
        lateinit var name:String
        var age:Int = 0
        val address: String by lazy {
            println("address 초기화")
            "seoul"
        }
      
        fun displayInfo() {
            println("이름은: ${name} 입니다.")
            println("나이는: ${age} 입니다.")
            println("주소는: ${address} 입니다.")
        }
    }
    

02 ) 널 세이프티

  • Kotlin의 Null 안정성을 향상시켜준다.
  • Null 예외는 프로그램의 가용성을 저하시키는 오류이다.
  • Kotlin은 안전한 설계를 위해 자료형에 Null 여부를 명시할 수 있다.

Null Safety방법

  • Null 예외로부터 안전한 설계를 위한 다양한 키워드들을 지원한다.
  • Null 예외를 피하기 위해 Kotlin에서는 ?, !!, ?., ?: 등을 사용한다.
  • 여기서 !! 는 강제로 Null값이 아니라고 설정해주는 것이므로 최대한 사용을 지양하자

예시코드

1. address변수를 null값 저장이 가능하도록 String? 으로 선언한다.
fun main(){
    var s = Student()
    s.name = "참새"
    s.address = "서울"
    s.displayInfo()
}

class Student {
    lateinit var name:String
    var address:String? = null // Null Safety! [?]
    
    fun displayInfo() {
        println("이름은: ${name} 입니다")
        println("주소는: ${address} 입니다")
    }
}
2. 메소드를 호출한 후 리턴값이 null이 아니라고 !! 로 보증한다.
fun main(){
//  var data = readLine()!!.toInt()

    var inputData = readLine()!! // Null Safety! [!!]
    var data = inputData.toInt()
    println("Null아닌 값: ${data}")
}
3. Null인지 확인하고 Null이 아닐때만 참조하는 메소드를 실행하기위해 ?. 사용
  • 주소값을 갖는 address는 초기값이 null로 설정되어 있기 때문에 Null 위협에 놓여있다.

  • Null이 아님을 보장할 때 강제로 !! 를 사용하는 것은 옳지 않다.
  • 그래서 안전호출 연산자(safe-calls)?. 을 사용한다.!
fun main(){
    var s = Student()
    s.name = "참새"
    s.displayAddressLength()
    
    s.address = "서울"
    s.displayInfo()
}

class Student {
    lateinit var name:String
    var address:String? = null

    fun displayInfo() {
        println("이름은: ${name} 입니다")
        println("주소는: ${address} 입니다")
    }
    
    fun displayAddressLength() {
        println("주소의 길이는: ${address?.length} 입니다")// safe calls 사용! [?.]
    }
}
4. ?. 키워드로 안전하게 실행한 후 null이 출력되는것을 막고싶다면?
  • ?: 키워드를 사용해 null 대신에 다른 문자열을 출력하도록 가능하다.
  • ?:엘비스 연산자 라고한다.
fun main(){
    var s = Student()
    s.name = "참새"
    s.displayAddressLength()

    s.address = "서울"
    s.displayInfo()
}

class Student {
    lateinit var name:String
    var address:String? = null

    fun displayInfo() {
        println("이름은: ${name} 입니다")
        println("주소는: ${address} 입니다")
    }
    
    fun displayAddressLength() {
        println("주소의 길이는: ${address?.length ?: "초기화하세요"} 입니다") //엘비스 연산자 함께 사용! [?:]
    }
}

© 2023. All rights reserved.

AgileCatch