Archives
Recent Posts
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Today
Total
관리 메뉴

안드로이드 개발자의 창고

[18일차 Kotlin] 리플렉션(Reflection) 본문

Computer/Kotlin

[18일차 Kotlin] 리플렉션(Reflection)

Wise-99 2023. 5. 23. 22:19

 

 

출처 : 안드로이드 앱스쿨 2기 윤재성 강사님 수업 PPT

 

 

 

📖 리플렉션

  • 프로그램 실행 중에 프로그램의 구조(객체, 함수, 프로퍼티)를 분석하는 기법
  • 객체의 클래스 타입, 클래스 정보, 생성자 정보, 프로퍼티 정보 등을 실행 중에 파악할 수 있다.

 

 

 

📖 예제 코드

객체를 생성할 TestClass

class TestClass(var number1:Int, var number2:Int, var number3:Int){

    var number4:Int = 0
    var number5:Int = 0

    constructor(a1:Int) : this(100, 200, 300)

    constructor(a1:Int, a2:Int) : this(100, 200, 300)

    fun testMethod1(){

    }

    fun testMethod2(a1:Int, a2:Int){

    }
}

 

클래스 정보 확인

import kotlin.reflect.KClass

fun main() {
    // 클래스 타입
    val a1: KClass<String> = String::class
    println("String의 코틀린에서의 타입 : $a1")

    val a2:Class<String> = String::class.java
    println("String의 자바에서의 타입 : $a2")

    val str1 = "안녕하세요"
    val a3:KClass<out String> = str1::class
    println("str1을 통해 접근할 수 있는 객체의 클래스 타입(코틀린) : $a3")

    val a4:Class<out String> = str1::class.java
    println("str1을 통해 접근할 수 있는 객체의 클래스 타입(자바) : $a4 ")

    val test1 = TestClass(100, 200, 300)

    val a7 = test1::class
    val a8 = test1::class.java
    println("test1의 클래스 타입(코틀린) : $a7")
    println("test1의 클래스 타입(자바) : $a8")

    println("추상 클래스 인가 : ${test1::class.isAbstract}")        // false
    println("Companion 클래스 인가 : ${test1::class.isCompanion}") // false
    println("Data 클래스 인가 : ${test1::class.isData}")           // false
    println("final 클래스 인가 : ${test1::class.isFinal}")         // true
    println("open 클래스 인가 : ${test1::class.isOpen}")           // false
    println("중첩 클래스 인가 : ${test1::class.isInner}")           // false
    println("Sealed 클래스 인가 : ${test1::class.isSealed}")       // false
}

코드 해석

  • val a1: KClass<String> = String::class
    • KClass<클래스타입> : 지정된 클래스의 타입을 파악한다(코틀린 클래스)
  • val a2:Class<String> = String::class.java
    • Class<클래스타입> : 지정된 클래스의 타입을 파악한다(자바 클래스)
  • val a3:KClass<out String> = str1::class 와 val a4:Class<out String> = str1::class.java 
    • 변수를 통해 접근할 수 있는 객체의 클래스 타입을 파악한다.
  • println("추상 클래스 인가 : ${test1::class.isAbstract}") ...
    • 클래스의 정보를 분석한다.
    • kotlin은 open 키워드를 붙이지 않으면 Java 코드로 변환될 때 final 키워드가 자동으로 붙게 된다.
    • 따라서 TestClass는 final 클래스이므로 true가 출력된다.

생성자 정보 확인

fun main(){
    val test1 = TestClass(100, 200, 300)
    
     val constructors = test1::class.constructors

    for(con in constructors){
        println("constructor : $con")

        for(param in con.parameters){
            println("parameter 순서 : ${param.index}")
            println("parameter 타입 : ${param.type}")
            println("parameter 이름 : ${param.name}")
        }
    }

    val primaryCon = test1::class.primaryConstructor
    if(primaryCon != null){
        println(primaryCon)

        for(param in primaryCon.parameters){
            println("parameter index : ${param.index}")
            println("parameter type : ${param.type}")
            println("parameter name : ${param.name}")
        }
    }
}

코드 해석

  • val constructors = test1::class.constructors
    • 생성자 정보를 가져온다.
  • for(param in con.parameters){ ... }
    • 생성자의 멤버 변수를 가져온다.
      • param.index : 멤버 변수의 순서
      • param.type : 멤버 변수의 타입
      •  param.name : 멤버 변수의 이름
  • val primaryCon = test1::class.primaryConstructor
    • 주생성자의 정보를 가져온다.

프로퍼티 정보 확인

fun main(){
    val test1 = TestClass(100, 200, 300)
    
    val properties = test1::class.declaredMemberProperties
    for (prop in properties){
        println(prop.name)
    }
}

메서드 정보 확인

fun main(){
    val test1 = TestClass(100, 200, 300)
    
    val methods = test1::class.declaredMemberFunctions
    for (met in methods){
        println(met.name)
    }
}