来自java的kotlin函数默认参数

给予以下Kotlin类:

class Foo { public fun bar(i: Int = 0): Int = 2 * i } 

我应该如何调用没有任何参数从一个Java / Groovy代码的“酒吧”功能?

 def f = new Foo() f.bar() //throws: java.lang.IllegalArgumentException: Parameter specified as non-null contains null 

你现在可以在Kotlin做到这一点。 对于你的类方法,使用@JvmOverloads注解 。

 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")); 

输出以下内容:

你好,世界!

你好弗兰克!

我很快就会发布真正的答案,但如果有人想要从反思中做到这一点,这里是代码的外观。 更复杂的是,如何使用Kotlin反射KCallable

这是要调用的类:

  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)); 

输出继电器:

你好弗兰克!

大卫你好!

你好,世界!