[kotlin] 은행코드 enum으로 관리하기

개발을 하다보면 코드표를 사용하여 값을 처리해야하는 경우가 있다. 이 경우 enum 클래스를 사용하곤 한다. Spring boot - kotlin에서 이를 구현하자.

1. enum class 만들기 (feat. complie constant, 컴파일 상수)

포트원의 은행 코드표를 예시로 사용한다.

https://faq.portone.io/1dae5145-1feb-4ef2-87ef-4b0e8a984945

 

가상계좌 은행코드표

포트원을 통해 확인가능한 은행명 & 코드

faq.portone.io

 

enum class BankCode( val bankCode: String, ) {
	BANKCODE("020") // 우리은행
  }

그 뒤 @Service에 enum을 사용하여 이름을 부여하고자한다.

@Service(BankCode.BANKCODE)
...

이 경우 @Service에서 컴파일 에러가 발생한다. String형이 필요한데 BankCode 형태가 전달됐다는 이유다.

BankCode.BANKCODE.bankcode를 하면 해결될 줄 알았는데 이번엔 다른 컴파일 에러가 발생한다.

an annotation argument must be a compile-time constant

 

Kotlin에서는 애노테이션의 인자로 컴파일 타임 상수만 허용한다. 하지만 BankCode.JYNAME.code는 런타임에서 결정되는 값이므로 컴파일 타임 상수(constant expression) 가 아니어서 에러가 발생한다.

이를 해결하려면 다음과 같은 방법을 사용할 수 있다.

enum class BankCode(val bankcode: String) {
    BANKCODE("020");

    companion object {
        const val BANK_CODE = "020"
    }
}

 

@Service(BANKCODE.BANK_CODE)
class MyService
...

왜 저런 코드가 나오는지에 대해서도 이해를 해보자

2. ENUM 이해해보기

주석을 달아보면 이렇다.

enum class BankCode(val bankcode: String) {
    BANKCODE("020"); // (1) Enum 생성자의 파라미터로 "020" 전달

    companion object {
        const val BANK_CODE = "020" // (2) const val을 사용함으로써, 컴파일 타입 상수로 "020" 선언
    }
}

2-1. 그러면 enum에 왜 생성자의 파라미터를 전달해야하는 것인가?

생성자가 없을 경우 enum 클래스는 아래 같은 모습이 된다.

enum class BankCode {
    WOORI,
    SHINHAN,
    HANA
}

위처럼 생성자 없이 선언하면 JYNAME, KIMCODE, PARKCODE 같은 이름만 가질 수 있다.
이렇게 하면 각 Enum 값에 추가 정보("020", "010" ...)를 넣을 방법이 없다.

2-2. companion object만 관리하면 안되나요

enum class BankCode(val bankcode: String) {
	companion object {
        const val BANK_CODE = "020"
    }
}

enum class 내부에는 최소 하나 이상의 Enum 값이 필요하다.
하지만 위 코드는 Enum 값이 하나도 없기 때문에 컴파일 에러가 발생한다.
companion object는 Enum 내부에서 정적(Constant) 데이터를 관리하는 용도로 사용될 수 있지만,
Enum 값 없이 단독으로 존재할 수는 없다.

3. enum을 안 쓰고 object를 사용하기

만약 Enum 값이 필요 없다면 Enum을 사용할 필요가 없다.
대신 object 또는 companion object를 활용하면 된다.

object BankCode {
    const val BANK_CODE = "020"
}

이제 Enum이 필요 없으므로, object를 사용해 정적인 데이터를 관리할 수 있다.
BankCode.BANK_CODE로 접근 가능하다.

 

4. 그럼 그냥 object쓰면 되는 거 아니야? object와 Enum은 무슨 차이가 있지?

포스팅하면서 많이 찾아봤는데 진짜 솔직히 모르겠다. enum은 when을 쓸 수 있다는 것 정도...

 

이런 object와 enum이 있다고 할 때 enum은 when을 사용할 수 있다.

이 부분에 대해서는 코틀린 공식문서를 좀 더 읽어봐야겠다.

 


https://tistory-pencilcase.tistory.com/358

enum클래스와 생성자 https://tistory-pencilcase.tistory.com/422