kotlin之 @JvmOverloads 的作用
@JvmOverloads 介紹
@Target([AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR]) annotation class JvmOverloads
Instructs the Kotlin compiler to generate overloads for this function that substitute default parameter values.
If a method has N parameters and M of which have default values, M overloads are generated: the first one takes N-1 parameters (all but the last one that takes a default value), the second takes N-2 parameters, and so on.
官網(wǎng)鏈接
以上就是kotlin官方對于kotlin @JvmOverloads 作用的解釋磅叛。
中文翻譯如下:
指示Kotlin編譯器為該函數(shù)生成替代默認參數(shù)值的重載贝椿。
如果一個方法有N個參數(shù)媳维,其中M個參數(shù)有默認值惠奸,那么就會生成M個重載紊扬。:第一個方法有N-1個參數(shù),第二個方法有N-2個參數(shù)烛亦,依此類推(除了最后一個方法都有默認值)坝咐。
加與不加@JvmOverloads對比
來段代碼對比下吧。
定義一個printPersonInfo方法撒桨,打印人物信息查刻,我們可以看到有兩個參數(shù)是有默認值的。
不加@JvmOverloads
首先讓我們看看不加@JvmOverloads 的情況
fun printPersonInfo(age:Int=0,name:String,sex:String="男"){
println("姓名:$name 年齡:$age 性別:$sex")
}
fun main() {
printPersonInfo(name = "chl")
}
其對應的反編譯Java代碼如下
public static final void overloadTest(int age, @NotNull String name, @NotNull String sex) {
Intrinsics.checkParameterIsNotNull(name, "name");
Intrinsics.checkParameterIsNotNull(sex, "sex");
String var3 = "姓名:" + name + " 年齡:" + age + " 性別:" + sex;
boolean var4 = false;
System.out.println(var3);
}
// $FF: synthetic method
public static void overloadTest$default(int var0, String var1, String var2, int var3, Object var4) {
if ((var3 & 1) != 0) {
var0 = 0;
}
if ((var3 & 4) != 0) {
var2 = "男";
}
overloadTest(var0, var1, var2);
}
public static final void main() {
overloadTest$default(0, "chl", (String)null, 5, (Object)null);
}
我們可以看到其對應的Java代碼是通過生成了一個 overloadTest$default
方法凤类,這個方法成為了外部調(diào)用的方法唉擂,在這個方法里面晃痴,進行了數(shù)據(jù)默認值的處理,然后再調(diào)用 overloadTest
方法。
加@JvmOverloads
接下來我們再來看下加上@JvmOverloads
注解的函數(shù)盘寡。
@JvmOverloads fun printPersonInfo(age:Int=0,name:String,sex:String="男"){
println("姓名:$name 年齡:$age 性別:$sex")
}
對應Java代碼
@JvmOverloads
public static final void printPersonInfo(int age, @NotNull String name, @NotNull String sex) {
Intrinsics.checkParameterIsNotNull(name, "name");
Intrinsics.checkParameterIsNotNull(sex, "sex");
String var3 = "姓名:" + name + " 年齡:" + age + " 性別:" + sex;
boolean var4 = false;
System.out.println(var3);
}
// $FF: synthetic method
public static void printPersonInfo$default(int var0, String var1, String var2, int var3, Object var4) {
if ((var3 & 1) != 0) {
var0 = 0;
}
if ((var3 & 4) != 0) {
var2 = "男";
}
printPersonInfo(var0, var1, var2);
}
@JvmOverloads
public static final void printPersonInfo(int age, @NotNull String name) {
printPersonInfo$default(age, name, (String)null, 4, (Object)null);
}
@JvmOverloads
public static final void printPersonInfo(@NotNull String name) {
printPersonInfo$default(0, name, (String)null, 5, (Object)null);
}
public static final void main() {
printPersonInfo$default(0, "chl", (String)null, 5, (Object)null);
}
從以上代碼可以看到,@JvmOverloads 注解的函數(shù)恳啥,對應的Java文件生成了一個所有參數(shù)都有的方法外油狂,還生成了2個重載方法,第一個2個參數(shù)企锌,第二個 1個參數(shù)榆浓。而所有的邏輯都在那個有所有參數(shù)的方法中,其他的方法通過調(diào)用printPersonInfo$default
來訪問該方法撕攒。
為什么用@JvmOverloads
通過以上代碼我們明白了 @JvmOverloads
的作用陡鹃,但是我們在使用kotlin編寫代碼時候烘浦。似乎@JvmOverloads
對我們的編碼毫無影響,我們?yōu)槭裁匆由纤仄季ǎ窟@其實主要是為了在java中調(diào)用kotlin代碼的時候能夠使用闷叉,如果不加 @JvmOverloads
, 當我們想要在Java中調(diào)用kotlin的方法時脊阴,是必須輸入所有參數(shù)的值得握侧,kotlin中默認參數(shù)我們無法使用。而當加上 @JvmOverloads
嘿期,kotlin編譯器生成的字節(jié)碼中有對應的重載方法品擎,我們就可以通過Java的重載方式來使用kotlin的代碼了,不必要輸入所有的參數(shù)备徐。
@JvmOverloads 使用范圍
kotlin中 構造函數(shù)萄传、頂級函數(shù)、類中方法蜜猾,靜態(tài)方法(@Jvmstatic修飾) 均可以采用@JvmOverloads
生成對應重載方法秀菱。
在主構造函數(shù)使用重載函數(shù),效果如下
kotlin代碼
class People @JvmOverloads constructor(age:Int=0,name:String,sex:String="男"){
}
java代碼
public final class People {
@JvmOverloads
public People(int age, @NotNull String name, @NotNull String sex) {
Intrinsics.checkParameterIsNotNull(name, "name");
Intrinsics.checkParameterIsNotNull(sex, "sex");
super();
}
// $FF: synthetic method
public People(int var1, String var2, String var3, int var4, DefaultConstructorMarker var5) {
if ((var4 & 1) != 0) {
var1 = 0;
}
if ((var4 & 4) != 0) {
var3 = "男";
}
this(var1, var2, var3);
}
@JvmOverloads
public People(int age, @NotNull String name) {
this(age, name, (String)null, 4, (DefaultConstructorMarker)null);
}
@JvmOverloads
public People(@NotNull String name) {
this(0, name, (String)null, 5, (DefaultConstructorMarker)null);
}
}
小結
本文主要講述了@JvmOverloads
關鍵字的作用蹭睡,其對應java代碼中效果衍菱,以及為什么使用@JvmOverloads
關鍵字,如有問題肩豁,還請批評指正脊串!
原創(chuàng)聲明
作者:陳浩亮
鏈接: