Main
Make a new Kotlin project, I’m using IntelliJ. In src make a main.kt file. Start with the equivalent main class as we would in Java. Declare a function with fun. Print Hello World. Notice you leave out the semi-colons. Note: when we don’t declare a class in Kotlin, the Kotlin compiler will generate one for you.
fun main(args: Array<String>) {
println("Hello World")
}
Classes and Fields
Make an Employee.kt file. Declare an Employee class. Declare a field called name by using the var keyword. Declare it of type string. Fields have to be initialised in Kotlin so initialise it with an empty string:
class Employee {
var name: String = ""
}
New
Now add to the main. Notice we don’t have to use the new keyword to instantiate an Employee:
var employee = Employee()
String Interpolation
Kotlin will recognise ${} as string interpolation:
employee.name = "Jack"
println("My name is ${employee.name}")
Variables: Mutable or Immutable
Variables can be declared with var (mutable) or val (immutable). If we had declared name to be a val as below:
class Employee {
val name: String = ""
}
Then it would be immutable, and we would get an error when we tried to reassign it in our main:
Constructors
Kotlin classes also support constructors. Change the Employee class so that it declares a constructor:
class Employee(var name: String) {
//var name: String = ""
}
Now in the main class we can remove the below line:
//employee.name = "Jack"
Instead we will pass “Jack” in the new Person constructor:
var employee = Employee("Jack")
Public by default
The default access modifier in Kotlin is public. If we add a function to Employee:
fun printEmployeeName() {
println("Display: $name")
}
We can call it from a different location:
employee.printEmployeeName()
If / Else
In Kotlin If / Else can be used as an expression that will return a value. We can then assign that value to a variable:
var message = if(employee.name == "Jack") {
"Correct"
} else {
"Incorrect"
}
println(message)
Nulls
Kotlin tries to protect us against null values. It does that by requiring we explicitly state if something can take on a null value. In a new Question class we do that with a question mark to state our answer field might be null:
class Question {
var answer: String? = null
}
In our main we can instantiate our Question like this:
var q = Question()
Or if we want to state that our Question instance might be null we can do so:
var q: Question? = Question()
If we had declared a Question instance that couldn’t be null we could have instantiated our answer like below:
var q = Question()
q.answer = null
However as we are declaring that the Question instance could be null if we instantiated it as above we would be prompted by the IDE:
To fix this we’ll use what’s known as the Safe Operator. The Safe Operator says if it evaluates to not-null then perform the operation, but if it evaluates to null don’t perform the operation. So add in the Safe Operator question mark:
q?.answer = null
When statement
Instead of a Switch statement Kotlin has a When statement:
fun printResult() {
when(answer) {
correctAnswer -> println("That's correct")
else -> println("That's incorrect")
}
}
Try
Like If/Else, the Try statement in Kotlin is also an expression. Below are examples of its use, first with non-null input:
var answerAsNumber: Int = try{
Integer.parseInt(q?.answer)
} catch (e: NumberFormatException) {
-1
}
And also with null input:
var answerAsNumberNull: Int? = try{
Integer.parseInt(q?.answer)
} catch (e: NumberFormatException) {
null
}
Ranges
Ranges are a useful tool in Kotlin. You can have a range over anything that implements the comparable interface: integers, characters, etc:
var myNum = 1..5
var myChar = 'a'..'e'
for (i in myNum) {
print(i)
}
for (i in myChar) {
print(i)
}
Loops
While and do loops are quite similar in Kotlin. However For loops are slightly different. To iterate over a list:
var numbers = listOf(1, 2, 3, 4, 5)
for(i in numbers) {
println(i)
}
To iterate over a list and return the index:
for((index, element) in numbers.withIndex()) {
println("$element at $index")
}
To iterate over a range:
for(i in 1..10) {
print(i)
}
Ranges can be closed ranges, i.e. inclusive ranges. In Java we are used to a half-closed range. For Kotlin you can use a half closed range by using until:
for(i in 1 until 10) {
println(i)
}
By using step we can define a step between the values:
for(i in 1..10 step 2) {
println(i)
}
To iterate in reverse order, use downTo instead of ..
for(i in 10 downTo 1) {
println(i)
}
To iterate over a map:
var ages = TreeMap<String, Int>()
ages["Tom"] = 23
ages["Lisa"] = 43
ages["Alex"] = 71
for((firstName, age) in ages) {
println("My name is $firstName and I am $age years old")
}
Exceptions
Another thing Kotlin simplifies is the use of exceptions. For example if we look at the read method for FileReader, we can see in the SE 8 documentation it throws an I/O exception.
However in Kotlin we don’t have to catch or re-throw this exception. Kotlin essentially uses unchecked exceptions. This means we don’t have to specify that any class throws an exception and we don’t have to catch exceptions in Kotlin.
var reader = FileReader("filename")
reader.read()
That’s it! I hope this is helpful, my GitHub is linked below with the topic we’ve just discussed. I’ve also linked Kotlin Fundamentals by Kevin Jones with more information.