Reputation: 800
I have read this in several places. But don’t really understand the meaning. You can read this short documentation on kotlinlang:
“In Kotlin, everything is an object in the sense that we can call member functions and properties on any variable. Some of the types can have a special internal representation - for example, numbers, characters and booleans can be represented as primitive values at runtime - but to the user they look like ordinary classes.“
What is a special internal representation? What does it mean, can be represented as primitive values at runtime?
Is it only the possibility to call conversion functions like toInt()? And the Extension Functions?
Elsewhere I have read the following statement:
“For primitive data types from java, kotlin has specialized array types like ByteArray”. Does it mean that I can only create an Array in Kotlin with functions like intArrayOf(1, 2, 3) or IntArray(5)?
Another statement that I find confusing from the book Head First Kotlin:
“When you declare a variable using code like:
var x = 5
the value you’re assigning to the variable is used to create a new object”.
“When an object is assigned to a variable, the object itself doesn’t go into the variable. A reference to the object goes into the variable instead:”
But the following code snippet does the same which I get with Java.
fun main() {
var x = 5
var y = x
x = 15
println("Hello, world!!! $y")
}
The output is 5. But I think it should be 15, because it is an object and a reference to it. Maybe I am a little bit stupid to understand Kotlin. That is my understanding of variables and references and the administration of memory in programming languages like Java (or Kotlin).
Upvotes: 6
Views: 1605
Reputation: 800
But what is the difference to Java here? I think Java does the same with the primitive Variables like x and y. When we assign y to x in Java and we will change x after that, y has still the old value. Because it is a copy and not a reference.
So the only difference between Kotlin and Java is I can call functions on primitive datatypes and give them properties like with objects?
Upvotes: 0
Reputation: 17288
All primitives are represented as their respective JVM types unless you specifically access them as or force them to be an object.
For sake of showing what I mean, let's use System.identityHashCode(Object)
function. Also using Int value > 127 to prevent object caching.
Case 1: primitives
fun main(){
var x = 128
var y = x
println("x: $x, ${System.identityHashCode(x)}")
println("x: $x, ${System.identityHashCode(x)}")
println("y: $y, ${System.identityHashCode(y)}")
x = 200
println("x: $x, ${System.identityHashCode(x)}")
}
/// output
x: 128, 746292446
x: 128, 1072591677
y: 128, 1523554304
x: 200, 1175962212
What we get here: x
is a primitive int
and is stored as such. when y = x
, that means y
is assigned same primitive value as x
. There are no Objects
allocated yet.
When we use System.identityHashCode(Object)
we get different hashes, even when we print x
twice in a row. That's because Int
wrapper objects are created on the spot where Object
representation is needed.
Case 2: object representation
fun main() {
var x : Any = 128 // this is the only line that changed
var y = x
println("x: $x, ${System.identityHashCode(x)}")
println("x: $x, ${System.identityHashCode(x)}")
println("y: $y, ${System.identityHashCode(y)}")
x = 200
println("x: $x, ${System.identityHashCode(x)}")
}
/// output
x: 128, 746292446
x: 128, 746292446
y: 128, 746292446
x: 200, 1072591677
Here we force x
to be represented as an Object
by declaring field type as non-primitive. When we assign x
to y
that object reference is copied and we can see that by identityHashCode
returning same hash in all prints.
Upvotes: 0
Reputation: 2150
lets think they are objects and not primitives
var x = 10
assign reference of 10
to x
var y = x
assign reference of x
to y
x = 5
assign reference of 5
to x
so reference of x
changed but y
keeps reference of 10
in another way
if you can do something like this
x.changeSomeOfMyProperties()
then changes will be applied to x
and y
but, because they are primitives you cannot do that kind of thing.
primitives are classes in kotlin, so it is difficult to understand how they work,
you can check Primitives.kt
Upvotes: 3
Reputation: 96
To answer your first question, Everything to you the developer is an object or behaves like an object but at runtime for efficiency sake compiles down to primitive type.
for the last one :
x = 5 //and let's say int 5 memory location is A235
so
y = x is synonymous to y = A235
then
x = 15
but y is still pointing to memory location A235 value
Upvotes: 1
Reputation: 54254
The output is 5. But I think it should be 15
We can walk through what's going on in this sample.
var x = 5
Create an Int
object holding the value 5. Create a variable x
, and make x
point to this new Int
object.
var y = x
Create a variable y
, and make y
point to whatever x
is currently pointing to (the Int
object).
(Note that it is not the case that x
and y
are two names for the same pointer. Rather, x
and y
are totally distinct but both happen to point at the same thing.)
x = 15
Create an Int
object holding the value 5. Make the x
variable point to this new Int
object.
(This is the key point in the flow. When we assign x = 15
, we are changing where x
points, but we aren't affecting y
at all. y
still points to the same thing it used to (the Int
holding 5)).
println("Hello, world!!! $y")
Display something to the user. To determine what to substitue for $y
, follow the pointer and see what it's pointing to. y
was only ever assigned a value one time, so it still points to the first thing it ever pointed to (the Int
holding 5).
Upvotes: 2