Torben G
Torben G

Reputation: 800

Is everything in Kotlin an object?

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:”

enter image description here

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).

enter image description here

Upvotes: 6

Views: 1605

Answers (5)

Torben G
Torben G

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

Pawel
Pawel

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

Hayk Melkonyan
Hayk Melkonyan

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

Sam
Sam

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

Ben P.
Ben P.

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

Related Questions