我的类型为A
,类型为contructor,需要参数x
并且有一些可选参数:
class A(x: String, y: String = "default_y")
现在我想引用带有所需参数的构造函数:
var function: (String) -> A = ::A
现在我遇到了不兼容类型的问题,因为该构造函数的签名是2个字符串,而不仅仅是一个。
当我添加这个构造函数重载时,编译器停止抱怨:
class A(x: String, y: String = "default_y") {
constructor(x: String): this(x, "default_y")
}
//added just so you can see full code
var function: (String) -> A = ::A
我现在正在获得这种冗余。我当然可以做一些事情(将"default_y"
提取为常量或从主构造函数中删除默认参数)以删除冗余,但这些只是糖代码并没有真正做任何事情。只是允许我引用它而不抱怨。
有没有办法引用构造函数(也可能是函数)作为只有必需参数的函数?
答案 0 :(得分:1)
方法参数的默认值是一个任意表达式,只能表示为一个字节码块;没有其他可以用于反思的表示。参数信息通过解析源代码来检索默认参数值。
作为一种解决方法,您可以让编译器为您的构造函数生成JVM重载,然后使用Java反射来调用带有单个String
参数的构造函数:
class A @JvmOverloads constructor(x: String, val y: String = "default_y")
val con: Constructor<A> = A::class.java.constructors
.filterIsInstance<Constructor<A>>()
.find { it.parameterCount == 1 } ?: throw IllegalStateException("Not found!")
val newInstance: A = con.newInstance("myArg")
println(newInstance.y) // Prints 'default_y'
编辑:
使用callBy
,您还可以使用Kotlin反射调用构造函数:
val con = MyClass::class.constructors.first()
val newInst =
con.callBy(mapOf(con.parameters.first() to "myArg"))
答案 1 :(得分:1)
虽然无法从签名中删除默认参数来获取函数引用,但您可以使用lambda而不是函数引用并调用仅提供所需参数的构造函数:
<section>