loading...

Pocket Guide on Kotlin

tbhaxor profile image Gurkirat Singh ・14 min read

Kotlin is a cross-platform, statically typed, general-purpose programming language with type inference

Every kotlin program starts from the main function, as demonstrated below

fun main(args: Array<String>) {
        // your code
}

NOTE : Since this is an interactive notebook generated from jupyter notebook, the main function part will be skipped.

Basics

Printing on the console

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/println.html#println

println("Hello World")
Hello World

Variables

Variables are used to store the value of specific type, the types supported by kotlin there in documentation

Documentation: https://kotlinlang.org/docs/reference/basic-types.html, https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/

var age: Int = 22
age
22

Changing value of the variable

age = 30
age
30

Kotlin support three types of variables

  • var → mutable variables, values of such variables can be changed during the program set
  • val → immutable variables, values of such variables can be initialized only single time
val i = 10
i
10
i = 20
Val cannot be reassigned
i
10

Using underscored number literal

val oneMillion = 1_000_000
oneMillion
1000000

Floating Numbers

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-float/

// the f means to use floating number, otherwise it will use the double and then type cast it into float
val price: Float = 44.77f;
price
44.77

Strings

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/

var name: String = "Gurkirat Singh"
name
Gurkirat Singh

Length of string

name.length
14

Getting one character

name[0] == name.get(0)
true

Comparing two strings

val name2 = "Gurkirat Singh"
name2
Gurkirat Singh
name == name2
true
name.compareTo(name2)
0

Here 0 means both strings are identical

Concatenating two strings

name.plus(name2)
Gurkirat SinghGurkirat Singh
name + name2
Gurkirat SinghGurkirat Singh

Arrays

Collection of similar type of data

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/

var numbers = arrayOf(1, 2, 3, 4, 5, 6)
numbers
[Ljava.lang.Integer;@728561a2

To get the value, use the index number

numbers[0]
1
numbers[4]
5

Getting the length of array

numbers.size
6

Empty array of specific type

val emptyArray = arrayOf<Int>()
emptyArray
[Ljava.lang.Integer;@303524fb
emptyArray.size
0

Type Conversion

val num1 = 1
val num2 = "2"

Both look identical (numbers), but the type of both the variables are not same

num1 + num2
None of the following functions can be called with the arguments supplied: 
public final operator fun plus(other: Byte): Int defined in kotlin.Int
public final operator fun plus(other: Double): Double defined in kotlin.Int
public final operator fun plus(other: Float): Float defined in kotlin.Int
public final operator fun plus(other: Int): Int defined in kotlin.Int
public final operator fun plus(other: Long): Long defined in kotlin.Int
public final operator fun plus(other: Short): Int defined in kotlin.Int
num1 + num2.toInt()
3

Operators and Operands

Documentation: https://kotlinlang.org/docs/reference/keyword-reference.html#operators-and-special-symbols

Arithmatic Operators

val num1 = 20
val num2 = 30

Addition

num1 + num2
50

Subtraction

num2 - num1
10

Multiplication

num1 * num2
600

Division

num2 / num1
1
num2.toFloat() / num1.toFloat()
1.5

Finding remainder

num2 % num1
10

Relation Operators

val num1 = 20
val num2 = 30

Equality

num1 == num2
false

NOTE: Don't misunderstand == with =. First one is called equal to operator and another is called assignment operator (evaluates and assigns the RHS value to LHS)

Less than

num1 < num2
true
num2 < num2
false

Greater than

num1 > num2
false

Greater than equal to

num1 >= num1
true

Less than equal to

num1 <= num1
true

Not equal to

num1 != num2
true

Unary Operators

var num1 = 10
num1
10

Post increment

num1++
num1
11

Pre increment

++num1
num1
12

Post decrement

num1--
num1
11

Pre decrement

--num1
num1
10

Bitwise Operator

var num1 = 10
var num2 = 20
num1.toString(2)
1010
num2.toString(2)
10100

Shift left by one bit

num1 = num1.shl(1)
num1.toString(2)
10100

Shift right by one bit

num1 = num1.shr(1)
num1.toString(2)
1010

Bitwise or

num1.or(num2).toString(2)
11110

Bitwise and

num1.and(num2).toString(2)
0

Bitwise xor

num1.xor(num2).toString(2)
11110
num1.and(num1).toString(2)
1010

Bitwise inverse

num1.inv().toString(2)
-1011
num1.inv()
-11

Logical Operators

AND operator

true && true
true
false && true
false
true && false
false
false && false
false

OR operator

true || true
true
true || false
true
false || true
true
false || false
false

NOT Operator

true && !false
true

Conditionals

IF - ELSE

Documentation: https://kotlinlang.org/docs/reference/control-flow.html#if-expression

var age = 18
var age2 = 14
if (age >= 18) {
    println("You are an adult")
}
else {
    println("Hey kiddo")
}
You are an adult
if (age2 >= 18) {
    println("You are an adult")
}
else {
    println("Hey kiddo")
}
Hey kiddo

WHEN

Documentation: https://kotlinlang.org/docs/reference/control-flow.html#when-expression

var num = 4
when(num) {
    1 -> println("Sunday")
    2 -> println("Monday")
    3 -> println("Tuesday")
    4 -> println("Wednesday")
    5 -> println("Thursday")
    6 -> println("Friday")
    7 -> println("Saturday")
    else -> println("Number should be in between 1 and 7") // will be executed if no value matches
}
Wednesday

To run same lines of code for multiple choices

when(variable) {
    1, 2, 3 -> println("your input is either 1 or 2 or 2")
    else -> {
        // running multiple lines
        println("This is not a joke")
        println("Enter number 1, 2, 3 only")
    }
}

To run same lines of code for a range of numbers

when(variable) {
    in 1..3 -> println("your input is either 1 or 2 or 2")
    else -> {
        // running multiple lines
        println("This is not a joke")
        println("Enter number 1, 2, 3 only")
    }
}

FOR Loop

Documentation: https://kotlinlang.org/docs/reference/control-flow.html#for-loops

var numbers = arrayOf<Int>(1, 2, 3, 4, 5, 6)

Simple demonstration

for (number in numbers){
    println(number)
}
1
2
3
4
5
6

With indices

for ((idx, number) in numbers.withIndex()) {
    println("number '$number' is at index '$idx' in the array")
}
number '1' is at index '0' in the array
number '2' is at index '1' in the array
number '3' is at index '2' in the array
number '4' is at index '3' in the array
number '5' is at index '4' in the array
number '6' is at index '5' in the array

Range based loop

for (i in 1..5)
{
    println(i)
}
1
2
3
4
5

Range based loop with step

for (i in 1..5 step 2)
{
    println(i)
}
1
3
5

Reverse loop with step

for (i in 6 downTo 0 step 2)
{
    println(i)
}
6
4
2
0

WHILE and DO-WHILE Loop

Documentation: https://kotlinlang.org/docs/reference/control-flow.html#while-loops

var num = 5

While Loop

while (num > 0)
{
    println(num--)
}
5
4
3
2
1

Do While Loop

do {
    println(num--)
} while (num > 0)
0

Difference between while and do-while loop: https://stackoverflow.com/a/3347010/10362396

Jump statements like break and continue are used to end and skip the following loop body.

Documentation: https://kotlinlang.org/docs/reference/returns.html#returns-and-jumps

Functions

A function is a unit of code that performs a special task. In programming, function is used to break the code into smaller modules which makes the program more manageable.

Declaring a function

Documentation: https://kotlinlang.org/docs/reference/functions.html#function-declarations

Simple function

fun greet() {
    println("Hello User")
}
greet()
Hello User

Receiving parameters

fun sum(x: Int, y: Int) {
    println(x+y)
}
sum(10, 11)
21

Calling function with wrong type

sum(10.4f, 11)
The floating-point literal does not conform to the expected type Int

Return statements

fun say_hello(name: String) : String {
    return "Hello, " + name
}
say_hello("John")
Hello, John
say_hello("Dale")
Hello, Dale

Recursion

A function which calls itself is called as recursive function and this process of repetition is called recursion.

fun factorial(num: Int): Int {
    // base condition
    if (num <= 1) {
        return 1
    }

    // function calling itself
    return num * factorial(num - 1)
}
factorial(5)
120

Default arguments

Documentation: https://kotlinlang.org/docs/reference/functions.html#default-arguments

fun say_hello_default(name: String = "Guest"): String {
    return "Hello, " + name
}
say_hello_default()
Hello, Guest
say_hello_default("Sheldon")
Hello, Sheldon

Named arguments

Documentation: https://kotlinlang.org/docs/reference/functions.html#named-arguments

fun say_hello_default_name(name: String = "Guest", robot: String): String {
    return "Hello, " + name + ". I am " + robot
}
say_hello_default_name(robot = "Alex")
Hello, Guest. I am Alex
say_hello_default_name("Dale", robot = "Alice")
Hello, Dale. I am Alice

Lambda Functions

The lambda functions are the functions that are not declared, but passed immediately as an expression

Documentation: https://kotlinlang.org/docs/reference/lambdas.html#lambda-expressions-and-anonymous-functions

fun multiply(x: Int, y: Int, callback: (Int) -> Unit)
{
    callback(x * y)
}
var cb: (Int) -> Unit = {p -> println("The product is $p") } // lambda function
multiply(10, 20, cb)
The product is 200

Higher order functions

Function that accept functions as the parameters and can return function as a value. This is basically implemented by the lambda functions

Documentation: https://kotlinlang.org/docs/reference/lambdas.html#higher-order-functions

Accepting function

var fn:(Int, Int) -> Int = {x, y-> x + y};

fun adder(num1: Int, num2: Int, callback: (Int, Int) -> Int): Int {
    return callback(num1, num2)
}
adder(10, 20, fn)
30

Inline function

Documentation: https://kotlinlang.org/docs/reference/inline-functions.html

inline fun inlineFunc(myFunc: () -> Unit): Unit {
    myFunc()
}
inlineFunc({println("Printing inside inline function")})
Printing inside inline function

Exception Handling

Try Catch

Documentation: https://kotlinlang.org/docs/tutorials/kotlin-for-py/exceptions.html#throwing-and-catching

var num1 = 100
var num2 = 0
try {
    num1 / num2
} catch (e: ArithmeticException) {
    println("Attempeted divide by zero")
}
Attempeted divide by zero

Try-Catch as an Expression

fun toInt(v: String): Int {
    return try {
        Integer.parseInt(v)
    } catch (e: NumberFormatException) {
        0
    }
}
toInt("10")
10
toInt("hello")
0

The finally blocks runs regardless of the successful or failed execution

try {
    // some code
} catch (e: Exception) {
    //some execption
} finally {
    // this will run after try or catch block execution
}

Throwing Exception

fun divMe(x: Int, y: Int): Int {
    if (y < 0){
        throw IllegalArgumentException("y should be strictly greater than 0")
    }

    return x / y
}
try {
    divMe(10, 0)
} catch (e: ArithmeticException) {
    print("Aborted: ")
    println(e)
} catch (e: IllegalArgumentException) {
    print("Aborted: ")
    println(e)
}
Aborted: java.lang.ArithmeticException: / by zero
try {
    divMe(10, -20)
} catch (e: ArithmeticException) {
    print("Aborted: ")
    println(e)
} catch (e: IllegalArgumentException) {
    print("Aborted: ")
    println(e)
}
Aborted: java.lang.IllegalArgumentException: y should be strictly greater than 0

NULL Safety

Documentation: https://kotlinlang.org/docs/reference/null-safety.html#nullable-types-and-non-null-types

var myVar: Int = 7
myVar
7
myVar = 10
myVar
10
myVar = null
Null can not be a value of a non-null type Int

Use Int? while defining the variable, so as to accept null values

var myVar: Int? = 7
myVar
7
myVar = 10
myVar
10
myVar = null
myVar

Safe Casting

Documentation: https://kotlinlang.org/docs/reference/null-safety.html#safe-casts

var num: Int? = 19
num = null
var num2: Int? = num as? Int
num2
num = 10
var num2: Int? = num as? Int
num2
10

Elvis Operator

Documentation: https://kotlinlang.org/docs/reference/null-safety.html#elvis-operator

val s1: String? = null;
val s2: String? = "Hello World";
var l1: Int = if (s1 != null) s1.length else -1
l1
-1
var l2: Int = if (s2 != null) s2.length else -1
l2
11

Simplifying the above with elvis operator

var l1: Int = s1 ?.length ?: -1
l1
-1
var l2: Int = s2 ?.length ?: -1
l2
11

Collections

Lists

Documentation:https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/

Immutable List: listOf

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/list-of.html

var numbers = listOf(1, 2, "3", 4, 5)

for (number: Any in numbers) {
    println(number)
}
1
2
3
4
5

List with type specification

var numbers = listOf<Int>(1, 2, 3, 4, 5)

for (number: Int in numbers) {
    println(number)
}
1
2
3
4
5

Mutable List: mutableListOf

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/mutable-list-of.html

var list = mutableListOf<Int>()
list.isEmpty()
true
list.size
0

Adding an element

list.add(10)
list.size
1
list[0]
10

Adding multiple elements

list.addAll(listOf(20, 30, 40))
list.size
4

Arrays: arrayListOf

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/array-list-of.html

var array = arrayListOf<Int>(10, 20, 30)
for(element in array) {
    println(element)
}
10
20
30
array.add(100)
for(element in array) {
    println(element)
}
10
20
30
100
array[2] = -100
for(element in array) {
    println(element)
}
10
20
-100
100

Inserting at specific location

array.add(1, -200)
for(element in array) {
    println(element)
}
10
-200
20
-100
100

Map

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-map/

Immutable Map: mapOf

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map-of.html

var map: Map<String, Int> = mapOf<String, Int>("ONE" to 1, "TWO" to 2)
map["ONE"]
1
map.keys
[ONE, TWO]
for (key in map.keys) {
    println(map[key])
}
1
2

Mutable Map: mutableMapOf

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/mutable-map-of.html

var map = mutableMapOf<Int, String>(10 to "TEN", 20 to "TWENTY")
map
{10=TEN, 20=TWENTY}
map[10]
TEN
map[30] = "THIRTY"
for(key in map.keys) {
    println(map[key])
}
TEN
TWENTY
THIRTY

HashMap

It is an implementation of the interface MutableMap

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-hash-map/

var hmap: HashMap<Int, String> = HashMap<Int, String>();
// HashMap<Int, String>(initalCapacity) use this to reserve the memory while initilization
// you can add more keys later on
hmap.put(1, "Spiderman")
hmap.put(2, "Ironman")
hmap.put(3, "Black Widow")
hmap.put(4, "Ant Man")
hmap[1]
Spiderman
hmap.get(2)
Ironman
hmap.keys
[1, 2, 3, 4]
for(key in hmap.keys) {
    println(hmap[key])
}
Spiderman
Ironman
Black Widow
Ant Man

hashMapOf

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/hash-map-of.html

var hmap = hashMapOf<Int, Int>(1 to 10, 2 to 20)
hmap.size
2
for(key in hmap.keys) {
    println(hmap[key])
}
10
20

Sets

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-set/#kotlin.collections.Set

Immutable Set: setOf

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/set-of.html

var set1 = setOf(1, 2, 3, 4, 4, 2, 3)
set1
[1, 2, 3, 4]
for(element in set1){
    println(element)
}
1
2
3
4
set1.contains(1)
true
set1.contains(10)
false

Mutable Set: mutableSetOf

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/mutable-set-of.html

val set2 = mutableSetOf<Int>()
set2.add(1)
set2.add(1)
set2.add(2)
set2.add(2)
set2.add(3)
true
set2
[1, 2, 3]
for(element in set2) {
    println(element)
}
1
2
3
set2.remove(1)
true
set2.remove(5)
false
for(element in set2) {
    println(element)
}
2
3

Hashset: hashSetOf

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/hash-set-of.html

val set3 = hashSetOf<Int>(1, 2, 3, 5)
set3
[1, 2, 3, 5]
for(el in set3) {
    println(el)
}
1
2
3
5

Classes

Basic Example

Documentation: https://kotlinlang.org/docs/tutorials/kotlin-for-py/classes.html#declaration-and-instantiation

class Vehicle {
    // class properties
    var speed: Int = 0
    var wheels: Int = 0
    var model: String = ""

    // class methods
    fun SetModel(m: String) {
        model = m
    }

    fun SetSpeed(s: Int) {
        speed = s
    }
}
var vehicle1 = Vehicle()
vehicle1
Line_166_jupyter$Vehicle@6400abd0
vehicle1.model
vehicle1.SetModel("BMW")
vehicle1.model
BMW
vehicle1.wheels
0
vehicle1.wheels = 4
vehicle1.wheels
4

Nested Classes

Documentation: https://kotlinlang.org/docs/reference/nested-classes.html#nested-and-inner-classes

class C1 {

    fun ShowMe() {
        println("From Outer Class C1")
    }   

    class C2 {
        fun ShowMe() {
            println("From Inner Class C2")
        }
    }
}
var c1 = C1()
c1.ShowMe()
From Outer Class C1
var c2 = C1.C2()
c2.ShowMe()
From Inner Class C2

Constructor

Documentation: https://kotlinlang.org/docs/reference/classes.html#constructors

Primary Constructor: Default

class Car {
    var wheels: Int
    var model: String

    init {
        println("Starting the car")
        wheels = 4
        model = "BMW"
    }

    fun Stop() {
        println("Stopping the car")
    }
}
var car = Car()
Starting the car
car.wheels
4
car.Stop()
Stopping the car

Primary Constructor: Parameterized

class Vehicle(_wheels: Int, _model: String) {
    var wheels: Int
    var model: String

    init {
        println("starting")
        wheels = _wheels
        model = _model
    }

    fun Stop() {
        println("stopping")
    }
}
var v1 = Vehicle(4, "BMW")
var v2 = Vehicle(2, "Kawasaki Ninka")
starting
starting
v1.wheels
4
v2.wheels
2
v1.Stop()
v2.Stop()
stopping
stopping

NOTE: Keyword init can be used multiple times

class InitOrderDemo(name: String) {
    val firstProperty = "First property: $name"

    init {
        println("First initializer block that prints ${name}")
    }

    val secondProperty = "Second property: ${name.length}"

    init {
        println("Second initializer block that prints ${name.length}")
    }
}

InitOrderDemo("hello")
First initializer block that prints hello
Second initializer block that prints 5





Line_186_jupyter$InitOrderDemo@7435796a

Secondary Constructor

Documentation: https://kotlinlang.org/docs/reference/classes.html#secondary-constructors

class Person {
    var name: String;
    var age: Int;

    constructor(name: String, age: Int) {
        this.name = name;
        this.age = age;
    }

    fun whoami() {
        println("I am $name and I am $age years old.")
    }
}
var p1 = Person("John", 23)
var p2 = Person("Sarrah", 44)
p1.whoami()
I am John and I am 23 years old.
p2.whoami()
I am Sarrah and I am 44 years old.

Visibility Modifiers

Documentation: https://kotlinlang.org/docs/reference/visibility-modifiers.html#classes-and-interfaces

class Person {
    private var name: String;

    constructor(name: String) {
        this.name = name
    }

    fun whoami(): String {
        return "I am $name"
    }
}
var p1 = Person("Joel")
p1.whoami()
I am Joel
p1.name
Cannot access 'name': it is private in 'Person'

Inheritance

Documentation: https://kotlinlang.org/docs/reference/classes.html#inheritance

open class Vehicle {

    public var wheels: Int = 0;
    public var model: String = "";

    fun Start() {
        println("Starting")
    }

    fun Stop() {
        println("Stop")
    }
}
class Car: Vehicle {
    constructor(model: String, wheels: Int) {
        this.wheels = wheels
        this.model = model
    }
}
var car = Car("BMW", 4)
car.Start()
Starting
car.model
BMW
car.Stop()
Stop

Method Overriding

Documentation: https://kotlinlang.org/docs/reference/classes.html#overriding-methods

open class Vehicle {

    public var wheels: Int

    constructor(wheels: Int) {
        this.wheels = wheels
    }

    open fun Start() {
        println("Starting the vehicle")
    }

    open fun Stop() {
        println("Stopping the vehicle")
    }
}
class Car(_wheels: Int): Vehicle(_wheels) {

    init {
        this.wheels = _wheels;
    }

    override fun Start() {
        println("Starting the car")
    }

    override fun Stop() {
        println("Stopping the car")
    }
}
var car = Car(4)
car.wheels
4
car.Start()
Starting the car
car.Stop()
Stopping the car

Property Overriding

Documentation: https://kotlinlang.org/docs/reference/classes.html#overriding-properties

open class Shape {
    open protected val ndims: Int = 0

    fun getDims(): Int {
        return this.ndims
    }
}
class Rectangle : Shape() {
    override protected val ndims = 4
}
var rect = Rectangle()
rect.getDims()
4
rect.ndims
Cannot access 'ndims': it is protected in 'Rectangle'

Abstract Class

Documentation: https://kotlinlang.org/docs/reference/classes.html#abstract-classes

abstract class Shape(_n: Int) {
    protected var ndims: Int

    init {
        this.ndims = _n
    }

    public fun getDims(): Int {
        return this.ndims
    }
}
class Rect: Shape(4) {
}
var rect = Rect()
rect.getDims()
4

Accessing super class from base class

open class Person {
    open fun sayHello() {
        println("Hello from super class")
    }
}

class Student: Person {
    constructor() : super() {}
    override fun sayHello() {
        println("Hello from sub class")
        super.sayHello()
    }
}
var student = Student()
student.sayHello()
Hello from sub class
Hello from super class

Data Class

Documentation: https://kotlinlang.org/docs/reference/data-classes.html#data-classes

data class Student(var name: String, var age: Int);
var student: Student = Student("John", 22)
student
Student(name=John, age=22)
student.name
John
student.age
22

Sealed Class

Documentation: https://kotlinlang.org/docs/reference/whatsnew11.html#sealed-and-data-classes

sealed class Shape {
    data class Circle (var radius: Int)
    data class Rectangle (var width: Int, var height: Int)
    data class Square (var side: Int)
}
var c = Shape.Circle(20)
c
Circle(radius=20)
var r = Shape.Rectangle(20, 10)
r
Rectangle(width=20, height=10)
var s = Shape.Square(20)
s
Square(side=20)

Extension Function

Documentation: https://kotlinlang.org/docs/reference/extensions.html#extension-functions

class Person {}

fun Person.sayHello(): String {
    return "Hello"
}
var p = Person()
p.sayHello()
Hello

Generic Functions

Documentation: https://kotlinlang.org/docs/reference/functions.html#generic-functions

fun <T> Return(x: T): T {
    return x
}
Return<Int>(5)
5
Return<String>("Hello")
Hello

Misc

Regex

Documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-regex/

var str = "Hello world at 10:22!!"
var pattern = Regex("[0-9]{2}:[0-9]{2}")
pattern
[0-9]{2}:[0-9]{2}
pattern.containsMatchIn(str)
true
pattern.findAll(str)
kotlin.sequences.GeneratorSequence@53db2a04

Call Java from Kotlin

Documentation: https://kotlinlang.org/docs/reference/java-interop.html

System.out.println("Hello")
Hello

Like Java, it also supports imports

Call Kotlin from Java

Documentation: https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html

filename: main.kt

fun main() {
}

fun Print() {
    println("Calling from kotlin file")
}

filename: app.java

public class app
{
    public static void main() {
        MainKt.Print()
    }
}

Connect with me

Discussion

markdown guide