Kotlin扩展方法

前言

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

环境以及工具

Android Studio 3.3git

扩展函数(本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直接访问你扩展的类型的函数和属性,就像定义在这个类中的方法同样调用。github

这个例子若是看不懂,不要紧,文末已经给出答案。bash

扩展函数(其余包下的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中有相似的么?
我也是带着这个疑问才去找答案的。

因为Kotlin文件在通过Kotlin编译器编译后会生成Java字节码,因此我只要找到对应的字节码文件就能够找到答案了。 我在字节码文件中找到了答案 StringUtils.kt 源代码app

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

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

fun StringUtils.CustomGetLenth(): Int {
    return this.name.length
}
复制代码

StringUtilskt.class 字节码文件jvm

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是接收者实例化对象,文章开头扩展函数就给你们解释了,仍是截个图,你们看着方便点。ui

源码

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

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爬虫之旅之豆瓣音乐

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

参考文章 gad.qq.com/article/det…

相关文章
相关标签/搜索