[kotlin] 예외 처리 (try-catch-finally)
try-catch-finally
fun main(args: Array<String>){
try {
println("try top...")
val data: String = "Son"
val intData: Int? = data.toInt()
println("try bottom...")
} catch (e: Exception){
println("catch...${e.toString()}")
} finally {
println("finally")
}
}
// try top...
// catch...java.lang.NumberFormatException: For input string: "Son"
// finally
catch 문 여러 개
하나의 try 영역에 다양한 예외 처리를 위해 catch 문을 여러 개 작성할 수 있지만, 이때 하위 타입의 예외를 먼저 catch 문으로 선언하고 상위 타입의 예외는 그 다음에 선언해주어야 여러 예외 처리를 수행할 수 있다.
fun some(args: Array<Any>){
try {
println("try top...")
val intData: Int = array[0] as Int
val data: String = array[2] as String
val data2: Int = data.toInt()
} catch (e: ClassCastException) {
println("catch...ClassCastException")
} catch (e: ArrayIndexOutOfBoundsException) {
println("catch...ArrayIndexOutOfBoundsException")
} catch (e: Exception){
println("catch...${e.toString()}")
} finally {
println("finally")
}
}
fun main(args: Array<String>) {
val array = arrayOf("0", 1, "2")
some(array)
val array2 = arrayOf(10, "5")
some(array2)
val array3 = arrayOf(10, 0, "world")
some(array3)
}
// try top...
// catch...ClassCastException
// try top...
// catch...ArrayIndexOutOfBoundsException
// try top...
// catch...java.lang.NumberFormatException: For input string: "world"
표현식으로 try-catch 이용
try-catch를 표현식으로 사용하면 각 영역의 마지막 줄이 반환값이다. 이때 finally 문을 함께 사용하면 finally 문은 표현식으로 사용되지 않는다.
fun some(arg: String): Int {
val parseData: Int = try {
arg.toInt()
} catch (e: Exeption) {
0
} finally {
100 // 사용 안됨
}
return parseData
}
fun main(args: Array<String>) {
println("${some("10")}")
println("${some("a")}")
}
// 10
// 0
예외 발생시키기 throw
예외 발생은 throw 키워드를 이용하며 throw 뒤에 Exception 클래스 객체를 명시하면 해당 예외가 발생한다.
fun some(arg: String): Int {
if(arg < 1)
throw Exception("parameter must be greater than zero")
else {
var sum = 0
for(i in 1..arg){
sum += i
}
return sum
}
}
fun main(args: Array<String>) {
try {
println("${some(5)}")
println("${some(-1)}")
} catch (e: Exception) {
println("catch...${e.toString()}")
}
}
// 15
// catch...java.lang.Exception: parameter must be greater than zero
Exception 클래스를 정의할 수 있다.
class MyException(msg: String): Exception(msg){
val errorData: String = "some error data"
fun errorFun() {
println("errorFun call...")
}
}
fun some(){
throw MyException("My Error...")
}
fun main(args: Array<String>){
try{
some()
} catch(e: MyException){
println("${e.toString()}")
println("${e.errorData}")
e.errorFun()
}
}
// MyException: My Error...
// some error data
// errorFun call...
코틀린에서 throw는 일종의 표현식이다. throw 구문을 프로퍼티에 대입할 수 있으며 throw만을 반환하는 함수라면 반환 타입을 Nothing으로 지정할 수 있다.
fun some1(arg: String): Int {
val name: String? = null
val s: String = name ?: throw IllegalArgumentException("Name required")
println("some1 bottom")
}
fun some2(arg: Int): Nothing {
if(arg > 0)
throw Exception("some2 exception.. arg > 0 true")
else
throw Exception("some2 exception.. arg > 0 false")
}
fun main(args: Array<String>) {
try {
some1()
} catch (e: Exception) {
println("catch...${e.toString()}")
}
try {
some2(10)
} catch (e: Exception) {
println("catch...${e.toString()}")
}
}
// catch...java.lang.IllegalArgumentException: Name required
// catch...java.lang.Exception: arg > 0 true
코틀린에는 자바의 throws가 없다. 없앤 이유는 프로그램에서 throws가 꼭 필요하지도 않고 프로그램의 생산성과 품질 향상에 별 도움이 안된다고 판단한 것이다.