Kotlin默认参数基本用法、构造函数、与 Java 代码相互调用

 Kotlin默认参数是一个简短而易用的功能,它可以让您无需模版代码便可实现函数重载。和 Kotlin 所提供的许多其他功能一样,默认参数会给人一种魔法般的感觉。如果您想要知道其中的奥秘,请继续阅读,本文将会揭晓默认参数内部的工作原理。

  • 默认参数
基本用法

如果您需要重载一个函数,您可以使用默认参数,而不是将同一个函数实现许多次:




// 无需像下面这样实现:
fun play(toy: Toy){ ... }


fun play(){
    play(SqueakyToy)
}


// 使用默认参数:
 fun play(toy: Toy = SqueakyToy)


fun startPlaying() {
    play(toy = Stick)
    play() // toy = SqueakyToy
}
  • @JvmOverloads

int 参数

play$default 函数中 int 参数的值是基于传入的有默认参数的参数数量和其索引计算的。根据这一参数的值,Kotlin 编译器可以知道在调用 play 函数时使用哪个参数。

 

在我们的 play() 函数的示例代码中,索引位置为 0 的参数使用了默认参数。所以 play$default 在调用时传入的 int 参数为 int var1 = 2⁰:

play$default((Toy)null, 1, (Object)null);

这样一来,play$default 的实现便可以知道 var0 的值应当被替换为默认值。

 

为了进一步了解 int 参数的行为,我们来观察一个更为复杂的例子。让我们扩展 play 函数,并在调用时使用 doggo 和 toy 的默认参数:

/* Copyright 2020 Google LLC.  
   SPDX-License-Identifier: Apache-2.0 */
   
fun play(doggo: Doggo = goodDoggo, doggo2: Doggo = veryGoodDoggo, toy: Toy = SqueakyToy) {...}


fun startPlaying() {
    play2(doggo2 = myDoggo)
}

让我们来看看反编译后的代码中发生了什么:

/* Copyright 2020 Google LLC.  
   SPDX-License-Identifier: Apache-2.0 */
   
public static final void play(@NotNull Doggo doggo, @NotNull Doggo doggo2, @NotNull Toy toy) {
...
 }


// $FF: synthetic method
public static void play$default(Doggo var0, Doggo var1, Toy var2, int var3, Object var4) {
  if ((var3 & 1) != 0) {
     var0 = goodDoggo;
  }


  if ((var3 & 2) != 0) {
     var1 = veryGoodDoggo;
  }


  if ((var3 & 4) != 0) {
     var2 = SqueakyToy;
  }


  play(var0, var1, var2);
}


public static final void startPlaying() {
    play2$default((Doggo)null, myDoggo, (Toy)null, 5, (Object)null);
 }