A Beginner's Guide to Kotlin
A Beginner's Guide to Kotlin
Get started with this guide that outlines some of the basic features of Kotlin, walks through a Hello World app, and more.
Join the DZone community and get the full member experience.Join For Free
This post will provide you with:
- A brief overview of Kotlin’s features
- A guide for solving a basic problem and building a “Hello, World!” app.
- A brief breakdown on running a Kotlin Spring Boot application with authentication via Okta
Kotlin is a modern language that is statically typed within the JVM. It’s a multi-purpose, cross-platform, free and open-source language developed by JetBrains under the Apache 2.0 license. Kotlin has constructs for both Object Oriented and Functional programming styles (as well as mixed). It can be used for many types of development; web, server, and client, and mobile—using most Java IDEs.
For Java developers, Kotlin is a great option as it is concise, expressive, and safe. It can cut the total lines of code in your app by up to 40% (source: JetBrains). Kotlin also helps prevent NullPointerExceptions as it provides non-nullable types.
According to GitHub Octoverse Report 2018, Kotlin is the number one fastest-growing language. Its popularity increases every month—with 2.2M users and growing—and many large organizations are using it. Android and JVM developers can’t get enough of its features.
Before we begin, let’s discuss why Kotlin could be useful for you in your next project:
Kotlin vs. Java, aka Why This Tutorial?
Kotlin was designed to fix a number of Java’s issues:
Null references: Java allows null reference values, and the Kotlin type system helps to eliminate the access to a member of a null reference, which would result in the equivalent of a
Invariant array: In Java, arrays are covariant, and array
Integer is a subtype of
Number, so the compiler allows assigning a
Double to a
Number reference, but the program might raise an exception at runtime if the instance is
Integer. Kotlin does not let you assign
Array<Any>, preventing runtime failures.
Any is the root of the Kotlin class hierarchy.
Any is the root of the Kotlin class hierarchy, but it is not equivalent to
java.lang.Object is mapped to
kotlin.Any!, and the
! notation means it can be
Any? (nullable or not). As
Object, other Java types are not used “as is”, but mapped to Kotlin types. A complete list of mappings is available in the Kotlin Reference.
No raw types: There are no raw types in Kotlin, as generics are different. Java raw types, like
List, are converted into star projections
List<*>!, which are similar to raw types, but provide runtime safety. How? The compiler will not allow write operations if the type argument is unknown, as it might cause a cast exception when reading. In Java, you can add any object to a raw List, but in Kotlin adding to a start projected list won’t compile.
Use-site variance: Java’s type system uses bounded wildcards to increase API flexibility, as generic types are invariant (as opposed to Java arrays, which are covariant), meaning
List<String> is not a subtype of
List<Object>, but can be assigned to
List<? extends Object> type. In Kotlin, instead of bounded wildcards, use-site variance allows to restrict the generic type in the place it is used, with a simpler syntax like
Array<out Any>, equivalent to Java’s
Array<? extends Object>. The compiler verifies the parameter type is only returned from a method of the instance, but not consumed, to avoid runtime exceptions, for example, if attempting to write a
The example above does not compile in Kotlin, because the
readMethod() receives the out-projected array (only read operations allowed) and it is calling the write operation
No checked exceptions: Java checked exceptions must be somehow handled for the program to compile, and are many times swallowed by an empty catch block. Kotlin does not have checked exceptions, because it is suggested that in large software projects it decreases productivity.
Proper function types: As opposed to Java SAM (Single Abstract Method) conversions, where a lambda expression is convertible to a SAM type according to some rules, Kotlin uses a family of function types like
(Int) -> String, with the special notation corresponding to the signature of the functions (parameters and return values).
A complete list of Kotlin features, not supported in Java, is available at Kotlin Reference.
Java and Kotlin Interoperability
Kotlin is 100% interoperable with Java: Kotlin code can be called from Java and vice versa. Existing Java code can be used with some considerations. For example, Java getters and setters are represented by properties in Kotlin:
With an IDE like IntelliJ IDEA, you can add Java source code to a Kotlin project just by creating a
Objects coming from Java, called platform types, have relaxed null-checks for practical reasons, and safety is the same as in Java. Kotlin will not inform a compilation error but the call might fail at runtime. For example, if Kotlin calls Java code that returns an
ArrayList, the inferred type in Kotlin will be
ArrayList<String!>!, which means the collection can be nullable, and the items as well.
In the Java code below,
null is added as an item to the list.
In the Kotlin lines below, we are calling the previous Java code, so the safety is relaxed. The program compiles, but as the first item is
null, it will fail at runtime with
Pre-Tutorial: A Taste of Kotlin
To avoid the programmer’s curse, let’s not skip trying a simple “Hello, World!” example with Kotlin. An easy way to get started with Kotlin is to download and install IntelliJ IDEA Community Edition from JetBrains, which is also free. And also install Maven for dependency management and to run the application from the command line.
Start IntelliJ IDEA and create a new Kotlin project, choosing Kotlin/JVM.
Set the project name, location, and Java 8 SDK. After the project is created, add Maven support by doing a right-click on the project and choosing Add Framework Support. Then select the Maven checkbox and click OK.
Add a new Kotlin File/Class to the
src/main/kotlin folder. Set the file name to
app. The IDE will automatically add the extension
.kt, which indicates it is a Kotlin file. Add the following code:
In the lines above, you can see a package declaration, which is optional. If not present, everything goes to the default package. The
main function is the entry point to the application and can be declared without parameters (if your program does not need to accept command-line arguments) and return nothing. The
println function is part of the Kotlin Standard Library and prints the message and the line separator to the standard output stream.
N: In Kotlin, it is not required to match directories and packages. Source files can be placed arbitrarily in the file system, and one file can contain multiple classes. For pure Kotlin projects, the common root package
com.okta.developers is omitted in the filesystem.
pom.xml to add Kotlin dependencies and the Kotlin Maven Plugin.
Build and run the application with the following Maven command:
It should output the hello message:
Now, let’s apply some Kotlin idioms to solve a common interview problem: finding anagrams in substrings. Given a string, find the number of pairs of substrings that are anagrams of each other.
First, update the
main function in
app.kt to make it scan the string to analyze from the standard input:
In the code above, we declare two immutable variables, using the keyword
val. Mutable variables must be declared with the keyword
var. Kotlin also does type inference, so as you can see, none of the variables declare type.
readLine() is a function from the
kotlin-stdlib that reads a line from the standard input stream, available for JVM and Native targets.
Then, add a new Kotlin File/Class to the existing project with the name
String to add a function that returns a String with the same characters in lexicographic order, appending the following code to
The Extension functions idiom provides a mechanism to extend a class without using inheritance, allowing to write new functions for classes in third party libraries that cannot be modified, even if they are final classes. In the code above, we declare the function
sort() as an extension for the
String class, with no parameters and return type
sort() function is a Single-expression function, another Kotlin idiom for writing shorter code, as the
return keyword and enclosing brackets are not required.
sort(), define the
Anagrams class as follows:
for loop in
count(s: String) function will iterate over
i in a half-open range, from
s.length, not including
s.length. That way, in each iteration using the
windowed function of
String, we create all the possible substrings of the current length
i . Then
sort() all the substrings and create a
MutableList, to be able to remove elements later. Each collection type in the Kotlin Standard Library (set, list, map) provides a read-only and a mutable interface that defines write operations.
As the substrings are sorted, they can be compared to each other to find anagrams. Using the
count() and passing a lambda predicate expressed with the
it parameter, the number of matches will be returned. Many times, a lambda expression has only one parameter, and the implicit name of a single parameter
it allows a shorter syntax.
Add the following test cases for the
Anagram class in a new Kotlin file
Run the test cases with Maven:
The test results will show in the console:
Run the program the same way as before, type the string to analyze in the console, then type the enter key. You should see an output like the following:
Tutorial: Use Kotlin With Spring Boot Securely
Finally, let’s see how easy is to create a Kotlin Spring Boot application with Okta OpenID Connect (OIDC) authentication.
Using the Spring Initializr API, create a Maven project with the following command:
Unzip the file:
Secure Your Application with OpenID Connect
If you already have an Okta account, see the Create a Web Application in Okta sidebar below. Otherwise, we created a Maven plugin that configures a free Okta developer account + an OIDC app (in under a minute!).
You should see the following output:
Check your email and follow the instructions to activate your Okta account.
If you already have an Okta Developer account, log in and create a new application:
- From the Applications page, choose Add Application.
- On the Create New Application page, select Web.
- Give your app a memorable name, add
http://localhost:8080/login/oauth2/code/oktaas a Login redirect URI.
Copy the issuer (found under API > Authorization Servers), client ID, and client secret into
KotlinSpringBootApplication located in the package
com.okta.developer to add a controller mapping that will print a welcome message in the browser window.
As you can see, in the
hello() function, the authenticated user is passed in the
@AuthenticationPrincipal annotation from Spring Security helps to resolve the principal to the expected principal type. The welcome message is built using String interpolation, a Kotlin idiom for variable substitution inside strings.
Run the application with the following command:
http://localhost:8080 and the application should start an OAuth 2.0 authentication code flow, redirecting to the Okta login page.
After the login, you should see the welcome message:
You now have a secure application with just a few lines of Kotlin and the help of Spring Boot!
Learn More About Kotlin, Java, and Secure Authentication with These Tutorials
I hope this blog post helped you grasp how succinct and expressive Kotlin is and why developers are loving it. You can find all the tutorial code in repositories kotlin-hello-world and kotlin-spring-boot on GitHub. To learn more about Kotlin, check out the following links:
- Build a Basic CRUD App in Android with Kotlin
- Build an Application with Spring Boot and Kotlin
- Kotlin Reference
Published at DZone with permission of Jimena Garbarino , DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.