繁体   English   中英

在不破坏二进制向后兼容性的情况下,Java 中的扩展方法可能吗?

[英]Extension Methods in Java possible without breaking Binary Backwards Compatibility?

几种语言都有扩展方法,如 C#、Ruby、Smalltalk、Kotlin、Scala。 这个想法是你可以向一个类添加方法,该类对于扩展是封闭的,比如系统类,如 String、Integer 或最终类,如 ArrayList。

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

Java 没有扩展方法。 我的问题是是否可以将扩展方法添加到 Java 中,而不会破坏二进制向后兼容性,就像过去使用 Java8 lambda 或其他功能的示例一样。 问题仅在于是否可以在不降低向后兼容性的情况下完成。

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

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

我不知道这个问题的最终答案,但这里是 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();
}

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

关于 Kotlin 扩展的更多信息

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM