快捷搜索:  汽车  科技

kotlin脚本原理(Kotlin里的ExtensionFunctions实现原理分析)

kotlin脚本原理(Kotlin里的ExtensionFunctions实现原理分析)执行后,输出结果是:fun String.hello(world : String) : String { return "hello " world this.length; } fun main(args: Array<String>) { System.out.println("abc".hello("world")); } 可以看到在main函数里,直接可以在String上调用hello函数。Kotlin里的Extension Functionskotlin里有所谓的扩展函数(Extension Functions),支持给现有的Java类增加函数。比如给String增加一个hello函数,可以这样子写:

本文来自阿里云云栖社区,未经许可禁止转载。

更多资讯,尽在云栖科技快讯~

来科技快讯看新闻鸭~

快点关注我认识我爱上我啊~~~

kotlin脚本原理(Kotlin里的ExtensionFunctions实现原理分析)(1)


Kotlin里的Extension Functions

kotlin里有所谓的扩展函数(Extension Functions),支持给现有的Java类增加函数。

  • https://kotlinlang.org/docs/reference/extensions.html

比如给String增加一个hello函数,可以这样子写:

fun String.hello(world : String) : String { return "hello " world this.length; } fun main(args: Array<String>) { System.out.println("abc".hello("world")); }

可以看到在main函数里,直接可以在String上调用hello函数。

执行后,输出结果是:

hello world3

可以看到在hello函数里的this引用的是"abc"。

刚开始看到这个语法还是比较新奇的,那么怎样实现的呢?如果不同的库都增加了同样的函数会不会冲突?

反编绎生成的字节码,结果是:

@NotNull public static final String hello(@NotNull String $receiver @NotNull String world) { return "hello " world $receiver.length(); } public static final void main(@NotNull String[] args) { System.out.println(hello("abc" "world")); }

可以看到,实际上是增加了一个static public final函数。

并且新增加的函数是在自己的类里的,并不是在String类里。即不同的库新增加的扩展函数都是自己类里的,不会冲突。

lombok 里的 @ExtensionMethod 实现

lombok里也提供了类似的@ExtensionMethod支持。

  • https://projectlombok.org/features/experimental/ExtensionMethod

和上面的例子一样,给String类增加一个hello函数:

  • 需要定义一个class Extensions
  • 再用@ExtensionMethod声明

class Extensions { public static String hello(String receiver String world) { return "hello " world receiver.length(); } } @ExtensionMethod({ Extensions.class }) public class Test { public static void main(String[] args) { System.out.println("abc".hello("world")); } }

执行后,输出结果是:

hello world3

可以看到在hello函数里,第一个参数String receiver就是"abc"本身。

和上面kotlin的例子不一样的是,kotlin里直接可以用this。

生成的字节码反编绎结果是:

class Extensions { public static String hello(String receiver String world) { return "hello " world receiver.length(); } } public class Test { public static void main(String[] args) { System.out.println(Extensions.hello("abc" "world")); } }

可以看到所谓的@ExtensionMethod实际上也是一个语法糖。

设计动机

  • https://kotlinlang.org/docs/reference/extensions.html#motivation

据kotlin的文档:各种FileUtils,StringUtils类很麻烦。

比如像下面处理List,在java里可以用java.util.Collections

// Java Collections.swap(list Collections.binarySearch(list Collections.max(otherList)) Collections.max(list));

简化下import,可以变为

// Java swap(list binarySearch(list max(otherList)) max(list));

但是还不够清晰,各种import *也是比较烦的。利用扩展函数,可以直接这样子写:

// Java list.swap(list.binarySearch(otherList.max()) list.max());

总结

  • kotlin的Extension Functions和lombok的@ExtensionMethod实际上都是增加public static final函数
  • 不同的库增加的同样的Extension Functions不会冲突
  • 设计的动机是减少各种utils类。

猜您喜欢: