How to obtain Properties or Function declared in kotlin extensions by java reflection

为君一笑 提交于 2021-01-27 07:02:13

问题


If I declare an extension function or some Extension Properties in Kotlin like this

var View.newPosition: Int
    get():Int {
        return newPosition
    }
    set(value) {
        this.newPosition=value
        Log.e("test","newPosition"+newPosition)
    }


fun View.setPosition(value:Int ){
    Log.e("test", "Position" + value)
}

Then I want to obtain them by Java reflection like this

    Class stuClass = null;
    try {
        stuClass = Class.forName("android.view.View");
    } catch (Exception e) {
        Log.e("test", e.toString());
    }
    Field f = null;
    try {
        f = stuClass.getField("newPosition");
    } catch (Exception e) {
        Log.e("test", e.toString());
    }
    Object obj = null;
    try {
        obj = stuClass.getConstructor().newInstance();
    } catch (Exception e) {
        Log.e("test", e.toString());
    }

    try {
        f.set(obj, 555);
    } catch (Exception e) {
        Log.e("test", e.toString());
    }

    try {
        Method setPosition = stuClass.getDeclaredMethod("setPosition", int.class);
        setPosition.setAccessible(true);
        try {
            setPosition.invoke(obj, 20);
        } catch (Exception e) {
            Log.e("test", e.toString());
        }

    } catch (Exception e) {
        Log.e("test", e.toString());
    }

But I just get some error says

NoSuchFieldException: newPosition
NoSuchMethodException: <init> []
NoSuchMethodException: setPosition [int]

So I'm wondering whether my code written in a wrong way or we can't get kotlin extension Properties or Function by java reflection like common java method or field?


回答1:


Extension functions and properties are not added to existing class for real. Kotlin compiler allows you to reference them AS IF they were a part of the class.

If you write in Kotlin a function 'setPosition' in a Kotlin file named 'Funs.kt':

//in file Funs.kt
fun View.setPosition(value: Int) {
    //smth
}

The compiler will make it a FunsKt.class with a static method 'setPosition' inside.

public final class FunsKt {

    public static void setPosition(View $receiver, int value) {
        //smth
    }

}

It is just Kotlin compiler magic that it allows you to use it as if it was a part of the View class (notice that because of that you cannot access private/protected values from extension funtions). From java you must use it as it is.

To obtain Method setPosition do that:

Class c = Class.forName("[your package].[kotlin file name + "Kt"]");
Method m = c.getMethod("setPosition", View.class, int.class);

Extension properties work in a simmilar way. No real variable is created - only two static methods (getter and setter). These method don't have a real variable in which they store value, but they calculate this value on the go. You cannot obtain them as a Field object but you can get them as methods in the very same way as setPosition.



来源:https://stackoverflow.com/questions/48635210/how-to-obtain-properties-or-function-declared-in-kotlin-extensions-by-java-refle

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!