코틀린 언어 정리 1-5

기본 - 접근 제한자, 예외처리

접근 제한자

적용 가능한 곳

최상위 레벨 또는 클래스 및 인터페이스의 멤버 함수, 프로퍼티, 프로퍼티의 getter/setter, 주생성자, 보조생성자 등에 각각 개별적으로 적용할 수 있습니다.

 

최상위 레벨( package )

public

모든 곳에서 접근 가능

 

private

같은 파일 내에서 접근 가능

 

internal

같은 모듈 내에서 접근 가능

 

protected

최상위 레벨에서 허용되지 않음( 이 키워드는 사용 불가 )

 

class, interface

private

선언한 클래스 내부에서 접근 가능

 

protected

선언한 클래스 + 상속 받은 클래스 내에서 접근 가능

 

internal

같은 모듈, 클래스 선언을 볼 수 있는 모든 곳에서 접근 가능

 

public

클래스 선언을 볼 수 있는 모든 곳

 

제약

  • 하위 클래스에서 상위 클래스 멤버의 접근 권한을 줄여서 override 할 수 없습니다.
  • getter/setter관련
    • 프로퍼티의 접근 제한은 항상 get의 접근 제한과 같습니다.
    • set의 접근 권한은 프로퍼티의 접근 권한보다 확장할 수 없습니다.

 

예외처리

try/catch/finally/throw

 

예제

fun main(args: Array<String>) {
   try {
       val num = 0
       //val num1 = 10 / num // divide by zero
       throw (Exception("division by zero simulation"))
   } catch (e: Exception) {
       println(e)
       println("catch processed")
   } finally {
       println("finally processed")
   }
}

try 블록 내부의 코드 실행 중 예외가 발생하면 catch 구문 실행 후 finally구문을 실행합니다. 기본적인 구문이나 사용방법은 C++/Java와 동일합니다.

 

구조

try { 주 처리 코드 } catch ( e: Exception ) { 예외 발생 시 처리 코드 } finally { 항상 실행되는 코드 }

 

특징

try/catch/finally는 표현식으로 사용될 수 있습니다. 여기서 주의해야 할 부분이 있습니다. throw와 finally입니다. 각각에 대해 확인해 보겠습니다.

우선, throw 구문도 표현식으로 사용될 수 있습니다. 그런데 throw 구문은 실행 후 리턴을 하는 것이 아니라 제어가 전혀 다른 곳으로 jump되므로 throw구문의 리턴 값/타입은 의미가 없습니다.

하지만 throw가 if/when등에서 조건에 따라 각각 여러개의 동일한 타입의 다른 값이 리턴되는 곳에 포함되어 있다면 문법적으로 리턴 값이나 타입이 의미가 있습니다. 이 때에는 if/when등의 마지막 표현식으로 나열되어 있는 각 경우의 값의 타입과 throw에서 리턴하는 값의 타입이 동일한 타입처럼 취급되어야 if/when 구문의 리턴 값을 전달 받는 변수에 대해 문법적으로 문제없는 것으로 보이기 때문입니다. 이런 경우 throw에서는 의미적으로나 문법적으로 문제가 없는 Nothing타입을 리턴하는 것으로 처리가 됩니다. 다음에 나오는 예제에서 result_additional_add 변수를 선언하여 초기화 하는 곳을 참고하면 이해가 쉬울 것입니다.

 

finally를 사용하는 경우도 주의해야 합니다. finally는 항상 실행이 됩니다. 즉 try/catch/finally를 모두 사용한 표현식에서 각각의 구문 내에서 값을 리턴하도록 구현한 경우, 항상 finally의 반환값만 사용 됩니다. 따라서 어떠한 경우에도 try/catch에 명시된 반환은 의미가 없게 됩니다. 이런 동작을 하게 되면 try/catch/finally를 표현식으로 사용하게 되는 의미가 없게 됩니다. 이런 이유로 try/catch/finally로 구성된 구문이 표현식으로 사용되는 경우 finally의 반환값은 무시하도록 처리되어 있습니다.

 

예제

fun main1(args: Array<String>) {
   var list = mutableListOf("개", "고양이", "돼지", "소", "호랑이", "개", "고양이", "곰", "개", "곰")

   var result =
       try {
           var result_addAll = list.addAll(0, listOf("쥐", "치타", "타조"))

           var result_additional_add =
               if (result_addAll) {
                   list.add("물개")
               } else {
                   throw Exception()
               }
           println(result_additional_add)
           //throw Exception()
           0 // 예외가 발생하지 않으면 result = 0
       } catch (e: Exception) {
           println("Exception!!!")
           1 // 예외 발생 시 result = 1
       } finally {
           println("addAll operation executed successfully!")
           2 // try/catch/finally 구문에서 finally는 표현식 처리가 제외되는 부분이다.
       }
   println(result)
}

 

+ Recent posts