Kotlin

[Kotlin] 리플렉션(Reflection) 으로 제네릭(Generic) 객체 생성하기

nineDeveloper 2021. 8. 2. 18:33
728x90

Excel 다운로드 기능을 개발했는데 아래와 같이 객체 내부에 companion object 형태로 단지 객채만 다른 from 메서드를 일일히 생성해주어야 되서
이부분의 중복을 제거하기 위해 Reflection 공통 유틸을 만들기로 했다

@Schema(title = "Sample 엑셀 다운로드 객체", hidden = true)
class SampleExcelReader(
    @field:Schema(title = "이름")
    var name: String? = null,
    @field:Schema(title = "이메일")
    var email: String? = null,
    @field:Schema(title = "전화번호")
    var phone: String? = null,
    @field:Schema(title = "소속부서")
    var dept: String? = null,
    @field:Schema(title = "업무코드")
    var workCode: Int? = null,
    @field:Schema(title = "부서코드")
    var deptCode: Int? = null,
    @field:Schema(title = "내용")
    var content: String? = null,
    @field:Schema(title = "IP")
    var ip: String? = null,
    @field:Schema(title = "소수")
    var percent: BigDecimal? = null,
    @field:Schema(title = "날짜")
    var createDate: String? = null,
    @field:Schema(title = "일시")
    var updateDatetime: String? = null,
    @field:Schema(title = "빈데이터")
    var empty: String? = null,
) {

    override fun toString(): String {
        return "SampleExcelReader(name=$name, email=$email, phone=$phone, dept=$dept, workCode=$workCode, deptCode=$deptCode, content=$content, ip=$ip, percent=$percent, createDate=$createDate, updateDatetime=$updateDatetime, empty=$empty)"
    }

    companion object {
        /**
         * 엑셀 업로드 처리를 위한 객체
         * @param row Row
         * @return SampleExcel?
         */
        fun from(row: Row): SampleExcelReader = ExcelUtils.setObjectMapping(SampleExcelReader(), row)
    }

}

 

⬇︎⬇︎⬇︎⬇︎

 

이렇게 아래와 같이 Generic 타입을 <reified T: Any> 으로 선언하고 inline 메서드를 생성한다음
객체를 생성해서 넘기는 부분에 T::class.createInstance() 이렇게 Generic ClasscreateInstance()으로 객체를 생성하면
기존의 객체를 생성해서 인자값으로 넘기는 것과 동일하게 동작한다

 

class ExcelUtils {
    companion object {
        inline fun <reified T: Any> from(row: Row): T = setObjectMapping(T::class.createInstance(), row)
    }
}

 

T::class.createInstance() 이 코드를 T::class.java.getDeclaredConstructor().newInstance() 이렇게 변경해도 잘 동작한다

 

class ExcelUtils {
    companion object {
        inline fun <reified T: Any> from(row: Row): T = setObjectMapping(T::class.java.getDeclaredConstructor().newInstance(), row)
    }
}
728x90