The first step in our Kotlin adventure is to write a minimal program in this language. Yes, it’s the famous "Hello, World!" program. This is what it looks like in Kotlin:
fun main() {
println("Hello, World")
}
This is minimal, isn't it? We need no classes (like we do in Java), no objects (like console in JavaScript), and no conditions (like in Python when we start code in the IDE). We need the main function and the println function call with some text[^02_0].
This is the most popular (but not the only) variant of the "main" function. If we need arguments, we might include a parameter of type Array<String>:
fun main(args: Array<String>) {
println("Hello, World")
}
There are also other forms of the main function:
fun main(vararg args: String) {
println("Hello, World")
}
class Test {
companion object {
@JvmStatic
fun main(args: Array<String>) {
println("Hello, World")
}
}
}
suspend fun main() {
println("Hello, World")
}
Although these are all valid, let's concentrate on the simple main function as we will find it most useful. I will use it in nearly every example in this book. Such examples are usually completely executable if you just copy-paste them into IntelliJ or the Online Kotlin Playground[^02_2].
fun main() {
println("Hello, World")
}
All you need to do to start the main function in IntelliJ is click the green triangle which appears on the left side of the main function; this is called the "gutter icon", also known as the "Run" button.
Live templates
If you decide to test or practice the material from this book[^02_3], you will likely be writing the main function quite often. Here come live templates to help us. This is an IntelliJ feature that suggests using a template when you start typing its name in a valid context. So, if you start typing "main" or "maina" (for main with arguments) in a Kotlin file, you will be shown a suggestion that offers the whole main function.
In most my workshops, I’ve used this template hundreds of times. Whenever I want to show something new with live coding, I open a "Playground" file, select all its content (Ctrl/command + A), type "main", confirm the live template with Enter, and I have a perfect space for showing how Kotlin works.
I also recommend you test this now. Open any Kotlin project (it is best if you have a dedicated project for playing with Kotlin), create a new file (you can name it "Test" or "Playground"), and create the main function with the live template “maina”. Use the print function with some text, and run the code with the Run button.
What is under the hood on JVM?
The most important target for Kotlin is JVM (Java Virtual Machine). On JVM, every element needs to be in a class. So, you might be wondering how it is possible that our main function can be started there if it is not in a class. Let's figure it out. On the way, we will learn to find out what our Kotlin code would look like if it were written in Java. This is Java developers’ most powerful tool for learning how Kotlin works.
Let's start by opening or starting a Kotlin project in IntelliJ or Android Studio. Make a new Kotlin file called "Playground". Inside this, use the live template "maina" to create the main function with arguments and add println("Hello, World") inside.
fun main(args: Array<String>) {
println("Hello, World")
}
Now, select from the tabs Tools > Kotlin > Show Kotlin Bytecode.
On the right side, a new tool should open. "Show Kotlin Bytecode" shows the JVM bytecode generated from this file.
This is a great place for everyone who likes reading JVM bytecode. Since not everyone is Jake Wharton, most of us might find the "Decompile" button useful. What it does is quite funny. We’ve just compiled our Kotlin code into JVM bytecode, and this button decompiles this bytecode into Java. As a result, we can see what our code would look like if it were written in Java[^02_5].
This code reveals that our main function on JVM becomes a static function inside a class named PlaygroundKt. Where does this name come from? Try to guess. Yes, this is, by default, the file's name with the "Kt" suffix. The same happens to all other functions and properties defined outside of classes on JVM.
If we wanted to call our main function from Java code, we can call PlaygroundKt.main({}).
The name of PlaygroundKt can be changed by adding the @file:JvmName("NewName") annotation at the top of the file[^02_6]. However, this does not change how elements defined in this file are used in Kotlin. It only influences how we will use such functions from Java. For example, to call our main function from Java now, we would need to call NewName.main({}).
If you have experience with Java, remember this tool as it can help you to understand:
How Kotlin code works on a low level.
How a certain Kotlin feature works under the hood.
How to use a Kotlin element in Java.
There are proposals to make a similar tool to show JavaScript generated from Kotlin code when our target is Kotlin/JS. However, at the time of writing this book, the best you can do is to open the generated files yourself.
Packages and importing
When our project has more than one file, we need to use packages to organize them. Packages are a way to group files together and avoid name conflicts.
A file can specify package at the top of the file using the package keyword.
package com.marcinmoskala.domain.model
class User(val name: String)
If we don't specify a package, the file is in the default package. In real projects, it is recommended that package path should be the same as the directory path in our source files. Package can also include company domain in reverse order, like com.marcinmoskala. We name package using lowercase characters only.
If we want to use a function or class from another package, we need to import it. Imports are declared after the package declaration and before file elements'[^02_7] declaration. They first specify the package name, then the name of the element. We can also use the * character to import all elements from a package.
package com.marcinmoskala.domain
import com.marcinmoskala.domain.model.User
// or
import com.marcinmoskala.domain.model.*
fun useUser() {
val user = User("Marcin")
// ...
}
Essential elements from Kotlin and Java strandard libraries are imported by default. For example, we can use println function without importing it.
Kotlin's developers rarely think about imports, because IntelliJ manage them automatically. When you use an element using IntelliJ suggestion, it will automatically add an import for you. If you use an element that is not imported, IntelliJ will suggest importing it. If you want to remove unused imports, you can use the "Remove unused imports" action (Ctrl/command + Alt + O). That is also why I decided to not show imports in most of the examples in this book.
Summary
We've learned about using main functions and creating them easily with live templates. We’ve also learned how to find out what our Kotlin code would look like if it were written in Java. For me, it seems like we have quite a nice toolbox for starting our adventure. So, without further ado, let's get on with that.
[^02_0]: The println function is implicitly imported from the standard library package kotlin.io.
[^02_2]: You can also find some chapters of this book online on the Kt. Academy website. These examples can be started and modified thanks to the Kotlin Playground feature.
[^02_3]: It makes me happy when people try to challenge what I am teaching. Be skeptical, and verify what you've learned; this is a great way to learn something new and deepen your understanding.
[^02_5]: This doesn’t always work because the decompiler is not perfect, but it is really helpful anyway.
[^02_6]: More about this in the book Advanced Kotlin, chapter Kotlin and Java interoperability.
[^02_7]: By elements in the context of Kotlin programming we mean classes, functions, properties, object, interfaces, etc. We will discuss all element types in the following chapters.
Marcin Moskala is a highly experienced developer and Kotlin instructor as the founder of Kt. Academy, an official JetBrains partner specializing in Kotlin training, Google Developers Expert, known for his significant contributions to the Kotlin community. Moskala is the author of several widely recognized books, including "Effective Kotlin," "Kotlin Coroutines," "Functional Kotlin," "Advanced Kotlin," "Kotlin Essentials," and "Android Development with Kotlin."
Beyond his literary achievements, Moskala is the author of the largest Medium publication dedicated to Kotlin. As a respected speaker, he has been invited to share his insights at numerous programming conferences, including events such as Droidcon and the prestigious Kotlin Conf, the premier conference dedicated to the Kotlin programming language.
Owen has been developing software since the mid 1990s and remembers the productivity of languages such as Clipper and Borland Delphi.
Since 2001, He moved to Web, Server based Java and the Open Source revolution.
With many years of commercial Java experience, He picked up on Kotlin in early 2015.
After taking detours into Clojure and Scala, like Goldilocks, He thinks Kotlin is just right and tastes the best.
Owen enthusiastically helps Kotlin developers continue to succeed.
Nicola Corti is a Google Developer Expert for Kotlin. He has been working with the language since before version 1.0 and he is the maintainer of several open-source libraries and tools.
He's currently working as Android Infrastructure Engineer at Spotify in Stockholm, Sweden.
Furthermore, he is an active member of the developer community.
His involvement goes from speaking at international conferences about Mobile development to leading communities across Europe (GDG Pisa, KUG Hamburg, GDG Sthlm Android).
In his free time, he also loves baking, photography, and running.
Software architect with 15 years of experience, currently working on building infrastructure for AI. I think Kotlin is one of the best programming languages ever created.
Emanuele is passionate about Android and has been fascinated by it since 2010: the more he learns, the more he wishes to share what he knows with others, which is why he started maintaining his own blog.
In his current role as Senior Android Developer at Mozio, he is now focusing on Kotlin Multiplatform Mobile: he has already given a couple of talks on this topic on various occasions, so far.
Interested in everything Android and Kotlin related, including architecture patterns, TDD, functional programming and Jetpack Compose. Author of several articles about Android and Kotlin Coroutines.