当从Kotlin调用非可空性注释的Java函数时,我们得到灵活类型的返回值,用感叹号表示,例如: String!
.
Kotlin默默地允许将这些灵活值分配给正常的非空类型,例如, String
,可能会在运行时导致NullPointerExceptions .
我更希望得到编译器警告或错误的此类分配 . 或者,将平台类型视为等效于可空类型(例如 String?
) .
例如,使用此Java代码:
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
public class NullTest {
private String maybe() {
if (SystemClock.elapsedRealtimeNanos() % 2 == 0) {
return null;
}
return "ok";
}
public String annotatedNothing() { return maybe(); }
@Nullable public String annotatedNullable() { return maybe(); }
@NonNull public String annotatedNonNull() { return "ok"; }
}
...以及以下Kotlin代码,我想在两个新行上看到错误(请参阅注释):
fun testnulls() {
val obj = NullTest()
val nullExact: String = obj.annotatedNullable() // already gives an error
val nullMaybe: String? = obj.annotatedNullable()
val nullInfer = obj.annotatedNullable()
val okayExact: String = obj.annotatedNonNull()
val okayMaybe: String? = obj.annotatedNonNull()
val okayInfer = obj.annotatedNonNull()
val bareExact: String = obj.annotatedNothing() // I want a compiler error here
val bareMaybe: String? = obj.annotatedNothing()
val bareInfer = obj.annotatedNothing()
print("length " + nullExact.length)
print("length " + nullMaybe.length) // already gives an error
print("length " + nullInfer.length) // already gives an error
print("length " + okayExact.length)
print("length " + okayMaybe.length) // already gives an error
print("length " + okayInfer.length)
print("length " + bareExact.length)
print("length " + bareMaybe.length) // already gives an error
print("length " + bareInfer.length) // I want a compiler error here
}
关键是这将迫使我添加空检查或 !!
,确保我至少必须明确它 .
这可能吗?
在这个2014 JetBrains blog post的评论中,当他们引入平台/灵活类型时,听起来他们计划添加一个选项来警告这些情况,但我还没有找到任何进一步的信息 .
3 回答
Kotlin documentation描述了这个确切的情况:
不幸的是,这意味着在编译期间无法发出警告 . 一线希望是Kotlin至少会阻止null在运行时传播 .
如果我不控制我使用的Java库的源代码,我将所有结果视为可能为空的,除非很明显它们不是 .
Yes, it is possible 为Java方法的任何赋值获取编译器警告和/或错误,强烈假设if方法没有
@NotNull
注释,它是@Nullable
.怎么样? :) You will have to write your own Idea Custom Inspection plugin .
这里有一些有用的链接,适合任何有经验的人 Build 自定义检查插件(可能我会成为其感恩的用户之一):
Idea插件开发Quick Start Guide
所有现有Idea Kotlin Inspections的来源(可能作为现有null safety checks的示例有用)
如果您是熟悉且经验丰富的Idea插件开发人员,那么可能不会花费很多时间 . 否则我不认为你将要实现的结果真的值得你花费的时间 .
我喜欢你的想法,但AFAIK在
kotlin
开发的早期阶段试图尽可能实现完全无效的安全检查,并且转为如此,有太多可能不安全的分配 .附:如果您最终构建该检查插件,请告诉我 . 我个人试图制作它,但在我的情况下,我将首先了解有关Idea插件的更多信息 .
for non-null Strings -
检查isEmpty() . 您将无法在该方法中传递非空字符串 . 所以这是类型安全的 .
for null Strings -
如果条件允许,你可以检查null .