Kotlin中的 noArg 和 AllOpen插件
历史上的今天: (2021/3/30)
1998年3月30日 大众与宝马争夺劳斯莱斯
1998年3月30日,美国维克斯集团宣布,德国宝马汽车制造公司将以10亿马克(约合5.71亿美元)的价钱,买下集团旗下的劳斯莱斯汽车制造公司。自集团去年10月宣布将出售劳斯莱斯后,德国的宝马和大众公司争相出价购买,但劳斯莱斯最终还是看中了宝马。
4月20日,对英国老牌名车劳斯莱斯情有独钟的大众公司宣布将继续与宝马公司争夺对劳斯莱斯公司的收购权。由于最终决定将由维克斯集团4月底举行的股东大会作出,对此,大众公司表示将拿出更高的报价以及维护劳斯莱斯公司名牌产品的经营发展修改方案。果然,维克斯集团中两个较大的股东对将劳斯莱斯出售给宝马公司表示不满。于是,维克斯集团希望宝马公司将报价提高,但遭到拒绝,并称10亿马克是最高报价。
7月3日,维克斯集团决定以14.4亿马克把劳斯莱斯卖给大众公司。
7月28日,大众公司在花巨资购买劳斯莱斯还不到一个月,便宣布将它让给宝马公司。宝马撤销不久前宣布终止为劳斯莱斯提供发动机等配件的决定,并同意大众生产劳斯莱斯直到2002年12月31日。
前言:
众所周知,Google官方在前几年,就把Android推荐开发语言由java转变成了kotlin,所以很多伙伴在开发过程中都会java和kotlin混合开发.
在kotlin中没有数据类中如果有参数传递进来,没有默认赋值的话,则没办法创建无参构造,更没有final关键字,所以当java调用kotlin的数据类型时候,就会有一种疑惑,我怎么调用kotlin的无参构造呢?
编译成java字节码
咋们先来看看kotlin转换成java字节码是什么样子的:
kotlin数据类:
data class DataClass(val arg0: Int, val arg1: String)
双击shift:
鼠标放到左侧需要编译的地方,然后点击右侧选中编译成字节码:
编译后的字节码为:
public final class DataClass {
private final int arg0;
@NotNull
private final String arg1;
public final int getArg0() {
return this.arg0;
}
@NotNull
public final String getArg1() {
return this.arg1;
}
public DataClass(int arg0, @NotNull String arg1) {
Intrinsics.checkParameterIsNotNull(arg1, "arg1");
super();
this.arg0 = arg0;
this.arg1 = arg1;
}
public final int component1() {
return this.arg0;
}
@NotNull
public final String component2() {
return this.arg1;
}
@NotNull
public final DataClass copy(int arg0, @NotNull String arg1) {
...
}
// $FF: synthetic method
public static DataClass copy$default(DataClass var0, int var1, String var2, int var3, Object var4) {
...
}
@NotNull
public String toString() {
return "DataClass(arg0=" + this.arg0 + ", arg1=" + this.arg1 + ")";
}
public int hashCode() {
...
}
public boolean equals(@Nullable Object var1) {
...
}
}
kotlin转换成java后:
- 类/属性/getter/setter都添加了final关键字
- component1()是属性1(arg0)
- component2()是属性2(arg1)
- copy (浅拷贝)toString() ,hashCode(), equals()
可以看出并没有无参构造,而且加了很多final
什么是noArg 和 AllOpen
-
allOpen插件 是为了解决kotlin转换成java final的问题
-
noArgs是为了解决。kotlin转换成java没有无参勾构造的问题
noArg 和 AllOpen的使用
添加依赖:
![](https://i-blog.csdnimg.cn/blog_migrate/f431c6fcf61fa8c1f38cb3b7b62b62d7.png)
plugins {
//noArg插件第一步
id 'org.jetbrains.kotlin.plugin.noarg' version '1.3.60'
//AllOpen插件第一步
id 'org.jetbrains.kotlin.plugin.allopen' version '1.3.60'
}
//noArg插件第二步
noArg {
/**
* invokeInitializers = true 会执行init块代码
* invokeInitializers = false 不会执行init块代码
* 默认为false
*/
invokeInitializers = true
annotations "PoKo包名"
}
AllOpen插件第二步
allOpen {
annotations "PoKo包名"
}
Poko两种写法:
java:
public @interface PoKo {}
kotlin:
annotation class PoKo
最后在需要添加无参构造的地方调用@Poko注解即可;
@PoKo
data class DataClass(val arg0: Int, val arg1: String)
现在在来看看kt编译成java后的结果:
public class DataClass {
private final int arg0;
@NotNull
private final String arg1;
public int getArg0() {
return this.arg0;
}
@NotNull
public String getArg1() {
return this.arg1;
}
public DataClass(int arg0, @NotNull String arg1) {
Intrinsics.checkParameterIsNotNull(arg1, "arg1");
super();
this.arg0 = arg0;
this.arg1 = arg1;
}
public final int component1() {
return this.getArg0();
}
@NotNull
public final String component2() {
return this.getArg1();
}
@NotNull
public final DataClass copy(int arg0, @NotNull String arg1) {
....
}
// $FF: synthetic method
public static DataClass copy$default(DataClass var0, int var1, String var2, int var3, Object var4) {
....
}
@NotNull
public String toString() {
return "DataClass(arg0=" + this.getArg0() + ", arg1=" + this.getArg1() + ")";
}
public int hashCode() {
....
}
public boolean equals(@Nullable Object var1) {
....
}
public DataClass() {
}
}
可以看出编译后有了无参构造,并且类上,setter/getter的final关键字也没有了
最后在java中调用试一下:
invokeInitializers
还有一个参数需要注意一下:
![](https://i-blog.csdnimg.cn/blog_migrate/74b3b262aed38f6b4d04f6bb3e093fd1.png)
当java调用kotlin时:
- invokeInitializers = true 会执行init块代码
- invokeInitializers = false 不会执行init块代码
修改kotlin数据类:
@PoKo
data class DataClass(val arg0: Int, val arg1: String){
init {
println("我是Kotlin类DataClass中的init")
}
}
java调用kotlin:
如您对某处不理解,请在评论区留言!
原创不易,您的点赞就是对我最大的支持~