By Mike Cleron, Director,
Android Platform
Today the Android team is excited to announce that we are officially adding support for the Kotlin programming language. Kotlin is a brilliantly designed, mature language that we believe will make Android development faster and more fun. It has already been adopted by several major developers — Expedia, Flipboard, Pinterest, Square, and others — for their production apps. Kotlin also plays well with the Java programming language; the effortless interoperation between the two languages has been a large part of Kotlin's appeal.
The Kotlin plug-in is now bundled with Android Studio 3.0 and is available for immediate download. Kotlin was developed by JetBrains, the same people who created IntelliJ, so it is not surprising that the IDE support for Kotlin is outstanding.
In addition to the IDE support, we're announcing a collaboration with JetBrains to move Kotlin into a non-profit foundation. (Kotlin is already open sourced under Apache2.)
Today the Android team is excited to announce that we are officially adding support for the Kotlin programming language. Kotlin is a brilliantly designed, mature language that we believe will make Android development faster and more fun. It has already been adopted by several major developers — Expedia, Flipboard, Pinterest, Square, and others — for their production apps. Kotlin also plays well with the Java programming language; the effortless interoperation between the two languages has been a large part of Kotlin's appeal.
The Kotlin plug-in is now bundled with Android Studio 3.0 and is available for immediate download. Kotlin was developed by JetBrains, the same people who created IntelliJ, so it is not surprising that the IDE support for Kotlin is outstanding.
In addition to the IDE support, we're announcing a collaboration with JetBrains to move Kotlin into a non-profit foundation. (Kotlin is already open sourced under Apache2.)
- Download Android Studio 3.0
- Open one of your existing ".java" files
- Invoke "Code > Convert Java File to Kotlin File"
Say "Hello" to Kotlin
Kotlin will be very familiar to anyone who has used the Java programming language.package helloWorld fun main(args: ArrayAt first glance, you will see comforting elements like curly braces, classes, packages, functions and methods. But as you go deeper, you will discover that although Kotlin is based on familiar concepts, it is a uniquely modern, elegant and pragmatic riff on those models. In particular, Kotlin is highly expressive with minimal syntactic friction between your thoughts and what you have to type in order to express those thoughts. If when writing code you have asked yourself questions that began "why do I have to …?" you will be pleased to learn that in Kotlin the answer to many of those questions is "you don't!") { println("Hello World!") }
For example, perhaps you have asked why you need to type in a bunch of boilerplate getters and setters as well as overriding
equals()
,
hashCode()
and toString()
when implementing a simple
class. Here is a typical example from the Java programming language (in a
microscopic font for brevity).
public class Customer { private String name; private String email; private String company; public Customer(String name) { this(name, "", ""); } public Customer(String name, String email) { this(name, email, ""); } public Customer(String name, String email, String company) { this.name = name; this.email = email; this.company = company; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getCompany() { return company; } public void setCompany(String company) { this.company = company; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Customer customer = (Customer) o; if (name != null ? !name.equals(customer.name) : customer.name != null) return false; if (email != null ? !email.equals(customer.email) : customer.email != null) return false; return company != null ? company.equals(customer.company) : customer.company == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + (email != null ? email.hashCode() : 0); result = 31 * result + (company != null ? company.hashCode() : 0); return result; } @Override public String toString() { return "Customer{" + "name='" + name + '\'' + ", email='" + email + '\'' + ", company='" + company + '\'' + '}'; } }In Kotlin, you don't have to type any of that. This single line is equivalent to the entire class above.
data class Customer(var name: String, var email: String = "", var company: String = "")
History and Reference
Kotlin has been around for quite a while; it was announced back in 2011 and the first preview was released in 2012. Kotlin 1.0 was released in 2016, at which point JetBrains committed to maintaining backwards compatibility for stable features from 1.0 forward.You can find excellent training material and references at https://kotlinlang.org/. The Android team has found the Kotlin Koans tutorial to be especially helpful as a quick way to get started writing some Kotlin snippets. These tutorials range from the simple to the sublime as the material progresses from the basics to more sophisticated Kotlin idioms.
Why Kotlin?
Why did the Android team decide to support Kotlin? Most importantly, it was because we think Kotlin is a great language that will make writing Android apps easier and more enjoyable.Kotlin is also a great match for the existing Android ecosystem. It is 100% compatible with the Java programming language. You can add as little or as much Kotlin into your existing codebase as you want and mix the two languages freely within the same project. Calling out to Kotlin code from code written in the Java programming language Just Works™. Going the other direction usually works without any developer effort too via some automatically applied translation conventions (for example, things like property getters and setters are created for you). With the help of a few Kotlin annotations, you can also customize how the translation is performed.
Finally, many, many developers have told us they love the Kotlin language. (Many of our own developers on the Android team have also been saying similar things.) There is already an enthusiastic community of Kotlin developers for Android, and the Android team has been routinely peppered with questions about Kotlin at public events. The Android community has spoken, and we listened.
A Quick Tour
To help you get a sense of where all of the excitement around Kotlin is coming from, here is a quick, very-much-not-comprehensive tour of some of the particularly appealing aspects of Kotlin:Nullable
The Kotlin compiler enforces that variables that can hold null values are explicitly declared – thus no more NullPointerExceptions at runtime!
var neverNull: String = "something" var mightBeNull: String? = null // "?" indicates this can be null if (neverNull.length > 0) { // This is OK … } if (mightBeNull.length > 0) { // Compiler catches this error for you … }Named parameters and default arguments
We've all seen methods that have too many parameters to keep track of. For example:
fun orderPizza(size: Size, pepperoni: Boolean, mushrooms: Boolean, ham: Boolean, pineapple: Boolean, pickles: Boolean, sausage: Boolean, peppers: Boolean, onion: Boolean) { ... } // Wait… did I just order pickles on my pizza? // Why do we even have that option? orderPizza(Size.LARGE, true, false, false, false, true, false, true, false)Compare that to a similar scenario using named parameters and default arguments:
fun orderPizza(size: Size, pepperoni: Boolean = false, mushrooms: Boolean = false, ham: Boolean = false, pineapple: Boolean = false, pickles: Boolean = false, sausage: Boolean = false, peppers: Boolean = false, onion: Boolean = false) { ... } orderPizza(Size.LARGE, ham = true, mushrooms = true)In addition to helping to avoid tragic pizza outcomes, this is much easier to read. It also reduces the number of variants of overloaded functions you need to write.
When statement
Kotlin has a variation of a switch statement that allows matching on arbitrary expressions.
// Please don't put this in your app! when { password.equals("password") -> println("Insecure password!") password.length < 4 -> println("Too short!") else -> { println("Secure password!") } }Smart Casts
Why should you have to cast something to a class right after you just tested that it is an instance of that class? In Kotlin, you don't have to do that anymore.
if (obj is String) { // Compiler casts obj to a String for you. // (Would work with && instead of nested ifs too.) if (obj.length > 0) { … } }This generalizes to the when statement as well:
// Assume reasonable implementations of Cat and Dog when (obj) { is Cat -> obj.meow(...) is Dog -> obj.woof(...) else -> { … } }Extension functions
Kotlin lets you essentially retcon new methods onto an existing type. If you, like many people, wish that the String class had a
toPigLatin
method, you can now add it yourself
without having to create a new helper class to wrap String or going through the
trouble of serving on a language committee:
// The "String." prefix indicates that this method should // extend the existing String class fun String.toPigLatin() : String { ... } val plainOldString : String = "some text" // Can now call toPigLatin as if were a method on String println(plainOldString.toPigLatin()) // Or: println("some text".toPigLatin())Destructuring Declarations
We have already seen how easy it is to define a simple data class:
data class Order(val itemCode: String, val quantity: Int, val price: Float)A function that uses one of these classes as the return type is very close to supporting multiple return values:
fun getOrder(...): Order { ... return Order(itemCode, quantity, price); }To get all the way there, you can use the destructuring declaration syntax. The following statement takes the
Order
object, extracts its three
properties, and then assigns them to the three variables what
,
howMany
and howMuch
— all courtesy of the Kotlin
compiler, which also infers the correct types for you.
val (what, howMany, howMuch) = getOrder(...)Lambdas
Kotin has an extremely concise syntax for lambdas that makes is easy to express powerful functional programming paradigms. Here's a simple example that uses a lambda to test that everything in a collection is a String:
fun allStrings(collection: CollectionThat lambda syntax is building block of one of Kotlin's coolest features: the ability to create builders that use JSON-like syntax that also happens to be syntactically valid Kotlin. This example is adapted from an extended discussion here, but you can get the flavor of what it possible with this snippet:)= collection.all { it is String }
fun generatePage(withEmphasis : Boolean) { val result = html { head { title { +"Kotlin Builders" } } body { h1 { +"Kotlin Builders" } p { +"This is " if (withEmphasis) b { +"really " } +"interesting" a(href = "https://goo.gl/rHwJio") { +"More here" } } } } println(result) }There are a couple of interesting things going on here. First, this shows how expressive Kotlin's functional syntax can be: in this example, "
html
", "head
", "body
, etc. are all just
functions written in Kotlin and the stuff in curly braces that follows are
functional parameters. (This snippet uses functions with names that match HTML
tags to build a representation of a web page, but of course you can use this
pattern to build any complex data structure with whatever names you want.) The
second interesting thing is the "withEmphasis
" conditional. This
may look like we are mixing code (if (withEmphasis)
…) with data
(all the HTML-esque tags), but the "data" here is actually just more code. Since
it is all really just code, this lets you build complex data structures using a
declarative syntax while also having inline access to the full capabilities of
the Kotlin language.
Getting Started
If you want to get started with Kotlin, you can start playing with code online immediately here. Just hit the green triangle to compile and run.To try Kotlin in your app, follow these steps:
You can also find a lot more information on how to start using Kotlin on developer.android.com.