Stage

Kotlin feature

Java features

Notes

1

Calling Java code from Kotlin

Getters and Setters

Methods returning void

Escaping for Java identifiers that are keywords in Kotlin

Null-Safety and Platform Types

Notation for Platform Types

Nullability annotations

JSR-305 Support

Type qualifier nicknames

Type qualifier defaults

Compiler configuration

Mapped types

Java generics in Kotlin

Java Arrays

Java Varargs

Operators

Checked Exceptions

Object Methods

wait()/notify()

getClass()

clone()

finalize()

Inheritance from Java classes

Accessing static members

Java Reflection

SAM Conversions

Using JNI with Kotlin

https://kotlinlang.org/docs/reference/java-interop.html

1

Calling Kotlin from Java

Properties

Package-Level Functions

Instance Fields

Static Fields

Static Methods

Visibility

KClass

Handling signature clashes with @JvmName

Overloads Generation

Checked Exceptions

Null-safety

Variant generics

Translation of type Nothing

https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html

1

Improving Java Interop: Top-Level Functions and Properties

https://blog.jetbrains.com/kotlin/2015/06/improving-java-interop-top-level-functions-and-properties/

1

Functions

https://kotlinlang.org/docs/reference/functions.html

1

Interfaces

https://kotlinlang.org/docs/reference/interfaces.html

1

Classes and Inheritance

Classes

Constructors

Secondary Constructors

Creating instances of classes

Class Members

Inheritance / open class

Overriding Methods / open fun

Overriding Properties / open val

Calling the superclass implementation

Overriding Rules

Abstract Classes

Companion Objects

https://kotlinlang.org/docs/reference/classes.html

1

Nested and Inner Classes

Inner classes

Anonymous inner classes

https://kotlinlang.org/docs/reference/nested-classes.html

1

Visibility Modifiers

Packages

top-level

Classes and Interfaces

private, protected, internal, public

Constructors

Local declarations

Modules

https://kotlinlang.org/docs/reference/visibility-modifiers.html

1

;

1

package vlfsoft.iq.kotlin.fromjava

package vlfsoft.iq.kotlin.fromjava;

http://kotlinlang.org/docs/reference/basic-syntax.html#defining-packages

1

Default Arguments

https://kotlinlang.org/docs/reference/functions.html#default-arguments

1

Named Arguments

https://kotlinlang.org/docs/reference/functions.html#named-arguments

1

data class ImmutableValueObjectKt(val a: Int)

public class ImmutableValueObject {

    private final int a;

    public ImmutableValueObject(final int a) {

        this.a = a;

    }

    public int getA() {

        return a;

    }

}

https://kotlinlang.org/docs/reference/data-classes.html

https://kotlinlang.org/docs/reference/sealed-classes.html#sealed-classes

1

class MutableValueObjectKt(var a: Int)

public class MutableValueObject {

    private int a;

    public MutableValueObject(final int a) {

        this.a = a;

    }

    public int getA() {

        return a;

    }

    public void setA(final int a) {

        this.a = a;

    }

}

1

data class MyEntity(

        @Id

        @Column(nullable = false)

        @GeneratedValue(strategy = GenerationType.AUTO)

        var id: Long = 0,

        var name: String = “”

)

 

2

Explicit return types

https://kotlinlang.org/docs/reference/functions.html#explicit-return-types

2

fun asList(vararg ts: T)

When we call a vararg-function, we can pass arguments one-by-one, e.g. asList(1, 2, 3), or, if we already have an array and want to pass its contents to the function, we use the spread operator (prefix the array with *):

val a = arrayOf(1, 2, 3)

val list = asList(-1, 0, *a, 4)

void asList(T... ts)

https://kotlinlang.org/docs/reference/functions.html#variable-number-of-arguments-varargs

2

fun main(args: Array<String>) {

}

public class Application {

    public static void main(String[] args) {

    }

}

https://blog.jetbrains.com/kotlin/2015/06/improving-java-interop-top-level-functions-and-properties/

2

Single-Expression functions

fun sum(a: Int, b: Int) = a + b

public class Function {

    public static int sum (final int a, final int b) {

        return a + b;

    }

}

http://kotlinlang.org/docs/reference/basic-syntax.html#defining-functions

https://kotlinlang.org/docs/reference/functions.html#single-expression-functions

2

Unit-returning functions

fun printSum(a: Int, b: Int) {

    println("sum of $a and $b is ${a + b}")

}

void, Void

    public static void printSum(final int a, final int b) {

        System.out.printf("sum of %d and %d is %d", a, b, a + b);

    }

https://kotlinlang.org/docs/reference/functions.html#unit-returning-functions

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html

2

val a: Int = 2

val a = 2

final int a = 2;

http://kotlinlang.org/docs/reference/basic-syntax.html#defining-variables

2

var a = 5

int a = 2;

2

Compile-Time Constants

const val PI = 3.14

PI

public class Math {

   public final static double PI = 3.14;

}

Math.PI;

https://kotlinlang.org/docs/reference/properties.html#compile-time-constants

Naming convention by default: Upper case letters and _

2

// This is an end-of-line comment

/* This is a block comment

   on multiple lines. */

// This is an end-of-line comment

/* This is a block comment

   on multiple lines. */

http://kotlinlang.org/docs/reference/basic-syntax.html#comments

2

Documenting Kotlin Code

Generating the Documentation

KDoc Syntax

Block Tags

Inline Markup

Linking to Elements

Module and Package Documentation

http://kotlinlang.org/docs/reference/kotlin-doc.html 

2

Inline Markup

/**

 * [printSum]

 */

   

   /**

     * {@link #printSum(int, int)}

     */

http://kotlinlang.org/docs/reference/kotlin-doc.html#inline-markup

2

Inline Markup

    /**

     * [Stream]<[Entity]>

     */

   

   /**

     * {@link Stream<Entity>}

     */

http://kotlinlang.org/docs/reference/kotlin-doc.html#inline-markup

2

println("sum of $a and $b is ${a + b}")

System.out.printf("sum of %d and %d is %d", a, b, a + b);

http://kotlinlang.org/docs/reference/basic-syntax.html#using-string-templates

http://kotlinlang.org/docs/reference/basic-types.html#string-templates

2

fun max(a: Int, b: Int) = if (a > b) a else b

    public static int max(final int a, final int b) {

        return a > b ? a : b;

    }

http://kotlinlang.org/docs/reference/control-flow.html#control-flow-if-when-for-while

2

Control Flow: if, when, for, while

If Expression

When Expression

Before:

fun whenFun1(a: Int) : EnumObjectKt {

val value: EnumObjectKt

        when (a) {

            1 -> value  = EnumObjectKt.Value1

            else -> value  = EnumObjectKt.Value2

        }

return value

}

After:

fun whenFun1(a: Int) =

        when (a) {

            1 -> EnumObjectKt.Value1

            else -> EnumObjectKt.Value2

        }

    public static EnumObject whenFun(final int a) {

        switch (a) {

            case 1:

                return EnumObject.Value1;

            default:

                return EnumObject.Value2;

        }

    }

http://kotlinlang.org/docs/reference/control-flow.html#control-flow-if-when-for-while

http://kotlinlang.org/docs/reference/enum-classes.html#enum-classes

2

if (i in 1..10) {}

if (1 <= i && i <= 10) {}

http://kotlinlang.org/docs/reference/control-flow.html#control-flow-if-when-for-while

https://kotlinlang.org/docs/reference/ranges.html

2

for (i in 1..10) …

for (int i = 1; I <= 10; i++) …

http://kotlinlang.org/docs/reference/control-flow.html#control-flow-if-when-for-while

https://kotlinlang.org/docs/reference/ranges.html

https://kotlinlang.org/docs/reference/control-flow.html#for-loops

2

for (item in collection) …

for (ItemType item : collection) …

http://kotlinlang.org/docs/reference/control-flow.html#control-flow-if-when-for-while

https://kotlinlang.org/docs/reference/control-flow.html#for-loops

2

while (x > 0) …

do {

} while (y != null)

while (x > 0) …

do {

} while (y != null);

http://kotlinlang.org/docs/reference/control-flow.html#control-flow-if-when-for-while

https://kotlinlang.org/docs/reference/control-flow.html#while-loops

2

Break and continue in loops

Break and continue in loops

https://kotlinlang.org/docs/reference/control-flow.html#break-and-continue-in-loops

2

enum class EnumObjectKt {Value1, Value2}

enum EnumObject {Value1, Value2}

http://kotlinlang.org/docs/reference/enum-classes.html#enum-classes

2

if (obj is String) {

}

if (obj !is String) { // same as !(obj is String)

}

if (object instanceof String) {

}

http://kotlinlang.org/docs/reference/typecasts.html

2

if (x is String) {

        print(x.length) // x is automatically cast to String

    }

http://kotlinlang.org/docs/reference/typecasts.html#smart-casts

In many cases, one does not need to use explicit cast operators in Kotlin, because the compiler tracks the is-checks and explicit casts for immutable values and inserts (safe) casts automatically when needed:

2

Local functions

https://kotlinlang.org/docs/reference/functions.html#local-functions

2

Higher-Order Functions and Lambdas

Higher-Order Functions

it: implicit name of a single parameter

Underscore for unused variables (since 1.1)

Destructuring in Lambdas (since 1.1)

Inline Functions

Lambda Expressions and Anonymous Functions

Function Types

Lambda Expression Syntax

Anonymous Functions

Closures

Function Literals with Receiver

Note: Most of the items in the feature list should be used on 3 stage.

https://kotlinlang.org/docs/reference/lambdas.html

2

Function Types

() -> Unit

    @FunctionalInterface

    public interface Run {

        void run();

    }

https://kotlinlang.org/docs/reference/lambdas.html#function-types

2

"Unsafe" cast operator

val x: String = y as String

http://kotlinlang.org/docs/reference/typecasts.html#unsafe-cast-operator

2

Properties and Fields

Declaring Properties

Getters and Setters

Backing Fields

Backing Properties

Compile-Time Constants

Late-Initialized Properties

Overriding Properties

https://kotlinlang.org/docs/reference/properties.html

2

Object expressions

Anonymous classes

https://kotlinlang.org/docs/reference/object-declarations.html#object-expressions

2

Object declarations

Singleton

https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations

2

Companion Objects

Singleton

https://kotlinlang.org/docs/reference/object-declarations.html#companion-objects

2

Semantic difference between object expressions and declarations

https://kotlinlang.org/docs/reference/object-declarations.html#semantic-difference-between-object-expressions-and-declarations

2

Generics

https://kotlinlang.org/docs/reference/generics.html

2

Java 7's try with resources

OutputStreamWriter(r.getOutputStream()).use {

    it.write('a')

}

try (OutputStreamWriter writer = new OutputStreamWriter(…)) {

writer.write(‘a’);

}

https://kotlinlang.org/docs/reference/idioms.html#java-7s-try-with-resources

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/use.html

2

Exceptions

Exception Classes

Checked Exceptions

The Nothing type

https://kotlinlang.org/docs/reference/exceptions.html

3

Auto-generated properties into Single-Expression functions or functions

Before:

    @get:annotation

    val client: ClientType

After:

    @annotation

    fun getClient(): ClientType

Before:

    override val client: ClientType

        @annotation

        get() = mApplicationContext.getBean(ClientType::class.java)

After:

    @annotation

    override fun getClient() = mApplicationContext.getBean(DownloadFileWithHttpClientA::class.java)

Usage:

getCient()

Consider replacing auto-generated properties with Single-Expression functions (see. above) or functions (see. above).

Note: Function declaration is more concise than property, but usage is vice-versa.

Until auto-conversion is added to Refactor, do manually.

1. Refcator->Rename propertyName into getPropertyName

2. Migrate property syntax into function syntax.

3

Auto-generated functions into Single-Expression functions

    override fun getClient(): ClientType {

        return Client()

    }

    override fun getClient() = Client()

Auto-conversion doesn’t create Single-Expression functions, even if it’s possible.

3

Remove redundant code like <Type> and it -> in lambdas.

3

Nullable types and Non-Null Types

var a: String = "abc"

var a: String? = null

@NotNull String a = "abc";

@Nullable String a = null;

http://kotlinlang.org/docs/reference/null-safety.html#nullable-types-and-non-null-types

3

val l = if (b != null) b.length else -1

int l = b != null ? b.length : -1;

http://kotlinlang.org/docs/reference/null-safety.html#checking-for-null-in-conditions

3

Safe Calls

person?.department?.head?.name

http://kotlinlang.org/docs/reference/null-safety.html#safe-calls

Such a chain returns null if any of the properties in it is null and name value if all properties are not null.

3

safe call operator together with let

person?.let { println(it)} // prints person info only if person != null

http://kotlinlang.org/docs/reference/null-safety.html#safe-calls

To perform a certain operation only for non-null values, you can use the safe call operator together with let:

http://kotlinlang.org/api/latest/jvm/stdlib/kotlin/let.html

3

val l = b?.length ?: -1

is equivalent of val l = if (b != null) b.length else -1

http://kotlinlang.org/docs/reference/null-safety.html#elvis-operator

3

val l = b!!.length

http://kotlinlang.org/docs/reference/null-safety.html#the--operator

return a non-null value of b (e.g., a String in our example) or throw an NPE if b is null:

3

val aInt: Int? = a as? Int

http://kotlinlang.org/docs/reference/null-safety.html#safe-casts

safe cast that return null if the attempt was not successful

http://kotlinlang.org/docs/reference/typecasts.html#safe-nullable-cast-operator

3

val intList: List<Int> = nullableList.filterNotNull()

http://kotlinlang.org/docs/reference/null-safety.html#collections-of-nullable-type

3

Destructuring Declarations

val (name, age) = person

for ((a, b) in collection) { ... }

data class Result(val result: Int, val status: Status)

fun function(...): Result {

    // computations

   

    return Result(result, status)

}

// Now, to use this function:

val (result, status) = function(...)

for ((key, value) in map) {

   // do something with the key and the value

}

http://kotlinlang.org/docs/reference/multi-declarations.html#destructuring-declarations

3

Underscore for unused variable

val (_, status) = getResult()

http://kotlinlang.org/docs/reference/multi-declarations.html#underscore-for-unused-variables-since-11

3

Destructuring in Lambdas

map.mapValues { entry -> "${entry.value}!" }

map.mapValues { (key, value) -> "$value!" }

map.mapValues { (_, value: String) -> "$value!" }

http://kotlinlang.org/docs/reference/multi-declarations.html#destructuring-in-lambdas-since-11

3

After auto conversion

Before:

.flatMap<String> { it.myStream }

After:

.flatMap { it.myStream }

http://kotlinlang.org/docs/reference/lambdas.html

After auto conversion

Before:

.map { (_, _, arg) ->action(arg) }

After:

.map { action(it.arg) }

http://kotlinlang.org/docs/reference/lambdas.html

3

typealias NodeSet = Set<Network.Node>

typealias MyHandler = (Int, String, Any) -> Unit

class A {

    inner class Inner

}

class B {

    inner class Inner

}

typealias AInner = A.Inner

typealias BInner = B.Inner

http://kotlinlang.org/docs/reference/type-aliases.html#type-aliases

3

Sealed Classes

https://kotlinlang.org/docs/reference/sealed-classes.html

3

Infix notation

https://kotlinlang.org/docs/reference/functions.html#infix-notation

3

Operator overloading

http://kotlinlang.org/docs/reference/operator-overloading.html

3

Inline Functions

https://kotlinlang.org/docs/reference/functions.html#inline-functions

https://kotlinlang.org/docs/reference/inline-functions.html

3

Extensions

Extension Functions

Extensions are resolved statically

Nullable Receiver

Extension Properties

Companion Object Extensions

Scope of Extensions

Declaring Extensions as Member

Motivation

https://kotlinlang.org/docs/reference/extensions.html

3

Calling multiple methods on an object instance ('with')

Before:

obj.objMethod1()

obj.objMethod2()

After:

with (obj) {

    objMethod1()

    objMethod2()

}

obj.objMethod1();

obj.objMethod2();

https://kotlinlang.org/docs/reference/idioms.html#calling-multiple-methods-on-an-object-instance-with

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/with.html

3

Builder-style usage of methods that return Unit

Before:

val obj = Obj()

    obj.objMethod1()

    obj.objMethod2()

After:

val obj = Obj().apply {

    objMethod1()

    objMethod2()

}

https://kotlinlang.org/docs/reference/idioms.html#builder-style-usage-of-methods-that-return-unit

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/apply.html

3

Before:

   fun save(aId: Long, …) {

        val entity = MyEntity().apply {

            id = aId

        }

        try {

            mRepository.save (entity)

        } catch (e: Exception) {

            throw AppException.getExceptionToPropagate(e)        

       }

 }

After:

   fun save(aId: Long, …) {

        MyEntity().run {

            id = aId

        try {

            mRepository.save (this)

        } catch (e: Exception) {

            throw AppException.getExceptionToPropagate(e)        

       }

  }

}

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/apply.html

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/run.html

3

Suppresses the given compilation warnings in the annotated element.

@Suppress("unused")

@SuppressWarnings("unused")

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-suppress/

Auto-conversion removes @SuppressWarnings("unused") instead of replacing @SuppressWarnings with @Suppress

3

Try is an expression

Before:

    override fun getEntity(aId: Long): Optional<MyEntity> {

            try {

                return Optional.ofNullable(mRepository.findOne(aId))

            } catch (e: Exception) {

                throw AppException.getExceptionToPropagate(e)

            }

  }

After:

    override fun getEntity(aId: Long) =

            try {

                Optional.ofNullable(mRepository.findOne(aId))

            } catch (e: Exception) {

                throw AppException.getExceptionToPropagate(e)

            }

https://kotlinlang.org/docs/reference/exceptions.html#try-is-an-expression

3

Type-Safe Builders and DSL

https://kotlinlang.org/docs/reference/type-safe-builders.html

3

Delegation

Class Delegation

Before:

class (override val type: A.Type,

                @field:BehavioralPattern.Delegation.Delegate

                private val mAddress: AddressA) : A {

    override val name: String

        @BehavioralPattern.Delegation

        get() = mAddress.name

    override val port: Int

        @BehavioralPattern.Delegation

        get() = mAddress.port

    override fun equals(other: Any?): Boolean {

        if (this === other) return true

        if (other == null || javaClass != other.javaClass) return false

        val  = other as

        return mAddress == .mAddress

    }

    override fun hashCode(): Int {

        return mAddress.hashCode()

    }

}

After:

class (override val type: A.Type,

                @field:BehavioralPattern.Delegation.Delegate

                private val mAddress: AddressA) : A, AddressA by mAddress

http://kotlinlang.org/docs/reference/delegation.html

3

Delegated Properties

Standard Delegates

Lazy

Observable

Storing Properties in a Map

Local Delegated Properties

Property Delegate Requirements

Translation Rules

Providing a delegate

http://kotlinlang.org/docs/reference/delegated-properties.html

3

Coroutines

https://github.com/Kotlin/kotlinx.coroutines

3

Reflection

Function References

https://kotlinlang.org/docs/reference/reflection.html

Stage

Problem

Solution/Workaround

1

After auto conversion

double literals like 0 into 0.toDouble()

Change to 0.0

2

After auto conversion:

Spring boot application can’t start - Configuration problem: @Configuration class 'Application' may not be final. Remove the final modifier to continue.

Or

Spring bean processor doesn’t process nested @Configuration class (f.e. located in @SpringBootTest class).

Note: plugin kotlin-maven-allopen is configured, but error still appear.

add open class, open fun, open val to @Configuration class.

Change Application.kt

from

object Application {

    private val log = LoggerFactory.getLogger(Application::class.java)

    @JvmStatic

    fun main(args: Array<String>) {

        log.info("Started")

        val app = SpringApplication(Application::class.java)

        app.run(*args)

    }

}

to

open class Application

private val log = LoggerFactory.getLogger(Application::class.java)

fun main(args: Array<String>) {

    log.info("Started")

    val app = SpringApplication(Application::class.java)

    app.run(*args)

}

2

Configuration problem: @Bean method 'getMyBean' must not be private or final; change the method's modifiers to continue

Change @Bean methods in @Configuration classes

from

internal fun getMyBean (

to

open internal fun getMyBean (

2

After auto conversion:

    private object QualifierName {

        private val VALUE = "VALUE"

    }

@Bean

@Qualifier(QualifierName.VALUE)

Use Compile-Time Constants

const val QualifierName_VALUE = "VALUE"

@Bean

@Qualifier(QualifierName_VALUE)

2

    @SuppressWarnings("unused") doesn’t suppress warning

Ignore warning

2

After auto conversion

No qualifying bean of type 'Type' available: expected single matching bean but found 2: getMyBean, getMyBean$com_app

Bean names that are generated by default in main and test class become different:

main: getMyBean$com_app,

test: getMyBean

Remove internal modifier to avoid getMyBean$com_app.

2

Note: Remove internal modifier everywhere to avoid different problems with names like getMyBean$com_app

2

After auto conversion

Incorrect expression

Optional.ofNullable(getNullableValue()).map<Long>(Function<Type, Long> { it.getCountry() }).orElse(111L).toInt()

Change stream sequence

from

when

Optional.ofNullable(getNullableValue()).map<Long>(Function<Type, Long> { it.getCountry() }).orElse(111L).toInt()

to (with Optional)

Optional.ofNullable(getNullableValue()).map{it.country}.orElse(111L)?.toInt()

or  to (Kotlin null-safety instead of Optional)

getNullableValue()?.country ?: 111L

2

After auto conversion

Incorrect lambda expressions like:

.map<Stream<Entity>>(Function<Entity, Stream<Entity>> { Stream.of(it) })

.map { Stream.of(it) }

2

After auto conversion

Warning on {@link getProperty}

Change [getProperty] to [property]

2

After auto conversion

Type getABName(); became val abName: Type

and is accessible from Java as getAbName instead of getABName

Migrate code from getABName to getAbName.

2

Note: Avoid identifiers that don’t follow Java default naming convention.