Программирование на Kotlin, осень 2016: Mixing Java and Kotlin

Preview:

Citation preview

Mixed projects: Java + Kotlin

Svetlana Isakova

Compilation of a mixed project

*.java

kotlinc

*.kt

*.class

javac *.class

*.jar

Nullability

Nullability

?Type =

Java Kotlin

Nullability annotations

@Nullable

@NotNull Type

Type?

Type

+

+

=

=

Type

Java Kotlin

Java type without annotation has “unknown” nullability

public class Session { String getDescription() { return null; }}

Explicit type

val session = Session() val description: String? = session.descriptionprintln(description!!.length)

val description1: String = session.description println(description1.length)

KNPE

IllegalStateException: session.description must not be null

Not-null typesclass A { fun x(s: List<String>) { println(s) }

private fun y(s: String) { println(s) } }

public final class A { public final void x(@NotNull List<String> s) { Intrinsics.checkParameterIsNotNull(s, "s"); System.out.println(s); } private final void y(String s) { System.out.println(s); }}

is compiled to

Platform type

Type Type= Type?OR

Java Kotlin

notation in error messages: Type!

Inferred type

val session = Session()val description = session.descriptionprintln(description.length)

val i: Int = session.description

NPE

Error: Type mismatch: inferred type is String! but Int was expected

println(description?.length)

Prefer explicit Kotlin types when working with Java

Basic types

Primitive & wrapper types

Java Kotlin

int Int

double Double

boolean Boolean

Java Kotlin

java.lang.Integer Int?

java.lang.Double Double?

java.lang.Boolean Boolean?

Generic arguments

Kotlin Java

List<Int> List<Integer>

Arrays of primitive types

Kotlin Java

Array<Int> Integer[]

IntArray int[]

Any?

Kotlin Java

Any? java.lang.Object

Unitfun f(): Unit { /*...*/ }

fun f() { /*...*/ }

Unit as generic argument

interface Processor<T> { fun process(): T } class NoResultProcessor : Processor<Unit> { override fun process() { // do stuff } }

Unit

Kotlin Java

Unit void

Foo<Unit> Foo<Unit>

Nothing

fun fail(message: String): Nothing { throw IllegalStateException(message)}

val n = null

: Nothing?

Nothing

Kotlin Java

Nothing void

List<Nothing> List //raw type

Any & Nothing typesAny

Int

StringList<T>

Parent

Nothing

MutableList<T>

Child

Type hierarchy

Any

Int

StringList<T>

Parent

Nothing

MutableList<T>

Child

Any?

Int?

String?List<T>?

Parent?

Nothing?

MutableList<T>?

Child?

Collections

List & MutableList

kotlin.List

kotlin.MutableList

• Two interfaces declared in kotlin package

•MutableList extends List

Read-only != immutable

(1, 2, 3)• Read-only interface just lacks mutating methods

• The actual list can be changed by another reference

listmutableList

Under the hood

fun getNames(): List<String>fun getNames(): MutableList<String>

java.util.List<String> getNames();

Both functions are compiled to:

At runtime is a good old java.util.List

List in Kotlin

Iterable

Collection

MutableIterable

List

MutableCollection

Set

MutableList

MutableSet

ArrayList

HashSet

Platform type

Type Type= Type?OR

Java Kotlin

List List= MutableListOR

Collection as platform type

(Mutable)List<Int!>

Annotations

@JvmName// Data.kt fun foo() {}

public final class DataKt { public static void foo() { } }

@file:JvmName("FooUtils") fun foo() {}

public final class FooUtils { public static final void foo() { } }

@JvmName

fun List<String>.filterValid(): List<String>fun List<Int>.filterValid(): List<Int>

Error: platform declaration clash: declarations have the same JVM signature (filterValid(Ljava/util/List;)Ljava/util/List;)

@JvmName

fun List<String>.filterValid(): List<String>

@JvmName("filterValidInt") fun List<Int>.filterValid(): List<Int>

@JvmOverloads

@JvmOverloadsfun f(a: String, b: Int = 0, c: String = "abc") { // ...}

// Javavoid f(String a, int b, String c) { }void f(String a, int b) { }void f(String a) { }

@Throws

@Throws(IOException::class) fun foo() { throw IOException()}

Checked exceptions

// Javatry { DemoKt.foo();} catch (IOException e) { // ...}

fun foo() { throw IOException() }

Error: Exception java.io.IOException is never thrown in body

of corresponding try statement

Checked exceptions

// Javatry { DemoKt.foo();} catch (IOException e) { // ...}

@Throws(IOException::class) fun foo() { throw IOException() }

@JvmStaticclass C { companion object { @JvmStatic fun foo() {} fun bar() {} }}

// JavaC.foo();C.Companion.bar();

@JvmStaticobject Obj { @JvmStatic fun foo() {} fun bar() {}}

// Java Obj.foo();Obj.bar();Obj.INSTANCE.bar();Obj.INSTANCE.foo();

Have a nice Kotlin!

Recommended