我知道我不应该在这里问“为什么”这些问题,但我希望这是允许的例外之一,因为它是与代码相关的问题。我只是不知道这种新语言的后果。
我正在使用Android studio 3.0 canary 3,我正在将Java代码转换为Kotlin。很多代码都是手动转换的,但是其他一些代码我将它通过复制/粘贴java转换为新的Kotlin文件。
到目前为止,这么好。但是,我开始注意到这一点:
Java代码:
class MyClass {
private String userId;
private Long newFolderId;
private int oldFolderId;
public MyClass(final String userId, final Long newFolderId, final int oldFolderId) {
this.userId = userId;
this.newFolderId = newFolderId;
this.oldFolderId = oldFolderId;
}
}
我将这小块代码复制到Kotlin,它会自动转换为:
class MyClass(private val userId: String,
private val newFolderId: Long?,
private val oldFolderId: Int)
所以,我现在的问题是为什么Long
转换为Long?
如果这是安全的,那么所有变量不应该是?
吗?比如,String?
和Int?
为什么只是Long
?
另外,我知道我在这堂课上花了很长时间,所以从长片中删除?
并将其称为Long
会不会很糟糕?
感谢您的帮助。
答案 0 :(得分:2)
问题是为什么Kotlin将原始Kotlin类型转换为可空类型?
首先--Kotlin没有原始类型 - 它只能在JVM上优化一些基本类型表示。 Kotlin Basic Types
第二 - 重要的是要注意您正在将Java代码转换为Kotlin。因此,您的Java代码及其类型会在转换方面产生影响。
在Java Long
中是类,而不是基本类型。在Java中,long
是Long
的原始对应物。
因此,您的Long
参数在Java中可以为null,并且它被正确地转换为可空Long?
您的int
参数在Java中是原始类型 - 它不能为空 - 并且它被转换作为不可空的Int
如果您有不同的Java类声明
class MyClass {
private String userId;
private long newFolderId;
private int oldFolderId;
public MyClass(final String userId, final long newFolderId, final int oldFolderId) {
this.userId = userId;
this.newFolderId = newFolderId;
this.oldFolderId = oldFolderId;
}
}
它将被转换为
internal inner class MyClass(private val userId: String, private val newFolderId: Long, private val oldFolderId: Int)
正如您所见,原始long
已转换为不可为空的Long
为什么非原始String
类型确切地转换为非可空?
问题的这一部分是基于意见的 - 或者至少答案是。
String
可能因其性质而有特殊待遇 - 空字符串可用作默认值。在许多语言中,字符串有特殊的处理和考虑。大多数情况下,您希望String
变量不可为空。由于Kotlin强调null安全性,因此默认代码转换将String
视为不可为空是合乎逻辑的。
就无效安全而言。当你可以使用非可空类型时,每一段代码都比使用可空类型的代码更安全,更易于处理。因此Long
优先于适用的Long?
。