一、前言:
Kotlin 能够扩展一个类的新功能而无需继承该类。 例如,你可以为一个你不 能修改的来自第三方库中的类编写一个新的函数。 这个新增的函数就像那个 原始类本来就有的函数一样,可以用普通的方法调用。 这种机制称为 扩展 函数 。此外,也有 扩展属性 , 允许你为一个已经存在的类添加新的属 性。想想是不是感觉很疯狂呢?那接下来就往我们开启这种疯狂吧。
二、扩展方法
Kotlin 的扩展函数可以让你作为一个类成员进行调用的函数,但是是定义在这 个类的外部。这样可以很方便的扩展一个已经存在的类,为它添加额外的方 法。在 Kotlin 源码中,有大量的扩展函数来扩展 Java,这样使得 Kotlin 比 Java 更方便使用,效率更高。
注意:Kotlin扩展方法可以和系统方法一致,优先调用自己的,自己定义的2个方法名不能一致,否则会报错!
1、扩展方法的定义语法如下:
fun [扩展类].(参数列表){
//方法执行体
}
示例:
//类名:AdjustUtils
object AdjustUtils {
}
/**
* String的扩展函数
*/
fun String.info(msg:String){
MyToash.Log("lyy","-----String的扩展函数-----:${msg}")
}
//Kotlin调用Kotlin扩展函数
"AAA".info("Kotlin调用Kotlin扩展函数")
注意:在 Java 中调用 Kotlin 扩展,需要通过扩展所在的文件名+Kt.的方式进行调用
//JAVA调用Kotlin扩展函数
AdjustUtilsKt.info("hahh","JAVA调用Kotlin扩展函数");
三、原理解析:Kotlin扩展方法怎么实现的
在体验到 Kotlin 扩展带个我们高效编程的同时,我们不禁要问自己几个问 题:
• Kotlin 的扩展是怎么实现的?
• Kotlin 的扩展会不是有性能问题?
接下来我们就从 Kotlin 反编译出 Java 代码上来一探究竟:
fun main() {
val test = mutableListOf(1, 2, 3)
test.swap(1, 2)
println(test)
}
fun MutableList<Int>.swap(index1: Int, index2: Int) {
val tmp = this[index1]
this[index1] = this[index2]
this[index2] = tmp
}
反编译出 Java 源码
public final class KotlinExtensionKt {
public static final void main() {
List test = CollectionsKt.mutableListOf(new Integer[]{1, 2, 3});
swap(test, 1, 2);
boolean var1 = false;
System.out.println(test);
}
// $FF: synthetic method
public static void main(String[] var0) {
main();
}
public static final void swap(@NotNull List $this$swap, int index1,
int index2) {
Intrinsics.checkParameterIsNotNull($this$swap, "$this$swap");
int tmp = ((Number)$this$swap.get(index1)).intValue();
$this$swap.set(index1, $this$swap.get(index2));
$this$swap.set(index2, tmp);
}
}
从反编译出的 Java 源码分析,扩展函数的实现非常简单,它没有修改接受者类型的成员, 仅仅 是通过静态方法来实现的
。所以我们不必担心扩展函数会带来额外的性能消耗。
四、扩展属性
扩展属性提供了一种方法能通过属性语法进行访问的 API 来扩展。尽管它们 被叫做属性,但是它们不能拥有任何状态,它不能添加额外的字段到现有的 Java 对象实例。
//为 String 添加一个 lastChar 属性,用于获取字符串的最后一个字符
val String.lastChar: Char get() = this.get(this.length - 1)
///为 List 添加一个 last 属性用于获取列表的最后一个元素,this 可以省略
val <T>List<T>.last: T get() = get(size - 1)
val listString = listOf("Android Q", "Android N", "Android M")
println("listString.last${listString.last}")
五、为伴生对象添加扩展
如果一个类定义了伴生对象 ,那么我们也可以为伴生对象定义扩展函数与属性:
class Jump {
companion object {}
}
fun Jump.Companion.print(str: String) {
println(str)
}
Jump.print("伴生对象的扩展")
就像伴生对象的常规成员一样:可以只使用类名作为限定符来调用伴生对象 的扩展成员;
六、Kotlin 中常用的扩展
在 Kotlin 的源码中定义了大量的扩展,比如:let,run,apply,also,with了解并运用这些 函数能帮我们提高编码效率!
参考:https://blog.csdn.net/m0_58941767/article/details/127043408