是否可以创建扩展功能并将其称为,就好像它是静态的?
fun System.sayByeAndExit() {
println("Goodbye!")
System.exit()
}
fun main(args: Array<String>) {
System.sayByeAndExit() // I'd like to be able to call this
}
我了解kotlin的扩展功能静态解析,如Kotlin Reference (Extension Functions) 中所述,但这并不意味着他们可以被称为它们是类中的静态函数(在Java意义上)。
我也明白这段代码不起作用,因为系统的没有实例传递给编译器将生成的方法;因此它不会编译。
有些人可能想知道为什么这种行为是可取的。我可以理解为什么你会认为这不是,所以这里有一些原因:
Kotlin是否有办法实现&#34; hook&#34;一个类的静态函数?我很想知道。
答案 0 :(得分:9)
你真的要求&#34;扩展函数用于类引用&#34;或者&#34;向现有类添加静态方法&#34;这里有另一个问题:How can one add static methods to Java classes in Kotlin,其中包含功能请求KT-11968
扩展功能无法添加到没有实例的任何内容中。对类的引用不是实例,因此您无法扩展java.lang.System
之类的内容。但是,你可以extend a companion object现有的课程。例如:
class LibraryThing {
companion object { /* ... */ }
}
允许您扩展LibraryThing.Companion
,因此当您正在扩展伴随对象的单例实例时,调用一些新的myExtension()
方法看起来就像是在扩展Class引用本身:
fun LibraryThing.Companion.myExtension() = "foo"
LibraryThing.Companion.myExtension() // results in "foo"
LibraryThing.myExtension() // results in "foo"
因此,您可能会发现一些Kotlin库仅为此案例添加了空伴随对象。其他人则没有,对于那些你运气不好的人。&#34;由于Java没有伴随对象,因此您也无法对Java执行相同的操作。
另一个常见的功能是采用现有的Java静态方法,该方法接受类的实例作为第一个参数,并使其表现为扩展函数。这可以通过问题KT-5261,KT-2844,KT-732,KT-3487以及可能的其他功能请求进行跟踪。
答案 1 :(得分:1)
您可以为object
定义扩展功能,并在系统范围的上下文中使用它。一个对象只会创建一次。
object MyClz
fun MyClz.exit() = System.exit(0)
fun main(args: Array<String>) {
MyClz.exit()
}
或
class MyClz {
companion object
}
fun MyClz.Companion.exit() = System.exit(0)
fun main(args: Array<String>) {
MyClz.exit()
}