Java 如何使用 Kotlin 反射
How to use Kotlin reflection from Java
是否可以使用来自 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
值调用是不明确的。
如果声明test
函数的文件是Utils.kt
,那么它将被编译成UtilsKt
class.
作为文档 states:
Normally, if you write a Kotlin function with default parameter values, it will be visible in Java only as a full signature, with all parameters present. If you wish to expose multiple overloads to Java callers, you can use the @JvmOverloads annotation.
因此,添加此注释后:
@JvmOverloads
fun test(a: String = "default", b: String): String {
return "A: $a - B: $b";
}
test
方法可以从 java 使用单个参数调用:
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"
}
}
是否可以使用来自 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
值调用是不明确的。
如果声明test
函数的文件是Utils.kt
,那么它将被编译成UtilsKt
class.
作为文档 states:
Normally, if you write a Kotlin function with default parameter values, it will be visible in Java only as a full signature, with all parameters present. If you wish to expose multiple overloads to Java callers, you can use the @JvmOverloads annotation.
因此,添加此注释后:
@JvmOverloads
fun test(a: String = "default", b: String): String {
return "A: $a - B: $b";
}
test
方法可以从 java 使用单个参数调用:
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"
}
}