我是Kotlin 的新手,我读到它似乎是继轮子之后最好的发明.这让我产生了怀疑,当然是因为我不理解这个概念所暗示的一切.

继续我的理解,在我们有NullPointerException个之前,我们非常清楚地知道代码中有什么错误,问题发生在哪里,但不知道空值是在哪里设置的.无论如何,很明显,我们可以在这里等待,直到空指针返回,以了解从回溯中发生了什么.每个人都已经这么做了,这从来都是不可能找到的.

Now with Null Pointer Safety, we do not have such crash anymore, just some part the code which silently won't be executed in our application (we assume the reference used is not supposed to be null as before, of course), causing maybe strange behavior even more complicated to understand than the NullPointerException before, or maybe just some tasks not executed for month before someone realize it.

Is it the benefits Null Pointer Safety offer?

推荐答案

I will assume that you come from Java, you already looked at some explanations somewhere else and did not fully understand them. Therefore, I will not try to give you a comprehensive explanation (which you can find elsewhere) but instead I will try to make clear the core idea of null pointer safety.

There are two points that, if you understand them, should make it clear enough. First, there is the idea of having two separate types to represent what you would model as a single type in Java: nullable ones and not nullable ones. To give you an example, while in Java you put a string in a String object, without caring if the string can be null or not, in Kotlin you have two types: String? and String. The first accepts null values (like the Java equivalent) but the second does not. So you can have null values in types with a ? (like String? or Int?) but there are a lot of restrictions on what you can do with those: basically you are restricted to the things you can do with a null, because, after all, the variable could be holding a null value. So no calling of method on it, for instance. So, while in Java you could call a method on it and have a NullPointerException sometimes, in Kotlin you cannot call any methods. And this is not because of some silent behavior of Kotlin, it’s much simpler than that: the compiler won’t let you. Try and you will see that the program does not compile. If the variable was of type String instead of String? then Kotlin would allow you to call methods from it.

因此,基本上没有空指针异常,因为您永远不能对可能为空的对象变量调用方法.

But then, sometimes the variable is not null: so how could you call the method on the variable in those cases where the variable is not null? Again, the answer is simple: you have to check it. I mean, you have to use an if instruction (explicitly or implicitly) that will check if the variable is null or not. Something like “if (myVariable != null) {call method on variable}”. So, as you can see, the Kotlin compiler is clever enough to see that you used an if instruction that guarantees that the variable is not null, so it will let you call methods on the variable in the block between { and }. In other words, if your variable is of type String? but you are inside an if block where you checked that the variable is not null, Kotlin will treat it like a variable of type String instead of String?

When you speak about

some part the code which silently won't be executed

我猜你在想一些操作符,里面有一个隐式的if,比如?.操作符.如果你写信

myVariable?.call()

it means roughly

if (myVariable != null) { myVariable.call()}

因此,事实上,如果变量为null,它将silent地"失败".但是如果你使用同样的if,这和Java没有什么不同.换句话说,如果变量为null,则不会发生任何事情,因为您显式地将其编码为那样的行为.

Kotlin相关问答推荐

将基于注册的服务转换为流

如何为集成测试配置Gradle JVM测试套件?

协程子作业(job)取消

修改器的属性是什么,我需要更改以使角变圆且宽度更小?喷气背包组合

为什么多线程不会使执行更快

如何在 kotlin 中使用带有泛型的密封类

Mixin 在 Jackson 中添加 defaultImpl 不起作用

添加 Kapt 插件后 - 执行 org.jetbrains.kotlin.gradle.internal.KaptExecution 时发生故障

为什么 IntelliJ Idea 无法识别我的 Spek 测试?

runBlocking 中的 deferred.await() 抛出的异常即使在被捕获后也被视为未处理

比较 Kotlin 中的可比对象列表

如何在 Spring WebFlux 的响应正文中流式传输二进制数据

如何在 Kotlin 中传递有界通配符类型参数?

无法在Kotlin中使用argb color int值?

如何在Kotlin中获得KType?

ObjectAnimator.ofFloat 不能直接在kotlin中取Int作为参数

如何在Android Studio 4.1中默认启用Kotlin Android扩展

Dagger +Kotlin 不注入

内联 Kotlin 方法没有覆盖报告

如何在伴随对象中使用泛型