在 Java 中,您不能扩展最终类,但在 Kotlin 中,您可以为此类最终类编写扩展方法。他们是如何让它在内部运作的?我找不到任何解释 Kotlin 扩展方法内部工作原理的文章。
问问题
1482 次
2 回答
8
在 Java 中,您不能扩展最终类,但在 Kotlin 中,您可以为此类最终类编写扩展方法
我认为您假设扩展方法使用了继承,但事实并非如此。它是一种伪装成 kotlin 语法糖的静态方法。例如看下面的简单扩展方法:
String.removeSpace(): String {
return this.replace(" ", "")
}
你可以认为它等同于下面的 java 代码。
static String removeSpace(String input) {
return input.replace(" ", "")
}
kotlin 在这里所做的是它在顶部提供了包装器,以便通过使用this
您可以获得调用者的实例。通过将其与 Kotlin 将函数定义为一等公民的能力相结合,您可以编写如下优雅的东西:
fun String.removeSpace() = this.replace(" ", "")
于 2020-08-06T15:04:42.680 回答
4
如果您想知道 Kotlin 代码是如何转换为 Java 代码的,有一种方法可以查看它。IntelliJ 为 Java 代码提供反编译 Kotlin 字节码。你可以找到它Tools -> Kotlin -> Show Kotlin Bytecode
并点击它Decompile
。然后它将显示 Java 代码。
这是一个例子。
科特林
val Int.asByteArray get() =
byteArrayOf(
(this shr 24).toByte(),
(this shr 16).toByte(),
(this shr 8).toByte(),
this.toByte())
val Int.asHex get() = this.asByteArray.asHexUpper
@ExperimentalUnsignedTypes
val ByteArray.asInt get() =
((this[0].toUInt() and 0xFFu) shl 24) or
((this[1].toUInt() and 0xFFu) shl 16) or
((this[2].toUInt() and 0xFFu) shl 8) or
(this[3].toUInt() and 0xFFu)
爪哇
public final class IntExtensionKt {
@NotNull
public static final byte[] getAsByteArray(int $this$asByteArray) {
return new byte[]{(byte)($this$asByteArray >> 24), (byte)($this$asByteArray >> 16), (byte)($this$asByteArray >> 8), (byte)$this$asByteArray};
}
@NotNull
public static final String getAsHex(int $this$asHex) {
return HexExtensionKt.getAsHexUpper(getAsByteArray($this$asHex));
}
/** @deprecated */
// $FF: synthetic method
@ExperimentalUnsignedTypes
public static void asInt$annotations(byte[] var0) {
}
public static final int getAsInt(@NotNull byte[] $this$asInt) {
Intrinsics.checkParameterIsNotNull($this$asInt, "$this$asInt");
byte var1 = $this$asInt[0];
boolean var2 = false;
int var5 = UInt.constructor-impl(var1);
short var6 = 255;
boolean var3 = false;
var5 = UInt.constructor-impl(var5 & var6);
byte var7 = 24;
var3 = false;
var5 = UInt.constructor-impl(var5 << var7);
byte var8 = $this$asInt[1];
var3 = false;
int var9 = UInt.constructor-impl(var8);
short var10 = 255;
boolean var4 = false;
var9 = UInt.constructor-impl(var9 & var10);
byte var11 = 16;
var4 = false;
var9 = UInt.constructor-impl(var9 << var11);
var3 = false;
var5 = UInt.constructor-impl(var5 | var9);
var8 = $this$asInt[2];
var3 = false;
var9 = UInt.constructor-impl(var8);
var10 = 255;
var4 = false;
var9 = UInt.constructor-impl(var9 & var10);
var11 = 8;
var4 = false;
var9 = UInt.constructor-impl(var9 << var11);
var3 = false;
var5 = UInt.constructor-impl(var5 | var9);
var8 = $this$asInt[3];
var3 = false;
var9 = UInt.constructor-impl(var8);
var10 = 255;
var4 = false;
var9 = UInt.constructor-impl(var9 & var10);
var3 = false;
return UInt.constructor-impl(var5 | var9);
}
}
如您所见,Kotlin 扩展方法变成了 Java中的public final static
方法。final class
于 2020-08-06T17:45:12.157 回答