本文介绍了如何通过Java反射获取在Kotlin扩展中声明的属性或函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我像这样在Kotlin中声明扩展功能或某些扩展属性

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)
}

然后我想通过Java反射来获取它们

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]

所以我想知道我的代码是用错误的方式编写的还是我们无法通过java反射(例如常见的java方法或字段)获得kotlin扩展的Properties或Function?

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?

推荐答案

扩展功能和属性并未真正添加到现有类中. Kotlin编译器允许您在类中引用它们的情况下引用它们.

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.

如果您使用Kotlin在名为"Funs.kt"的Kotlin文件中编写函数"setPosition":

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
}

编译器将使其内部具有静态方法"setPosition"成为FunsKt.class.

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
    }

}

这只是Kotlin编译器的魔力,它使您可以像使用View类一样使用它(请注意,因此您无法从扩展功能访问私有/受保护的值).从Java开始,您必须按原样使用它.

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.

要获取方法setPosition,请执行以下操作:

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);

扩展属性以相似的方式工作.没有创建任何实变量-只有两个静态方法(getter和setter).这些方法没有用于存储值的实数变量,但可以随时计算该值.您不能将它们作为Field对象获得,但可以通过与setPosition相同的方式将它们作为方法获得.

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.

这篇关于如何通过Java反射获取在Kotlin扩展中声明的属性或函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 19:49