How Kotlin handles variables

All programming languages come with data types which are used to store different values, i-e integers, float etc. Programming languages such as C, C++, Java provide primitive data types such as byte, short, int, long, float, double, char, and boolean. These data types have very limited functionalities and cannot be assigned with null value. Java uses wrapper classes to wrap each primitive data type in an object, for example java .lang.Integer is the wrapper class for int and  java.lang.Double for double data types. 

int age = 20  // Primitive data type 
Integer weight = 60 // Wrapper class Integer
Example 1: Data type declaration instances in Java

In Java as in C++ as well, primitive data type’s name starts with a small letter and each wrapper class’ name starts with a capital letter. This differentiates between the primitive types and wrapper classes. In Kotlin each data type’s name starts with a capital letter indicating that in Kotlin everything is already wrapped in an object.

var age : Int = 20 
var weight = Double = 60.0 
var ch = : Character = ‘a’ 
Example 2: Data type declaration instances in Kotlin


Boxing or Auto-boxing 

Boxing or Auto-boxing is an automatic conversion which compiler performs between primitive data type and its related wrapper class. Primitive data type always initializes on Stack and Object is always initializes on Heap.

As an example, lets explore java data types. 

 int i = 5;

A variable i of type int is assigned a value 5. Variable i is a primitive data type so it is initialized on Stack and value is directly stored in variable.

Now take Wrapper class object Integer and assign primitive variable i to it

int i = 5; // int primitive data type  
Integer j = i; // Integer wrapper class object

This Integer is not a primitive data type but it is an object which is created on Heap. On Stack, variable j is an object which contains reference to the Object having value 5. When value of int i is assigned to value of Integer j the java compiler calls a valueOf() method.

Integer j = Integer.valueOf(i);

The Integer.valueOf(i) passes a value i as an argument to the valueOf() method and returns a boxed object. This process is called auto-boxing and it happens behind the scene. 
autboxing

 

 

 

 

 

 

 

In Kotlin everything is an Object and these are the known facts that :

  • Objects are slower than primitive data types.
  • Continuous auto-boxing can cause serious performance issues
  • Objects require more space in memory.

Kotlin handles this problem in a very neat manner. In Kotlin every non-nullable variable is mapped back to JVM as primitive data type for performance improvement and variables are boxed when the type is nullable, for example int?, float?. 

Let’s create a small example of Kotlin program with two integer variables.   Take two integer types of variables, first a non-nullable variable i and assign a value 5 and take another nullable variable j and assign variable i to it.

fun main (args: Array<String>)
{ 
   var i : Int = 5 // non-nullable 
   var j : Int? = i // nullable 
   println("$i , $j") 
} 
Variable declaration in Kotlin

Compile and Run this program and it will display 5,5 in the output window.

Let’s go behind the scene and look at bytecode, it will be more interesting. In IntelligeIdea menu items, press Tools -> Kotlin -> Show Kotlin ByteCode. In the newly opened window press the Decompile button. This will show the decompiled code of your Kotlin file. 

import kotlin.Metadata; 
import kotlin.jvm.internal.Intrinsics; 
import org.jetbrains.annotations.NotNull; 
 @Metadata( 
  mv = {1, 1, 6}, 
  bv = {1, 0, 1}, 
  k = 2, 
 d1 ={"\u0014\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\u0011\n"}, 
  d2 = {"main", "", "args", "", "", "([Ljava/lang/String;)V", "production sources for module Variables"} 
) 

// It looks interesting
public final class ByteCode_Kt { 
public static final void main(@NotNull String[] args) { 
     Intrinsics.checkParameterIsNotNull(args, "args"); 
     int i = 5; 
     Integer j = Integer.valueOf(i); 
     String var3 = i + " , " + j; 
     System.out.println(var3); 
  } 
} 
Kotlin ByteCode

For the simplicity you can ignore the first part of the file and look at the ByteCode_Kt class.
In public static final void main function, you can see two variables int i and Integer j.

Non-nullable variable i from Kotlin file var i : Int = 5 

is converted into primitive data type int  i = 5;  

and for nullable variable j var j : Int? = i 

compiler performed auto-boxing by calling Integer j = Integer.valueOf(i); and created wrapper class object Integer j. 

Leave a Reply

Your email address will not be published. Required fields are marked *