0

几种语言都有外部方法,如 C#、Ruby、Smalltalk、Kotlin、Scala。这个想法是,您可以将方法添加到对扩展关闭的类中,例如系统类(如 String、Integer)或最终类(如 ArrayList)。

因此,您只需添加相应的扩展方法,而不是拥有所有这些 Util-Classes。因此,您可以调用“foo”.split() 而不是 StringUtils.split(...)。

Java 没有扩展方法。我的问题是是否可以在不破坏二进制向后兼容性的情况下将扩展方法添加到 Java 中,例如过去使用 Java8 lambda 或其他功能。问题只是关于它是否可以在不制动向后兼容性的情况下完成。

在 C# 和 Kotlin 中,扩展方法被实现为静态方法。因此,与 Java 相同,StringUtils.split(...) 会有一些额外的语法,它会告诉 Java 编译器在编译时“foo”.split() 必须替换为 StringUtils.split( ...)。至少,我认为这是在 C# 和 Kotlin 中发生的。

同样,我的问题只是关于 Java 中的扩展方法是否可以在不影响向后兼容性的情况下完成。只是。

4

1 回答 1

0

我不知道这个问题的最终答案,但这就是 Kotlin 是如何做到的,这对于 Java 来说也可能是可能的。

让我们考虑一个简单的扩展String

fun String.lengthSquare() = length * length

Kotlin 编译器生成类似于以下的字节码(显示为对应的 Java 代码):

public static final int lengthSquare(@NotNull String $this$lengthSquare) {
   Intrinsics.checkParameterIsNotNull($this$lengthSquare, "$this$lengthSquare");
   return $this$lengthSquare.length() * $this$lengthSquare.length();
}

所以基本上它只是创建一个接受 a 的静态方法String,就像我们从实用程序方法中知道的那样。我相信 Java 编译器可以做类似的事情。当然,这些扩展函数的所有调用点都会在 JVM 字节码中使用该静态方法。

有关 Kotlin 扩展的更多信息

扩展实际上并不修改它们扩展的类。通过定义扩展,您不会将新成员插入到类中,而只是使新函数可以使用这种类型的变量的点符号调用。

于 2020-01-27T10:24:44.247 回答