给定以下Kotlin类:
class Foo {
public fun bar(i: Int = 0): Int = 2 * i
}
如果没有java/groovy代码中的任何参数,我应该如何调用'bar‘函数?
def f = new Foo()
f.bar() //throws: java.lang.IllegalArgumentException: Parameter specified as non-null contains null
发布于 2015-12-29 19:47:59
您现在可以在Kotlin中做到这一点。对于您的类方法,请使用@JvmOverloads
annotation。
class Foo {
@JvmOverloads public fun bar(name: String = "World"): String = "Hello $name!"
}
现在只需从Java调用它:
Foo foo = new Foo();
System.out.println(foo.bar());
System.out.println(foo.bar("Frank"));
输出以下内容:
问候世界!
你好,弗兰克!
发布于 2015-12-29 19:42:30
我将很快发布真正的答案,但如果有人想从反射中做到这一点,这里是代码的样子。关于如何在KCallable
中使用Kotlin反射要复杂得多,但却很有教育意义。
下面是要调用的类:
class Foo {
public fun bar(name: String = "World"): String = "Hello $name!"
}
然后,我们需要Kotin中的一个实用程序类,它可以接收类的实例、来自java反射的方法以及按名称命名的参数。这只适用于非基元类型:
class KReflectHelper {
companion object {
@Suppress("UNCHECKED_CAST")
@JvmStatic fun <T> callKotlinMethodWithNamedParms(instance: Any, method: Method, parmMap: Map<String, Any>): T {
val callable: KFunction<T> = method.kotlinFunction as? KFunction<T> ?: throw IllegalStateException("Method is not a Kotlin method")
val unusedParms = HashSet(parmMap.keys)
val callableParms = hashMapOf<KParameter, Any?>()
callable.parameters.map { parm ->
if (parm.kind == KParameter.Kind.INSTANCE) {
callableParms.put(parm, instance)
} else if (parm.kind == KParameter.Kind.VALUE && parmMap.contains(parm.name)) {
unusedParms.remove(parm.name)
callableParms.put(parm, parmMap.get(parm.name))
} else if (parm.kind == KParameter.Kind.VALUE) {
if (parm.isOptional) {
// default value will be used!
} else {
throw IllegalStateException("Missing required parameter ${parm.name}")
}
} else {
throw IllegalStateException("Cannot call methods that are not direct instance methods")
}
}
if (unusedParms.isNotEmpty()) {
throw IllegalStateException("Unrecognized parameters passed to function: $unusedParms")
}
return method.kotlinFunction?.callBy(callableParms) as T
}
}
}
现在,可以从Java调用该静态方法,但这并不是很有趣。代码生成器确实是必需的。从Kotlin调用它要容易得多,一些框架(如Klutter和Kovert)已经使用了一些类似的东西。
Foo foo = new Foo();
System.out.println(foo.bar("Frank"));
Method barMethod = Foo.class.getMethod("bar", String.class);
Map<String, Object> parms = new HashMap<String, Object>();
parms.put("name", "David");
System.out.println(KReflectHelper.callKotlinMethodWithNamedParms(foo, barMethod, parms));
// now call using the default
parms.clear();
System.out.println(KReflectHelper.callKotlinMethodWithNamedParms(foo, barMethod, parms));
输出:
你好,弗兰克!
你好,大卫!
你好,世界!
https://stackoverflow.com/questions/17348084
复制