代码如下:
class B {
operator fun invoke() {
println("B invoke")
}
}
class A(val b: B?) {
// @Suppress("UNSAFE_CALL")
fun a() {
if (b != null) {
b.invoke()
b()
}
}
}
反编译后的java代码:
public final void a() {
if (this.b != null) {
this.b.invoke();
this.b.invoke();
}
}
上述代码idea会在b()处提示
Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type B?
给A类的a函数加上 @Suppress("UNSAFE_CALL")
后idea不标红了,编译时会提示 Error:(16, 13) Kotlin: Reference has a nullable type 'B?', use explicit '?.invoke()' to make a function-like call instead
。
但是如果将B类改成下面这样子,将invoke从对象体里面移出来用扩展函数实现就不会在报错了:
class B
operator fun B.invoke() {
println("B invoke")
}
反编译后的java代码:
public final void a() {
if (this.b != null) {
AaaKt.invoke(this.b);
B var10000 = this.b;
Intrinsics.checkExpressionValueIsNotNull(var10000, "b");
AaaKt.invoke(var10000);
}
}
主要问题有三个个:
1、为什么将invoke方法改为扩展函数后并且输出正确结果而类方法却不行?
2、作为类方法时从idea自带的反编译工具生成的结果来看都b()和invoke()生成的字节码都是一样的且符合预期,为什么kotlin编译器却在编译时报错?
3、印象中Suppress应该能够抑制编译时的异常的,但是这里仍然报错了,是要有什么特殊条件才能抑制吗?