본문 바로가기

kotlin

by Delegates.observable 동작 방식

class ObservableClass {
    var stringProperty: String by Delegates.observable("INITIAL_VALUE") { prob, oldValue, newValue ->
        println("기존값: $oldValue, 새로운 값: $newValue")
    }
}
val observableClass = ObservableClass()
observableClass.stringProperty = "first change"
observableClass.stringProperty = "second change"

 

위 코드를 java 코드로 디컴파일을 해보면 아래와 같이 동작한다

 

/*
*   1. ReadWriteProperty를 상속받은 ObservableProperty를 상속받은 observable 클래스가 생성된다.
*      사용자가 정의한 람다식인 afterChange 함수는 ObservableProperty 클래스의 setValue 함수 내부에서 실행된다.
* */
public final class ObservableClass$$special$$inlined$observable$1 extends ObservableProperty {
    final Object $initialValue;

    public ObservableClass $$special$$inlined$observable$1(Object $captured_local_variable$1, Object $super_call_param$2) {
        super($super_call_param$2);
        this.$initialValue = $captured_local_variable$1;
    }
    //개발자가 정의한 람다식이 afterChange 함수로 변환되어 생성된다.
    protected void afterChange(@NotNull KProperty property, Object oldValue, Object newValue) {
        Intrinsics.checkParameterIsNotNull(property, "property");
        String newValue =(String) newValue;
        String oldValue =(String) oldValue;
        int var7 = false;
        String var8 = "기존값: "+oldValue+", 새로운 값: "+newValue;
        boolean var9 = false;
        System.out.println(var8);
    }
}

/*
*   2. 사용자가 정의한 ObservableClass 의 생성자에서 1번에서 생성된 클래스인 observable 의 객체를 생성한다
*      프로퍼티의 세터가 동작하면 observable 객체의 setValue 함수가 호출되고 최종적으로 setValue 함수 내에서 afterChange 함수가 실행되어 사용자가 전달한 람다식이 실행된다.
* */
public final class ObservableClass {
    static final KProperty[] $$delegatedProperties = new KProperty[]
    {
        (KProperty) Reflection . mutableProperty1 (new MutablePropertyReference1Impl (Reflection.getOrCreateKotlinClass(
            ObservableClass.class),
            "name",
            "getName()Ljava/lang/String;"
        ))
    };
    @NotNull
    private final ReadWriteProperty name$delegate;

    @NotNull
    public final String getName()
    {
        return (String)this.name$delegate.getValue(this, $$delegatedProperties[0]);
    }
    
    public final void setName(@NotNull String var1)
    {
        Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
        this.name$delegate.setValue(this, $$delegatedProperties[0], var1);  
    }

    public ObservableClass()
    {
        Delegates var1 = Delegates . INSTANCE;
        Object initialValue $iv = "INITIAL_VALUE";
        int $i$f$observable = false;
        ReadWriteProperty var5 =(ReadWriteProperty)(new ObservableClass $$special$$inlined$observable$1(initialValue$iv, initialValue$iv)); // 1번에서 생성된 observable 클래스의 객체 생성
        this.name$delegate = var5;  //생성된 객체를 ObservableClass 의 프로퍼티에 저장
    }
}

'kotlin' 카테고리의 다른 글

코틀린 확장 함수  (0) 2022.10.26
lateinit 과 by lazy 분석  (0) 2022.10.22