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.
官網鏈接
以上就是kotlin官方對于kotlin @JvmOverloads 作用的解釋。
中文翻譯如下:
指示Kotlin編譯器為該函數生成替代默認參數值的重載。
如果一個方法有N個參數,其中M個參數有默認值,那么就會生成M個重載。:第一個方法有N-1個參數,第二個方法有N-2個參數,依此類推(除了最后一個方法都有默認值)。
加與不加@JvmOverloads對比
來段代碼對比下吧。
定義一個printPersonInfo方法,打印人物信息,我們可以看到有兩個參數是有默認值的。
不加@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
方法,這個方法成為了外部調用的方法,在這個方法里面,進行了數據默認值的處理,然后再調用 overloadTest
方法。
加@JvmOverloads
接下來我們再來看下加上@JvmOverloads
注解的函數。
@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 注解的函數,對應的Java文件生成了一個所有參數都有的方法外,還生成了2個重載方法,第一個2個參數,第二個 1個參數。而所有的邏輯都在那個有所有參數的方法中,其他的方法通過調用printPersonInfo$default
來訪問該方法。
為什么用@JvmOverloads
通過以上代碼我們明白了 @JvmOverloads
的作用,但是我們在使用kotlin編寫代碼時候。似乎@JvmOverloads
對我們的編碼毫無影響,我們為什么要加上它呢?這其實主要是為了在java中調用kotlin代碼的時候能夠使用,如果不加 @JvmOverloads
, 當我們想要在Java中調用kotlin的方法時,是必須輸入所有參數的值得,kotlin中默認參數我們無法使用。而當加上 @JvmOverloads
,kotlin編譯器生成的字節碼中有對應的重載方法,我們就可以通過Java的重載方式來使用kotlin的代碼了,不必要輸入所有的參數。
@JvmOverloads 使用范圍
kotlin中 構造函數、頂級函數、類中方法,靜態方法(@Jvmstatic修飾) 均可以采用@JvmOverloads
生成對應重載方法。
在主構造函數使用重載函數,效果如下
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
關鍵字,如有問題,還請批評指正!
原創聲明
作者:陳浩亮
鏈接: