温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

kotlin中扩展方法有哪些

发布时间:2021-08-12 12:52:29 来源:亿速云 阅读:296 作者:小新 栏目:移动开发

这篇文章给大家分享的是有关kotlin中扩展方法有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

Usage

扩展函数是 kotlin 的又一杀手锏功能,能够在不修改源码的基础上,扩展某些类的能力,方便开发。

例如这里演示了给 String 添加一个获取第一个元素的方法。

fun String.first(): Char {   if (isEmpty()) {     throw NoSuchElementException("String is empty")   }   return this[0] } fun main(args: Array<String>) {   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<String>) {   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中扩展方法有哪些”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI