写在前面
Kotlin
代码可以经过编译器转换成VM虚拟机
能识别的字节码,所以Java
与Kotlin
可以互相进行调用。而由于Java
与Kotlin
语言特性的差异,当Java
调用Kotlin
代码时,可以在Kotlin
代码中适当增加一些注解,从而更方便的调用Kotlin
代码。
@JvmOverloads
在Kotlin
的方法里有多个默认参数时,如果在Java
中直接调用,只能调用一个包含完整参数的方法,如果想暴露更多的重载函数给Java
,可以使用@JvmOverloads
用于生成重载。对于每一个有默认值的参数,生成的重载会把当前有默认值的参数及其右边的参数都去掉,所以如果方法中所有的参数都有默认值,生成的重载函数中还会有一个无参的重载函数。
@JvmOverloads
主要用于构造函数、方法中,同时不能用于抽象方法、接口中的方法等。
- 应用在方法中
@JvmOverloads
fun method(a: Int, b: Boolean = true, c: String = "c") {
}
转换成Java后:
//1
@JvmOverloads
public final void method(int a, boolean b, @NotNull String c) {
Intrinsics.checkNotNullParameter(c, "c");
}
//2
@JvmOverloads
public final void method(int a, boolean b) {
method$default(this, a, b, (String)null, 4, (Object)null);
}
//3
@JvmOverloads
public final void method(int a) {
method$default(this, a, false, (String)null, 6, (Object)null);
}
//4: synthetic method
public static void method$default(KtAnnotation var0, int var1, boolean var2, String var3, int var4, Object var5) {
if ((var4 & 2) != 0) {
var2 = true;
}
if ((var4 & 4) != 0) {
var3 = "c";
}
var0.method(var1, var2, var3);
}
- 应用在自定义View构造函数中
class VpLoadMoreView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0,
) : LinearLayout(context, attrs, defStyle) {}
转换成Java代码后:
public final class VpLoadMoreView extends LinearLayout {
//1
@JvmOverloads
public VpLoadMoreView(@NotNull Context context) {
this(context, (AttributeSet)null, 0, 6, (DefaultConstructorMarker)null);
}
//2
@JvmOverloads
public VpLoadMoreView(@NotNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0, 4, (DefaultConstructorMarker)null);
}
//3
@JvmOverloads
public VpLoadMoreView(@NotNull Context context, @Nullable AttributeSet attrs, int defStyle) {
Intrinsics.checkNotNullParameter(context, "context");
super(context, attrs, defStyle);
}
//4: synthetic method
public VpLoadMoreView(Context var1, AttributeSet var2, int var3, int var4, DefaultConstructorMarker var5) {
if ((var4 & 2) != 0) {
var2 = (AttributeSet)null;
}
if ((var4 & 4) != 0) {
var3 = 0;
}
this(var1, var2, var3);
}
}
如果将注解去掉,转换成Java
后:
public final class VpLoadMoreView extends LinearLayout {
//1
public VpLoadMoreView(@NotNull Context context, @Nullable AttributeSet attrs, int defStyle) {
Intrinsics.checkNotNullParameter(context, "context");
super(context, attrs, defStyle);
}
//2: synthetic method
public VpLoadMoreView(Context var1, AttributeSet var2, int var3, int var4, DefaultConstructorMarker var5) {
if ((var4 & 2) != 0) {
var2 = (AttributeSet)null;
}
if ((var4 & 4) != 0) {
var3 = 0;
}
this(var1, var2, var3);
}
}
可以看到去掉了@JvmOverloads
注解,少了1个、2个参数的构造函数了,那么在Java
中也不能初始化1个、2个参数的构造函数了。
@JvmStatic
@JvmStatic
用于声明静态方法。在具名对象及伴生对象中使用时,既会在相应对象的类中生成静态方法,也会在对象自身中生成实例方法,如:
class KtA {
companion object {
@JvmStatic
fun invokeStatic() {}
fun invokeNoStatic() {}
}
}
在Java中调用:
public void invokeKt() {
KtA.invokeStatic(); //正确,可以直接调用
//KtA.invokeNoStatic(); //错误,这里调用不到
KtA.Companion.invokeStatic(); //正确
KtA.Companion.invokeNoStatic(); //正确
}
@JvmField
@JvmField
使得编译器不再对该字段生成getter/setter
并将其作为公开字段,如:
val id1 = 100 //1
@JvmField
val id2 = 200 //2
var id3 = 300 //3
@JvmField
var id4 = 400 //4
编译成Java后:
private final int id1 = 100;
@JvmField
public final int id2 = 200;
private int id3 = 300;
@JvmField
public int id4 = 400;
public final int getId1() {
return this.id1;
}
public final int getId3() {
return this.id3;
}
public final void setId3(int var1) {
this.id3 = var1;
}
@JvmSynthetic
@JvmSynthetic
可以修饰于方法上,控制只能在Kotlin
中调用,如:
//kt代码
class KtA {
@JvmSynthetic
fun visit() {}
}
Java中调用:
public void invokeKt() {
KtA clz = new KtA();
clz.visit(); //错误,这里在Java中调用不到。
}
如果想在Java
中调用到Kotlin
类中的方法,将@JvmSynthetic
去掉即可。
@JvmName 、@JvmMultifileClass
@JvmName
注解可以生成类名;如果类名已存在,可以修改已生成的 Java
类的类名。
包名相同并且类名相同或者有相同的 @JvmName
注解有会错误,可以通过@JvmMultifileClass
把他们合并到一起,如:
//A.kt
@file:JvmName("generate")
@file:JvmMultifileClass
package org.ninetripods
fun getA() {}
//B.kt
@file:JvmName("generate")
@file:JvmMultifileClass
package org.ninetripods
fun getB() {}
Java
中调用:
org.ninetripods.generate.getA();
org.ninetripods.generate.getB();
@JvmInline
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@SinceKotlin("1.5")
public actual annotation class JvmInline
@JvmInline
在1.5.0
版本引入,可以指定一个类为内联类,需结合value
一起使用;在1.5.0
之前使用inline
关键字。
//1.5.0之前,inline标记内联类
inline class Person(private val name: String = "")
//1.5.0之后,@JvmInline + value 标记内联类
@JvmInline
value class Person(private val name: String = "")
内联类构造参数中有且只能有一个成员变量,最终被内联到字节码中的value。,上述代码经过内联优化会在字节码中将Person
对象转换为String
值,从而由堆分配优化为栈分配。
文章来源于互联网:Kotlin之@JvmOverloads、@JvmStatic、@JvmField、@JvmInline等注解使用总结
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/19811,转载请注明出处。
评论0