【发布时间】:2019-12-15 21:54:36
【问题描述】:
Kotlin 有原始类型吗?当我声明变量时:val myAge: Int = 18 那么myAge 变量存储实际值是18 还是将对象的地址存储在内存中?如果Int是原始类型,那么为什么我们可以使用myAge.minus(10)这样的方法呢?
【问题讨论】:
标签: kotlin primitive-types reference-type
Kotlin 有原始类型吗?当我声明变量时:val myAge: Int = 18 那么myAge 变量存储实际值是18 还是将对象的地址存储在内存中?如果Int是原始类型,那么为什么我们可以使用myAge.minus(10)这样的方法呢?
【问题讨论】:
标签: kotlin primitive-types reference-type
不...是的。
Kotlin 没有原始类型(我的意思是您不能直接声明原始类型)。它使用Int、Float 等类作为基元的对象包装器。
当 kotlin 代码转换为 jvm 代码时,尽可能将“原始对象”转换为 java 原始代码。
在某些情况下,这是无法做到的。例如,这些情况是“原语”的集合。例如,List<Int> 不能包含原语。因此,编译器知道何时可以将对象转换为原始对象。而且,它与 java 非常相似:
List<Integer> numbers = new ArrayList<>;
numbers.add(0); // <-- you use primitive, but in fact, JVM will convert this primitive to object.
numbers.add(new Integer(0)); // <-- We don't need do that.
此外,当您声明“可空基元”时,它永远不会转换为基元(这很明显,因为基元不能为空)。在java中它的工作方式非常相似:
int k = null; // No way!
Integer kN = null; // That's OK.
还有一件事 - 文档是怎么说的?
通用、JVM、JS
表示一个 32 位有符号整数。在 JVM 上,这种类型的不可为空的值表示为原始类型 int 的值。
原生
表示一个 32 位有符号整数。
@见:https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/index.html
所以,最后的结论。 Kotlin 没有开箱即用的原始类型。您将所有对象都视为对象。转换为原语是在比代码更低的级别上完成的。这种设计是为了保持与JVM的兼容性。
我做了一点深入研究并在媒体上发表了它。有意者:https://medium.com/@przemek.materna/kotlin-is-not-primitive-primitives-in-kotlin-and-java-f35713fda5cd
【讨论】:
reflectClassUtil.kt:32 例如此处:github.com/JetBrains/kotlin/blob/…
简短回答 - 是,取决于声明。
val myAge: Int = 18 // this is primitive
val myAge2: Int? = 18 // this is not
有一个内容丰富的视频 https://www.youtube.com/watch?v=Ta5wBJsC39s
【讨论】:
Int 是原始类型,那么为什么我们可以使用myAge.minus(10)? 这样的方法
public operator fun minus(other: Int): Int),意思是它和myAge - 10一样
在 Java 平台上,数字在物理上存储为 JVM 基本类型,除非我们需要可空的数字引用(例如 Int?)或涉及泛型。在后一种情况下,数字被框起来。
请注意,数字的装箱不一定能保持身份:
val a: Int = 10000
println(a === a) // Prints 'true'
val boxedA: Int? = a
val anotherBoxedA: Int? = a
println(boxedA === anotherBoxedA) // !!!Prints 'false'!!!
注意“===”用于比较参考......
另一方面,它保持平等:
val a: Int = 10000
println(a == a) // Prints 'true'
val boxedA: Int? = a
val anotherBoxedA: Int? = a
println(boxedA == anotherBoxedA) // Prints 'true'
【讨论】: