可以使用Java的Kotlin反射吗?
我希望从Java中的Kotlin函数中获取KCallable,并使用它的方法callBy调用带有默认参数的方法。
以Kotlin为例:
fun test(a: String = "default", b: String): String {
return "A: $a - B: $b";
}
fun main() {
val callable: KCallable<*> = ::test
val parameterB = callable.parameters[1]
val result = callable.callBy(mapOf(
parameterB to "test"
))
println(result)
}有可能吗?如果是这样的话,如何从Java代码中获取KCallable实例?
编辑:
我不能像建议的那样使用@JvmOverloads,因为参数的数量、默认参数及其位置可能是任意的。
呼叫的已知信息是:
编辑2:
此处不工作@JvmOverloads的示例:
fun test(a: String = "default", b: String = "default"): String {
return "A: $a - B: $b";
}在这里,使用一个String值进行调用是不明确的。
发布于 2020-10-26 18:41:39
如果声明test函数的文件是Utils.kt,那么它将被编译成UtilsKt类。
作为文档州
通常,如果您使用默认参数值编写Kotlin函数,则它在Java中仅以完整签名的形式出现,并包含所有参数。如果希望向Java调用方公开多个重载,可以使用@JvmOverload注释。
因此,在添加了这个注释之后:
@JvmOverloads
fun test(a: String = "default", b: String): String {
return "A: $a - B: $b";
}可以使用单个参数从java调用test方法:
public class ReflectionInterop {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Method test = UtilsKt.class.getDeclaredMethod("test", String.class);
String result = (String) test.invoke(null, "test"); //null used because method is compiled as static, so no instance needed to call it
System.out.println(result); //Will print "A: default - B: test"
}
}编辑
如果您正在寻找一种方法来克服方便的java互操作的局限性,那么您确实需要在您的Java代码中获得一个KCallable实例。
我认为没有辅助Kotlin函数是不可能的:
fun testReflection(): KCallable<*> = ::test它在Java中的使用非常简单:
public class ReflectionInterop {
public static void main(String[] args) {
KCallable<?> test = UtilsKt.testReflection(); //Assuming it is located in the same `Utils.kt` file
KParameter parameterB = test.getParameters().get(1);
String result = (String) test.callBy(new HashMap<>() {{
put(parameterB, "test");
}});
System.out.println(result); //Will print "A: default - B: test"
}
}https://stackoverflow.com/questions/64539969
复制相似问题