Kotlin扩展方法

前言

带你深入理解Kotlin扩展函数和java的关系

3376017-0fd88f7928b9c1ac.png

环境以及工具

Android Studio 3.3

扩展函数(本kt文件中扩展方法)

//-----------------------扩展函数(本类中扩展方法)-------------------------------------
class Test1 {
    var name: String = "boyi.chen"
}
//Test1:接收器类型(receiver type)
//this:  接收器对象(receiver object)
fun Test1.temp() {
    println("增加扩展函数,打印扩展类的属性name=${this.name}")
}

fun main(args: Array<String>) {
  //-----------------------扩展函数(本kt文件)-------------------------------------
    Test1().temp()//输出结果-------------------------增加扩展函数-------------------------
}

在这个例子中,Test1是接收器类型,Test1()和this是接收器对象,在这个扩展函数中,你可以使用this直接访问你扩展的类型的函数和属性,就像定义在这个类中的方法一样调用。

这个例子如果看不懂,没关系,文末已经给出答案。

扩展函数(其他包下的kt文件)

package com.boy.learning.kotlinlearningtravel.extensions.utils

class StringUtils {
    var name: String = "StringUtils"
}

fun StringUtils.CustomGetLenth(): Int {
    return this.name.length
}
package com.boy.learning.kotlinlearningtravel.extensions
fun main(args: Array<String>) {
     //-----------------------扩展函数(其他包下的kt文件)-------------------------------------
    val lenth = StringUtils().CustomGetLenth()
    println(lenth)//输出结果-------------------------11-------------------------
}

范型化的扩展函数

class Test2 {}
//-----------------------范型化的扩展函数-------------------------------------
fun <T> Test2.temp(t: T) {
    when (t) {
        is String -> println("t is String:$t")
        is Int -> println("t is Int:$t")
        else -> println("既不是String也不是Int")

    }
}

fun main(args: Array<String>) {
    Test2().temp(1)//输出结果-------------------------t is Int:1-------------------------
    Test2().temp("Boyi-Chen")//输出结果-------------------------t is String:Boyi-Chen-------------------------
}

扩展函数不可覆盖(overriding)

//-----------------------扩展函数不可覆盖(overriding)-------------------------------------
open class View {}

class Button : View() {}

fun View.longClick() = println("base view longClicked")
fun Button.longClick() = println("button longClicked")

fun main(args: Array<String>) {
    //-----------------------扩展函数不可覆盖(overriding)-------------------------------------
    val button: View = Button()
    button.longClick()//输出结果-------------------------base view longClicked-------------------------

    val button2: Button = Button()
    button2.longClick()//输出结果-------------------------button longClicked-------------------------
}

问题

1. 看到这里是不是觉得有点奇怪,扩展函数有什么用?java中有类似的么?
我也是带着这个疑问才去找答案的。
3376017-3bb89a02575ff821.png

由于Kotlin文件在经过Kotlin编译器编译后会生成Java字节码,所以我只要找到对应的字节码文件就可以找到答案了。
我在字节码文件中找到了答案
StringUtils.kt
源代码

package com.boy.learning.kotlinlearningtravel.extensions.utils

class StringUtils {
    var name: String = "StringUtils"
}

fun StringUtils.CustomGetLenth(): Int {
    return this.name.length
}

StringUtilskt.class 字节码文件

package com.boy.learning.kotlinlearningtravel.extensions.utils;

import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

@Metadata(mv={1, 1, 13}, bv={1, 0, 3}, k=2, d1={"\000\f\n\000\n\002\020\b\n\002\030\002\n\000\032\n\020\000\032\0020\001*\0020\002��\006\003"}, d2={"CustomGetLenth", "", "Lcom/boy/learning/kotlinlearningtravel/extensions/utils/StringUtils;", "appKt_debug"})
public final class StringUtilsKt
{
  public static final int CustomGetLenth(@NotNull StringUtils $receiver)
  {
    Intrinsics.checkParameterIsNotNull($receiver, "receiver$0");return $receiver.getName().length();
  }
}

其实现在可以看出来了,扩展函数经过kt编译器编译后,生成 public static final 的静态方法,就是java中的xxxUtils工具类。这样使得Kotlin比java更方便使用,效率更高。

2. kotlin扩展函数,java可以调用么?

java中使用kt定义的扩展函数(不要问我为什么,反正字节码中声明的静态函数就是这样的,拿起键盘就是干)

public class MainTest {
    public static void main(String[] args) {
        int lenth = StringUtilsKt.CustomGetLenth(new StringUtils());
        System.out.println(lenth);//11
    }
}

认真看的同学可能会看到静态函数需要传(@NotNull StringUtils $receiver),这里的receiver是接收者实例化对象,文章开头扩展函数就给大家解释了,还是截个图,大家看着方便点。

3376017-665a782991fa4f4a.png

源码

请关注公众号并在后台回复:kotlin

Kotlin重构系列分享教程

Kotlin环境搭建
Kotlin重构初体验之告别FindViewById
Kotlin基本类型
Kotlin 控制语句 if when for while
Kotlin返回与跳转
Kotlin 类和对象
Kotlin继承
Kotlin接口

Kotlin重构如何兼容原先的ButterKnife、EventBus3.1
当ButterKnife8.8.1碰到AndroidX怎么办
Githup教程开源项目

Python爬虫系列分享教程

Python爬虫之旅之Selenium库的使用
Python爬虫之旅之豆瓣音乐

请关注我(分享日常开发)

3376017-83908272f82196f8.jpg

参考文章
http://gad.qq.com/article/detail/44044

猜你喜欢

转载自blog.csdn.net/weixin_34129696/article/details/87399189