如果我像这样在 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/