问题
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