Kotlin, the Pragmatic
Language for Android
Mike Gouline
Android Developer
gouline.net • @mikestruct
Agenda
Background
Background
Problems with Java
What is Kotlin?
What is Kotlin?
History
Syntax
class Foo(name: String) : Bar(name) {
override fun makeStuff(): Stuff {
return Stuff()
}
}
Null safety
var str1: String? = null
str1?.trim() // doesn't run
str1 = "Not null anymore"
str1?.trim() // does runs
str1!!.trim() // runs anyway
val str2: String = "I am not null"
str2.trim() // no need for "?."
String str1 = null;
str1.trim(); // runs and crashes
str1 = "Not null anymore";
str1.trim(); // runs
String str2 = "I am not null";
str2.trim(); // runs
KOTLIN
JAVA
Lambdas
fun evens(nums: List<Int>) = nums.filter { it % 2 == 0 }
public List<Integer> evens(List<Integer> nums) {
List<Integer> numsCopy = new ArrayList<>(nums);
Iterator<Integer> numsItr = numsCopy.listIterator();
while (numsItr.hasNext()) {
Integer num = numsItr.next();
if (num % 2 != 0) numsItr.remove();
}
return numsCopy;
}
KOTLIN
JAVA
Data classes
public static class Island {
private String mName;
public Island(String name) { mName = name; }
public String getName() { return mName; }
public void setName(String name) { mName = name; }
@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Island island = (Island) o;
return mName != null ? mName.equals(island.mName) : island.mName == null;
}
@Override public int hashCode() { return mName != null ? mName.hashCode() : 0; }
}
data class Island(var name: String)
KOTLIN
JAVA
Properties in Java code
// Java code
public class Circle {
private float mRadius;
public float getRadius() { return mRadius; }
public void setRadius(float radius) { mRadius = radius; }
}
// Kotlin code
val circle = Circle()
circle.radius = 1.5f // => circle.setRadius(1.5f)
println(circle.radius) // => circle.getRadius()
Sealed classes (algebraic data types)
// Arithmetic expression
sealed class Expr {
class Const(val number: Double) : Expr()
class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
}
fun eval(expr: Expr): Double = when (expr) {
is Expr.Const -> expr.number
is Expr.Sum -> eval(expr.e1) + eval(expr.e2)
Expr.NotANumber -> Double.NaN
}
Named/optional arguments
// Argument "stroke" is optional
fun circle(x: Int, y: Int, rad: Int, stroke: Int = 1) {
...
}
// Argument "rad" is named and "stroke" defaults to 1
circle(0, 0, rad = 5)
Extension functions
// Extension to String
fun String.encodeSpaces(): String {
return this.replace(" ", "_")
}
println("one two three".encodeSpaces()) // output: one_two_three
Perfect for Android
Perfect for Android
Why not others?
Android extensions
Android extensions
import kotlinx.android.synthetic.main.activity_main.*
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn_go.setText(R.string.go)
btn_go.setOnClickListener { v ->
txt_status.text = "Done"
}
}
Nullability
Annotation processing
Performance and cost
Performance
Build time
Build time: clean
Courtesy of Keepsafe Engineering blog - goo.gl/WPs1Gx
Build time: incremental - isolated file change
Courtesy of Keepsafe Engineering blog - goo.gl/WPs1Gx
Build time: incremental - core file change
Courtesy of Keepsafe Engineering blog - goo.gl/WPs1Gx
Cost
Case study
Case study
Method count
All methods →
Method count
Kotlin methods →
Lines of code
APK size
Migration guide
Migration guide
Migration fears
Were they founded?
Migration fears
Were they founded? No
Migration fears
Community adoption
Community adoption
Contributions
Gradle support
Not just Android
Current issues
Current issues
Current issues
Future releases
Future releases
Kotlin EAP 1.1
Kotlin EAP 1.1 (relevant to Android)
Summary
Summary
Thank you!
More Kotlin talks at YOW! Connected 2016:
gouline.net • @mikestruct