숫자를 입력하는 칸이 있습니다
var number = readLine().toInt
여기 한글을 넣으면 Int로 변환할 수 없어 오류가 납니다
오류가 발생하면, 런타임 에러와 함께 앱이 비정상 종료됩니다
이를 방지하기 위해서
에러가 예상되는 경우 "예외처리"를 해야합니다
try {
} catch (타입) {
}
try { } 에는 정상 수행할 코드를 적습니다
괄호 () 속에는 에러의 타입을 적어줍니다. NumberFormatException 등이 있습니다.
catch() { } 에는 에러가 발생할 경우 예외적으로 수행할 코드를 적습니다
경고문구를 적어두면 좋겠네요
while(true){
try {
var number = readLine().toInt
break
} catch (NumberFormatException) {
println ("숫자만 입력하세요")
} finally {
<키보드 연결을 해제하는 코드>
}
}
잘못된 입력 -> catch 코드 -> while 반복 -> 정상적인 입력 -> try 코드 -> break
throw(타입)
에러가 예상될 경우, throw()로 예외를 던집니다
코드를 즉시 중단하고 코드를 거슬러올라가 "catch"코드를 찾아 예외처리합니다
만약 catch 코드가 없다면 앱이 종료됩니다
throw 뒤에 에러의 타입을 적어줍니다. NumberFormatException, IllegalArgumentException 등이 있습니다.
괄호 () 속에는 로그 안내문구를 적어줍니다
에러가 예상될 때마다 try 와 catch를 일일이 나눠적을 수 없으니
if () throw () 로 예외를 던지고 → 이전에 작성한 try - catch 문으로 예외를 처리하여
코드 양을 줄이는 것으로 이해했습니다
var 나이 = 3
val 종 = 푸들
변수, 상수를 선언하면 "초기값" 을 입력해야 합니다.
값이 없을 때 생기는 오류를 막기 위함입니다.
그러나 다수의 인스턴스를 생성할 때,
클래스가 가진 모든 프로퍼티에 전부 초기값을 대입하면
불필요한 정보로 인해 메모리가 낭비됩니다
그래서 지연초기화를 사용해,
불필요한 초기값을 유보하고 필요해졌을 때 값을 대입합니다
class 동물(){
lateinit var 이름:String
fun 자기소개() {
print (" 안녕! 나는 ${this.이름}이야 ")
}
}
lateinit var 으로 "초기값 없이 선언" 합니다
fun main(){
var 개 = 동물()
개.이름 = 돌돌이
개.자기소개()
}
인스턴스를 생성한 다음, 필요할 때 초기값을 대입하면 됩니다
class 동물(){
lateinit var 이름:String
fun 자기소개() {
if ( !this::이름.isInitialized ){
return
}
print (" 안녕! 나는 ${this.이름}이야 ")
}
}
단, 초기값을 대입하지 않고 없는 상태로 프로퍼티를 언급할 경우
런타임 에러로 앱이 종료됩니다
그래서 if 문으로 초기화 여부를 검사하는 과정을 넣어주는 것이 안전합니다
class 동물(){
val 국적 by lazy {
"한국"
}
fun 자기소개() {
print (" 저는 ${국적}에서 왔어요 ")
}
}
상수는 읽기 전용이라서 초기값 수정이 불가능합니다.
따라서 "초기값을 미리 설정" 해두되,
대입은 하지 않았다가 → 처음 언급될 때, 해당 초기값을 대입합니다
변수의 lateinit 은
애초에 초기값이 존재하지 않습니다. 인스턴스를 만들 때 새로운 초기값을 대입합니다.
상수의 by lazy는
미리 초기값을 설정해뒀습니다. 대입을 유보함으로서 메모리를 절약합니다.
원래 변수를 초기화(대입)하지 않으면
비어있음을 뜻하는 null 이 출력되어야 합니다
하지만 코틀린은 null 출력을 미연에 방지하기 위해
초기화를 강제하고, 값이 없을 시 컴파일 에러를 띄웁니다
따라서 만약 값이 없다는 정보를 표현하고 싶다면,
null을 별도로 허용해주어야 합니다
var name:String? = null
원래는 String 자료형에 null을 대입할 수 없습니다
자료형 뒤에 물음표 ( ? )를 붙여, 자료형을 널 허용 타입으로 설정했습니다
이제 변수에 null을 할당하여 비어있음을 표현할 수 있습니다
초기값으로 null을 대입해줍니다
null로 초기화 했기 때문에, 새로운 값을 대입하기 전까진 null, 즉 "비어있음" 상태입니다
println( "${ readLine()!!.toIntOrNull() }" )
var name:String? = null
null이 생길 가능성을 허용했다면
아래와 같이 null 을 감지하고 대응해야 합니다
print (" ${name?.length} ")
변수에 null 이 대입되었는지 검수합니다
만약 null이라면 .length 메서드를 실행하지 않습니다
print (" ${name? : "홍길동" } ")
변수에 null 이 대입되었는지 검수합니다
만약 null이라면 다음 "홍길동" 코드로 교체합니다
print (" ${name!!.length } ")
변수에 null이 대입될 경우, 런타임 에러가 발생합니다
null이 절대 없다는 확신이 있을 때만, 보증의 의미로 사용합니다
if (name != null) {
print (" ${name.length } ")
}
if 문을 활용해서 null 이 아닐 때만 명령이 동작하도록 체크하는 방법도 있습니다