java - 如何通过java反射获取kotlin extensions中声明的Properties或Function

标签 java kotlin

如果我像这样在 Kotlin 中声明一个扩展函数或一些扩展属性

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反射获取它们

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

但我只是得到一些错误提示

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

所以我想知道是我的代码写错了还是我们不能像普通的java方法或字段那样通过java反射获取kotlin扩展属性或函数?

最佳答案

扩展函数和属性不会真正添加到现有类中。 Kotlin 编译器允许您引用它们,就好像它们是类的一部分一样。

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

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

编译器会将它变成一个 FunsKt.class,里面有一个静态方法 'setPosition'。

public final class FunsKt {

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

}

这只是 Kotlin 编译器的魔力,它允许您像使用 View 类一样使用它(请注意,因此您无法从扩展函数访问私有(private)/ protected 值)。在 Java 中,您必须按原样使用它。

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

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

扩展属性以类似的方式工作。没有创建真正的变量——只有两个静态方法(getter 和 setter)。这些方法没有真正的变量来存储值,但它们会在运行中计算这个值。您不能将它们作为 Field 对象获取,但可以通过与 setPosition 完全相同的方式将它们作为方法获取。

关于java - 如何通过java反射获取kotlin extensions中声明的Properties或Function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48635210/

相关文章:

android - Handler().postDelayed 现在已弃用。要调用什么函数?

java - 发现 Java 9 中已关闭的错误/增强功能?

android - 如何在 Kotlin 中将数组转换为集合(HashSet)?

java - 如何在 InputStream 中接收多个文件并进行相应处理?

java - 如何调用在受 SSL 保护的服务器上运行的 API

android - Kotlin 对 @ColorInt Java 注释的支持

android - 华为、荣耀手机电池优化、前台服务

spring-boot - 无法使用 spring boot gradle 插件执行依赖管理的 junit5 测试

java - 在 JFrame MessageBox 中给出计算结果

java - 如何解决 Java 和 Spring Boot 中的 slf4j logback 类路径错误?