重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这篇文章给大家分享的是有关kotlin中扩展方法有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
成都创新互联专注于成都网站设计、网站制作、网页设计、网站制作、网站开发。公司秉持“客户至上,用心服务”的宗旨,从客户的利益和观点出发,让客户在网络营销中找到自己的驻足之地。尊重和关怀每一位客户,用严谨的态度对待客户,用专业的服务创造价值,成为客户值得信赖的朋友,为客户解除后顾之忧。
Usage
扩展函数是 kotlin 的又一杀手锏功能,能够在不修改源码的基础上,扩展某些类的能力,方便开发。
例如这里演示了给 String 添加一个获取第一个元素的方法。
fun String.first(): Char { if (isEmpty()) { throw NoSuchElementException("String is empty") } return this[0] } fun main(args: Array) { println("Hello,World".first()) }
这里需要额外注意的地方在于扩展函数的方法体中,是能够直接访问扩展对象 public 的变量的。例如上面的方法里面,我们也可以这么写:
fun String.first(): Char { if (length < 1) { throw NoSuchElementException("String is empty") } return this[0] }
通过 this 可以在方法内,访问扩展对象,这里就是通过 this[0] 拿到第一个字符的。
Under in hood
看上去很厉害哈,但他的原理却非常简单。我们要时刻记住,kotlin JVM 是基于 JVM 开发的,kotlin 源码最后会变成字节码而后被运行。当遇到语法上不太懂的地方,直接反编译字节码,或者 Decompile 成 Java 方法,就能洞察里面的玄机。
我们将上述代码,Decompile 成 Java 后,就能发现里面的秘密。
public static final char first(@NotNull String $this$first){ Intrinsics.checkParameterIsNotNull($this$first, "$this$first"); if ($this$first.length() < 1) { throw (Throwable)(new NoSuchElementException("String is empty")); } else { return $this$first.charAt(0); } }
原来是生成了一个 public static final 的方法呀,不过这个生成是 kotlin 提供的语法糖,帮我们完成的。看到这个代码,也解释了为什么在扩展对象方法内部,能够访问到扩展对象的 public 成员。
重载与多态
扩展方法能否被继承呢,或者重载呢?我们来看看例子
open class Animal class Dog : Animal() fun Animal.desc() = "Animal" fun Dog.desc() = "Dog" fun main(args: Array) { println(Dog().desc()) var animal: Animal = Dog() println(animal.desc()) } // output: // Dog // Animal
如果扩展方法能够被重载,那么两次都应该输出 Dog,我们还是和前面方法一样,来看看真相。
@NotNull public static final String desc(@NotNull Animal $this$desc) { Intrinsics.checkParameterIsNotNull($this$desc, "$this$desc"); return "Animal"; } @NotNull public static final String desc(@NotNull Dog $this$desc) { Intrinsics.checkParameterIsNotNull($this$desc, "$this$desc"); return "Dog"; }
可以看到实际生成了两个 desc 方法,里面的参数不动,所以这个方法的调用,只与扩展对象本身有关系,在编译时已经确定,不存在多态。
扩展属性
这是一个很神奇的设定,kotlin 并不能真的给扩展对象添加一个属性,而只是提供了一个语法糖,什么意思呢?我们具体看看下面这个例子。
var String.first: Char get() { if (isEmpty()) { throw NoSuchElementException(“String is empty”) } return this[0] } set(value) { println(“set value to $value”) } fun main() { “Hello, World”.first = ‘G' println(“Hello,World”.first) }
我们扩展了 kotlin 的属性,添加了一个 first。我们可以分别给这个所谓的 first 属性,注意是所谓的,添加 get 和 set 方法。然后我们可以通过 = 和 . 来调用 set 和 get 方法,就像 main 方法中那样。但实际上,最后并没有生成 first 属性,我们来看看反编译过后的代码。
public static final Char getFirst(@NotNull String $this$first) { Intrinsics.checkParameterIsNotNull($this$first, "$this$first"); CharSequence var1 = (CharSequence)$this$first; boolean var2 = false; if (var1.length() == 0) { throw (Throwable)(new NoSuchElementException("String is empty")); } else { return $this$first.charAt(0); } } public static final void setFirst(@NotNull String $this$first, char value) { Intrinsics.checkParameterIsNotNull($this$first, "$this$first"); String var2 = "set value to " + value; boolean var3 = false; System.out.println(var2); }
感谢各位的阅读!关于“kotlin中扩展方法有哪些”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!