SlideShare a Scribd company logo
Kotlin lang - advanced
(Android projects)
Bartosz Kosarzycki - StxNext Lightning Talks - Mar 11, 2016
talented developers | flexible teams | agile experts
Kotlin basics - view here
Stable 1.0 version is available
from Feb 15, 2016
Kotlin lang - advanced
1. Live templates
2. Enum translation
3. Calling extension functions from Kotlin/Java
4. Constructors with backing fields
5. Warnings
6. F-bound polymorphism
7. Variance (Covariance/Contravariance)
8. Variance comparison in Kotlin/Java/Scala
9. Annotation processing - KAPT
10. SAM conversions
11. Type equality
12. Lambda vs Closure
13. Reified generics
14. Fluent interfaces
15. Infix notation
16. Static extension methods in Kotlin
17. Generic types
18. Sealed classes
19. Dokka - documentation in Kotlin
20. J2K converter
21. Real-world example
22. Reflection
AGENDA
Live templates
exfun
fun Any.f(): Unit {
}
closure
{ x -> x }
iter
for (i in iterable) {
}
● let’s start with something
simple - templates
Live templates
exvar
var Any.v: Any
get() {
}
set(value) {
}
main
fun main(args: Array<String>) {
}
inn
if (i != null) {
}
Enum translation
Kotlin
enum class SliderActivityType
private constructor(val title: Int) {
PORTFOLIO(R.string.portfolio),
TEAM(R.string.team)
}
Java
public enum SliderActivityType {
PORTFOLIO(R.string.portfolio),
TEAM(R.string.team);
private final int title;
SliderActivityType(int title) {
this.title = title;
}
public int getTitle() {
return title;
}
}
● easier to read
● more concise
● help to avoid typos and boilerplate code
In Kotlin translated enums are:
Calling extension
functions
Get app-version ext. function:
@file:JvmName("ActivityUtil") //@file:JvmMultifileClass
package com.stxnext.stxinsider.util
fun Activity.getAppVersion(activity: Activity): String {
try {
val manager = activity.packageManager
val info = manager.getPackageInfo(activity.packageName, 0).versionName
} catch (e: PackageManager.NameNotFoundException) { /* ignore */ }
return "0.0.0"
}
Kotlin call:
versionTextView.setText(getAppVersion(this))
Java call:
versionTextView.setText(ActivityUtil.getAppVersion(MainActivity.this,
MainActivity.this));
Constructors with
backing fields
● using constructors with backing fields in
a proper way saves a lot of boiler-plate
code
“Java-style”
kotlin code:
class TeamCategoryFragment : Fragment() {
internal val TAG = TeamCategoryFragment::class.simpleName
lateinit var teamCategoryHeader: TeamCategoryHeader
lateinit var teamListRecyclerView: RecyclerView
fun teamCategoryHeader (teamCategoryHeader: TeamCategoryHeader): TeamCategoryFragment {
this.teamCategoryHeader = teamCategoryHeader
return this
}
override fun onCreateView(): View? {
val view = inflater!!.inflate(R.layout.fragment_layout, container, false)
teamListRecyclerView = view.findViewById(R.id.fragment_list) as RecyclerView
return view;
}
}
class TeamCategoryFragment (var teamCategoryHeader: TeamCategoryHeader) : Fragment() {
internal val TAG = TeamCategoryFragment::class.simpleName
lateinit var teamListRecyclerView: RecyclerView
override fun onCreateView(): View? {
val view = inflater!!.inflate(R.layout.fragment_layout, container, false)
teamListRecyclerView = view.findViewById(R.id.fragment_list) as RecyclerView
return view;
}
}
Contructor
with backing
field
Warnings
Checks:
Full list of supression contants:
https://github.com/JetBrains/kotlin/blob/master/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java
@Suppress("UNCHECKED_CAST")
@Suppress("CANNOT_CHECK_FOR_ERASED")
@Suppress("SENSELESS_COMPARISON")
@Suppress("GENERIC_THROWABLE_SUBCLASS")
etc.
F-bound
polymorphism
Kotlin:
interface Movable {
Movable move(int x, int y);
}
class Car implements Movable {
@Override
public Movable move(int x, int y) {
return this;
}
}
public class FBoundedExample {
Movable moveMeOneInch (Movable m)
{ return m.move(1,1); }
<T extends Movable > T moveMeOneInchFBound (T m)
{ m.move( 1,1); return m; }
Car car1 = (Car) moveMeOneInch( new Car());
Car car2 = moveMeOneInchFBound( new Car());
}
Java equivalent:
interface Movable {
fun move(x: Int, y: Int): Movable { return this }
}
class Car : Movable
fun moveMeOneInch(m: Movable): Movable {
return m.move(1, 1)
}
fun <T : Movable> moveMeOneInchFBound(m: T): T {
m.move(1, 1)
return m
}
val car1:Car = moveMeOneInch(Car()) as Car
val car2:Car = moveMeOneInchFBound(Car())
● in moveMeOneInch() we have to do
unsafe casting to (Car)
● in moveMeOneInchFBound() no
casting in necessary
● Kotlin&Java work the same but the
syntax is differrent
(<T : Movable> vs <T extends Movable>
● upper-bound generics
no casting necessary
Covariance
Notes:
● Cat is a subclass of Animal
● Animal shelter puts animals and
gets them for adoption
● We want to implement
CatShelter and get&put Cats
open class Animal
class Cat : Animal()
open class AnimalShelter {
open fun getAnimalForAdoption() : Animal {
return Animal()
}
open fun putAnimal(animal : Animal) {
}
}
Base class:
class CatShelter : AnimalShelter() {
//covariant method return type
override fun getAnimalForAdoption(): Cat {
return Cat()
}
//covariant method argument type - NOT POSSIBLE
override fun putAnimal(animal: Cat) { //overrides nothing
super.putAnimal(animal)
}
}
Derived class:
Covariance
Notes:
● Cat is a subclass of Animal
● Animal shelter puts animals and
gets them for adoption
● We want to implement
CatShelter and get&put Cats
open class Animal
class Cat : Animal()
open class AnimalShelter2<in T> {
open fun getAnimalForAdoption() : Animal {
return Animal()
}
open fun putAnimal(animal : T) {
}
}
Base class:
class CatShelter2 : AnimalShelter2<Cat>() {
//covariant method return type
override fun getAnimalForAdoption(): Cat {
return Cat()
}
//covariant method argument type
override fun putAnimal(animal: Cat) {
super.putAnimal(animal)
}
}
Derived class:
Contravariance
Notes:
● Cat is a subclass of Animal
● Animal shelter puts animals and
gets them for adoption
● We want to implement
CatShelter and get&put Cats
open class Animal
class Cat : Animal()
abstract class AnimalShelter3<out T> {
abstract fun getAnimalForAdoption() : T
open fun putAnimal(animal : Animal) { }
}
Base class:
class CatShelter3 : AnimalShelter3<Any>() {
//contravariant method return type
override fun getAnimalForAdoption(): Any {
return Cat()
}
}
Derived class:
Covariance
Preserve List<T> type
safety in Java:
List<String> strs = new ArrayList<String>();
List<Object> objs = strs; // Java prohibits this! (Incompatible types)
objs.add(1); //Cannot cast exception if compilation allowed the above line
● generic types in Java are invariant
List<String> is not a subtype of List<Object>
● wildcard types in Java allow method
argument type to be covariant
Collection<String> is a subtype of Collection<? extends Object>
(extends bound/upper-bound)
interface Collection<E> ... {
void addAll(Collection<? extends E> items);
}
which is why addAll() method
from Collection<E> is:
● doesn’t have wildcard
types
● uses declaration-site
variance and type
projections instead
● star-projections are
present
● generic constraints
(upper-bounds) are
possible
KOTLIN:
use-site variance
Variance
comparison
JAVA
● uses wildcards to express variance
● wildcards (use-site variance) are very
expressive but also hard to understand
and inconvienient for programmers
KOTLIN
● developed mixed-site variance system in
collaboration with Ross Tate
● combination of definition-site and use-site
variance that avoids the failings of wildcards
C<? extends T>
covariant instantiation of C
i.e.
“C-of-some-subtype-of-T”.
Example:
fun <T : Comparable<T>> sort(list: List<T>) {}
open class AnimalShelter2< in T> {}
open class AnimalShelter2< out T> {}
Annotation
processing
Implementation state:
● old implementation: kapt worked by intercepting
communication between annotation processors and javac,
and added already-compiled Kotlin classes on top of the
Java classes
● new implementation of KAPT: generates stubs of Kotlin classes
before running javac and llows the usage of APT based
libraries we already have at our current java stack
KAPT
kapt {
generateStubs = true
}
dependencies {
kapt 'com.google.dagger:dagger-compiler:2.0.2'
}
Example config:
● JSR 269 Annotation
Processing available in Kotlin
since M12
● Dagger 2 works :)
● DBFlow works
SAM
conversions
SAM call:
● function literals can be converted into implementations
of Java interfaces with a single non-default method
● the parameter types of the interface method must match
the parameter types of the Kotlin function
Lambda call:
mInsiderApiService.getTeamsAsync({ list ->
list.forEach { item -> print(item.description) } },
{ /* do nothing on error */ } )
versionTextView.setOnClickListener(
View.OnClickListener { print("Message content") } )
executor.execute(Runnable {
println("This runs in a thread pool") })
mInsiderApiService.getTeamsAsync(
object : Callback<List<SliderItem>> {
override fun onResponse(
p0: Call<List<SliderItem>>?,
response: Response<List<SliderItem>>?) {
/* something */ }
override fun onFailure(
p0: Call<List<SliderItem>>?,
p1: Throwable?) { /* something */ }
})
Java interface call:
Type equality
Checking type equality
BaseClass
TallItemView
if (this instanceof TallItemView) { .... }
// instanceof makes it very easy to be asymmetric
if (this.getClass()
.equals(TallItemView.class) ) { .... }
Java
if (this.javaClass
.isAssignableFrom(TallItemView::class.java) )
Kotlin
Referential equality
referential equality is checked by the ===
operation
Structural equality
structural equality is checked by the ==
operation
== is translated to: a?.equals(b) ?: (b === null)
a == null is translated to: a === null
if a is not null, it calls the equals(Any?)
function, otherwise b === null
Lambda vs
Closure
LAMBDA CLOSURE
● language construct
● a syntax for
anonymous function
● can be assigned to a
variable
● “closes over” the
environment in which
it was defined
● lambda which
references fields
external to its body
● function which is
evaluated in its own
environment
Reified generics
● in Java generic type parameters are not
reified: they are not available at runtime
● for inline functions
(inserting the function code at the address of each function call)
● safe casting of generic types
● problem comes from type-erasure
class MyClass<T> {
private final T o;
public MyClass() {
this.o = new T(); //type parameter ‘T’ cannot be instantiated directly
}
}
Example (Java)
public class MyClass2<T> {
@SuppressWarnings("unchecked")
public T doSomething() {
return (T) new MyClass(); //unchecked cast
}
}
class MyClass2 {
inline fun <reified T> doSomething() : T {
return MyClass() as T;
}
}
class MyClass
Kotlin
Fluent interfaces
Kotlin:
https://plugins.jetbrains.com/plugin/7903
Fluent setter generator plugin for Android Studio:
(JAVA)
public SampleActivity firstVariable(int firstVariable) {
this.firstVariable = firstVariable;
return this;
}
public SampleActivity secondVariable(int secondVariable) {
this.secondVariable = secondVariable;
return this;
}
● almost like an internal DSL
● ideal for filtering, creating,
customizing etc.
● used for model classes
Java:
Snakbar snack = Snackbar
.make(mainView , "Sample snackbar" , Snackbar.LENGTH_LONG)
.setAction( "Undo", undoClickListener) ;
Fluent interface example:
class Person(val name: String) {
val parents : List<String> = arrayListOf()
constructor(name: String, parent: String)
: this(name) {
parents.plus(parent)
}
fun parent(parent: String): Person {
parents.plus(parent); return this
}
}
Fluent interfaces /**
* Fluent sort
*/
fun <T : kotlin.Comparable<T>> kotlin.collections.MutableList<T>.
sortList(): MutableList<T> {
sort()
return this
}
/**
* For-each fluent interface
*/
fun <T : kotlin.Comparable<T>> kotlin.collections.MutableList<T>.
forEachList(action: (T) -> kotlin.Unit): MutableList<T> {
for (elem in this)
action.invoke(elem)
return this
}
Additional functions:
Fluent lists example:
val list = listOf(1, 2, 3, 4, 5, 6, 7, 8)
list .forEach { println(it) }
list forEachLoop { println(it) }
/**
* In-place forEach loop (discouraged in 1.0 release)
*/
infix fun <T> kotlin.collections.Iterable<T>
.forEachLoop(action: (T) -> kotlin.Unit): kotlin.Unit {
this.forEach { action }
}
val outList = list
.filter { it < 100 }
.filterNot { it == 1 }
.toMutableList()
.sortList()
.forEachList { it + 1 }
.filter { it % 2 == 0 }
.first()
//result: 2
Infix notation
infix fun Int.minus(x: Int): Int {
return this.minus(x)
}
infix extension function:
val result = 1 minus 2
println(3 minus 4)
type isPortfolio { println("Do something") }
type isTeam { println("Do something else") }
infix fun SliderActivityType.isPortfolio( execClosure : () -> Unit ) {
if (this.equals(SliderActivityType.PORTFOLIO))
execClosure.invoke()
}
infix fun SliderActivityType.isTeam( execClosure : () -> Unit ) {
if (this.equals(SliderActivityType.TEAM))
execClosure.invoke()
}
this displayToast "This is a message"
infix fun Activity.displayToast(txt : String) {
Toast.makeText(this, txt, Toast.LENGTH_SHORT).show()
}
● only one method
argument
● function literal can be
passed outside the
parentheses
Infix notation
if (this isGranted Manifest.permission.READ_CONTACTS) {
//do something here
}
infix fun Activity.isGranted(permissionStr : String) :
Boolean {
if (ContextCompat.checkSelfPermission(this,
permissionStr) !=
PackageManager.PERMISSION_GRANTED)
return false
return true
}
Handle Android
permissions check:
this loge "I really don't like errors"
infix fun Activity.loge(txt : String) {
Log.e(this.javaClass.simpleName, txt)
}
Log errors:
Static extension
methods
fun Util.isDeviceOnline(context: Context): Boolean {
val connMgr = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkInfo = connMgr.activeNetworkInfo
return networkInfo != null && networkInfo.isConnected
}
fun Activity.isDeviceOnline(context: Context) = { Util().isDeviceOnline(context) }
fun OkHttpClient.isDeviceOnline(context: Context) = { Util().isDeviceOnline(context) }
Workaround (extension method for multiple classes):
http://stackoverflow.com/questions/28210188/static-extension-methods-in-kotlin
● In Kotlin 1.0 there is no possibility to add a static extension method
Generic types
Create generic object instance:
● in JVM generic types are lost due to type erasure
class MyClass<T> {
private final T o;
public MyClass() {
this.o = new T(); //type parameter ‘T’ cannot be instantiated directly
}
}
Generic types
val bindFunc = { baseView: FrameLayout , item: ListItem , position: Int , clickListener: View.OnClickListener ->
val nameTextView = baseView.findViewById(R.id. item_simple_list_main_header) as TextView
nameTextView. text = item.title
baseView.setOnClickListener(clickListener)
}
val adapter = SimpleItemListAdapter<ListItem , ListItemView<ListItem>>(onClickFunc ,
{ ListItemView <ListItem> (R.layout. item_simple_list, bindFunc , baseContext , null /* attrs */ ) } );
Create generic object instance:
● in JVM generic types are lost due to type erasure
override fun onCreateItemView(parent: ViewGroup, viewType: Int): TView {
val view = factory()
return view as TView
}
//not really convenient
override fun onCreateItemView(parent: ViewGroup, viewType: Int, classParam : Class<T>): T {
val v: T = classParam.constructors[0].newInstance(mContext, null) as T
return v as T
}
Sealed classes
sealed class Pet(val name: String) {
class Dog(name: String): Pet(name)
class Cat(name: String): Pet(name)
}
Sealed class:
fun Pet.saySomething(): String {
return when (this) {
is Dog -> "woof"
is Cat -> "meow"
}
}
● algebraic data type - i.e. composite data
type which is formed by combining other
types
● sealed classes - instead of open classes
with private constructors
● “when” statement without “else” clause
● “Pet” cannot have other subclasses than
“Dog” and “Cat”
● since M13
// private constructor to prevent creating more subclasses outside
open class Pet private(val name: String) {
class Dog(name: String): Pet(name)
class Cat(name: String): Pet(name)
}
Dokka
What is dokka:
KDoc documentation:
● similar do Javadoc
● supports stale Javadoc out of the box
● markdown support included
/**
* # Beacon SDK initialization
*
* This method registers 3 beacons with IDs taken from Estimote Cloud.
* Invoke this method in [onCreate].
*
* ## Showcase demo
*
* Steps:
* * Grant application bluetooth, GPS and WiFi permissions
* * Wait for about 1 minute (beacons broadcast in 0.1 ~ 2.0 sec intervals)
* * Snackbar should appear on the app's main activity
*
*/
private fun initializeNearables() { ….. }
● generates documentation in
html/markdown/javadoc
● maintained by Jetbrains
● generated from
gradle/maven/ant
● standalone executable jar
available
● [ref] instead of @see ref
● https://github.com/Kotlin/dokka
Dokka
Standalone jar:
● java -jar dokka-fatjar.jar ./src/
buildscript {
dependencies {
classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.7"
}
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
dokka {
outputFormat = 'html' //'markdown', 'javadoc'
outputDirectory = "$buildDir/kotlindocs"
}
Dokka gradle plugin:
HTML output with css styles:
J2K converter
Simple Activity
conversion:
Call Java 2 Kotlin converter:
● There is no Kotlin 2 Java as for now
public class SampleActivity extends Activity {
@Override
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
class SampleActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
Real-world
example
Method count:
Library Method count
cardview-v7/23.1.0 872
play-services-maps 1369
play-services-base 700
okhttp 1463
dagger-compiler 1582
kotlin-stdlib 2411
kotlin-runtime 705
support-vector-drawable 635
butterknife 635
okio 712
(617 after proguarding)
LoC: 1857 kotlin + 503 java lines
Compilation time (debug): 45.584 sec (6 sec incremental)
Compilation time (release): 44.142 sec
(proguard + zipaligning)
Intel® Core™ i5-3470 CPU @ 3.20GHz × 4
8 GB RAM 1333 MHz, Ubuntu 15.10, Linux kernel 4.4.2-040402-generic
Real-world
example
Method count:
Library Method count
joda-time 1707
converter-gson 236
com.google.android.gms 1912
kotterknife 456
com.google.dagger 290
retrofit-2.0.0-beta2 593
com.android.support/design 1017
com.android.support/recyclerview-v7 1579
LoC: 1857 kotlin + 503 java lines
Compilation time (debug): 47.135 sec (6 sec incremental)
Compilation time (release): 53.173 sec
(proguard + zipaligning)
Mac Mini late 2014, SSD 256 GB drive USB-3.0
2.6 GHz Intel Core i5
8 GB 1600 MHz DDR3, OsX El Capitan 10.11.2 (15C50)
Try it yourself - STXInsider example project:
https://github.com/kosiara/stx-insider
Reflection
Calling reflection:
Text text text
dependencies {
compile 'org.jetbrains.kotlin:kotlin-reflect:1.0.0'
}
● Reflection is moved into separate *.jar which reduces the
size of runtime library
val javaMethod = util.javaClass.methods[0]
val javaConstructor = util.javaClass.constructors[0]
val utilInstance = javaConstructor.newInstance()
javaMethod.invoke(utilInstance)
Java reflection in Kotlin:
val classRef: KClass<Util> = Util::class
val constructor = classRef.constructors.first()
val method = classRef.functions.first()
val util = constructor.call()
method.call(util)
val aFun = classRef.functions
.filter { it.name.contains("aaa") }.first()
val bFun = classRef.functions.filter {
it.parameters.size == 1
}.first()
aFun.call(util)
bFun.call(util)
Resources
RESOURCES:
● https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
● https://kotlinlang.org/docs/reference/generics.html
● http://www.cs.cornell.edu/~ross/publications/mixedsite/mixedsite-tate-fool13.pdf
● http://blog.jetbrains.com/kotlin/2015/06/better-annotation-processing-supporting-stubs-in-kapt/
● https://yanniss.github.io/varj-ecoop12.pdf
● https://schneide.wordpress.com/2015/05/11/declaration-site-and-use-site-variance-explained/
● http://stackoverflow.com/questions/4231305/how-does-javas-use-site-variance-compare-to-cs-declaration-site-variance
● http://www.cs.cornell.edu/~ross/publications/tamewild/
● http://stackoverflow.com/questions/26507099/lambda-expressions-in-kotlin
● http://gafter.blogspot.com/2006/11/reified-generics-for-java.html
● http://stackoverflow.com/questions/1927789/why-should-i-care-that-java-doesnt-have-reified-generics
● https://github.com/KeepSafe/dexcount-gradle-plugin
● http://blog.jetbrains.com/kotlin/2015/09/kotlin-m13-is-out/
● http://blog.jetbrains.com/kotlin/2011/10/dsls-in-kotlin-part-1-whats-in-the-toolbox-builders/
● http://stackoverflow.com/questions/28210188/static-extension-methods-in-kotlin
● http://antonioleiva.com/collection-operations-kotlin/
Thankyou!
Bartosz Kosarzycki
bartosz.kosarzycki@stxnext.pl
Twitter: @bkosarzycki
Online compiler:
http://try.kotlinlang.org/
STXInsider example project in Kotlin:
https://github.com/kosiara/stx-insider

More Related Content

PDF
Kotlin in action
PDF
ADG Poznań - Kotlin for Android developers
PDF
Kotlin Developer Starter in Android projects
PDF
Kotlin advanced - language reference for android developers
PDF
Kotlin hands on - MorningTech ekito 2017
PDF
The Kotlin Programming Language, Svetlana Isakova
PDF
Develop your next app with kotlin @ AndroidMakersFr 2017
PDF
Kotlin, smarter development for the jvm
Kotlin in action
ADG Poznań - Kotlin for Android developers
Kotlin Developer Starter in Android projects
Kotlin advanced - language reference for android developers
Kotlin hands on - MorningTech ekito 2017
The Kotlin Programming Language, Svetlana Isakova
Develop your next app with kotlin @ AndroidMakersFr 2017
Kotlin, smarter development for the jvm

What's hot (19)

PDF
Kotlin cheat sheet by ekito
PDF
Kotlin for Android - Vali Iorgu - mRready
PPTX
PDF
Introduction to kotlin for android app development gdg ahmedabad dev fest 2017
PDF
Introduction to kotlin
PPTX
Introduction to kotlin + spring boot demo
PDF
Little Helpers for Android Development with Kotlin
PDF
Swift and Kotlin Presentation
PDF
scala.reflect, Eugene Burmako
PDF
Taking Kotlin to production, Seriously
PDF
Java Keeps Throttling Up!
PDF
Kotlin boost yourproductivity
PPTX
Building native Android applications with Mirah and Pindah
PDF
Javantura v2 - All Together Now - making Groovy and Scala sing together - Din...
PDF
Kotlin - Better Java
PDF
Kotlin Bytecode Generation and Runtime Performance
ODP
Ast transformations
ODP
AST Transformations
PDF
Android antipatterns
Kotlin cheat sheet by ekito
Kotlin for Android - Vali Iorgu - mRready
Introduction to kotlin for android app development gdg ahmedabad dev fest 2017
Introduction to kotlin
Introduction to kotlin + spring boot demo
Little Helpers for Android Development with Kotlin
Swift and Kotlin Presentation
scala.reflect, Eugene Burmako
Taking Kotlin to production, Seriously
Java Keeps Throttling Up!
Kotlin boost yourproductivity
Building native Android applications with Mirah and Pindah
Javantura v2 - All Together Now - making Groovy and Scala sing together - Din...
Kotlin - Better Java
Kotlin Bytecode Generation and Runtime Performance
Ast transformations
AST Transformations
Android antipatterns
Ad

Similar to Kotlin Advanced - language reference for Android developers (20)

PDF
Intro to Kotlin
PDF
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
PDF
Kotlin for Android Developers
PPTX
K is for Kotlin
PDF
Coding for Android on steroids with Kotlin
PPTX
Kotlin Language Features - A Java comparison
PDF
A quick and fast intro to Kotlin
PDF
Kotlin Introduction with Android applications
PDF
Android 101 - Building a simple app with Kotlin in 90 minutes
PDF
Summer of Tech 2017 - Kotlin/Android bootcamp
PDF
Having Fun with Kotlin Android - DILo Surabaya
PPTX
KotlinForJavaDevelopers-UJUG.pptx
PPTX
Why kotlininandroid
PDF
Kotlin: forse è la volta buona (Trento)
PPTX
Android & Kotlin - The code awakens #03
PPTX
從零開始學 Android
PDF
Kotlin intro
PPTX
Kotlin
PPTX
Kotlin – the future of android
Intro to Kotlin
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
Kotlin for Android Developers
K is for Kotlin
Coding for Android on steroids with Kotlin
Kotlin Language Features - A Java comparison
A quick and fast intro to Kotlin
Kotlin Introduction with Android applications
Android 101 - Building a simple app with Kotlin in 90 minutes
Summer of Tech 2017 - Kotlin/Android bootcamp
Having Fun with Kotlin Android - DILo Surabaya
KotlinForJavaDevelopers-UJUG.pptx
Why kotlininandroid
Kotlin: forse è la volta buona (Trento)
Android & Kotlin - The code awakens #03
從零開始學 Android
Kotlin intro
Kotlin
Kotlin – the future of android
Ad

More from STX Next (15)

PDF
Scrum Master - Breakout session.
PDF
Transformation to agile.
PDF
What scrum masters and product owners should know about software quality and ...
PDF
The essence hidden from the eye.
PDF
Why to nearshore in Central Europe?
PDF
Is there a common pattern in fixing projects?
PDF
Behave automatically: (Almost) Effortless feature testing
PDF
Time to React!
PDF
Salary Formula - bumpy road to transparency.
PDF
Software Quality Visualization
PDF
Discover, Define, Deliver - a workflow to create successful digital products.
PDF
Zwinność procesu rekrutacyjnego w branży IT
PDF
STX Next - Scrum Development Process Overview
PDF
STX Next - Meet Us
PDF
Group Process by Example - a PO’s and SM’s perspective
Scrum Master - Breakout session.
Transformation to agile.
What scrum masters and product owners should know about software quality and ...
The essence hidden from the eye.
Why to nearshore in Central Europe?
Is there a common pattern in fixing projects?
Behave automatically: (Almost) Effortless feature testing
Time to React!
Salary Formula - bumpy road to transparency.
Software Quality Visualization
Discover, Define, Deliver - a workflow to create successful digital products.
Zwinność procesu rekrutacyjnego w branży IT
STX Next - Scrum Development Process Overview
STX Next - Meet Us
Group Process by Example - a PO’s and SM’s perspective

Recently uploaded (20)

PPTX
MYSQL Presentation for SQL database connectivity
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
KodekX | Application Modernization Development
PDF
Modernizing your data center with Dell and AMD
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PPTX
Cloud computing and distributed systems.
PPT
Teaching material agriculture food technology
PDF
Encapsulation theory and applications.pdf
PPTX
A Presentation on Artificial Intelligence
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
PDF
Approach and Philosophy of On baking technology
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
MYSQL Presentation for SQL database connectivity
The Rise and Fall of 3GPP – Time for a Sabbatical?
KodekX | Application Modernization Development
Modernizing your data center with Dell and AMD
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Cloud computing and distributed systems.
Teaching material agriculture food technology
Encapsulation theory and applications.pdf
A Presentation on Artificial Intelligence
NewMind AI Monthly Chronicles - July 2025
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
Approach and Philosophy of On baking technology
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Building Integrated photovoltaic BIPV_UPV.pdf
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Digital-Transformation-Roadmap-for-Companies.pptx
Reach Out and Touch Someone: Haptics and Empathic Computing
20250228 LYD VKU AI Blended-Learning.pptx
“AI and Expert System Decision Support & Business Intelligence Systems”

Kotlin Advanced - language reference for Android developers

  • 1. Kotlin lang - advanced (Android projects) Bartosz Kosarzycki - StxNext Lightning Talks - Mar 11, 2016 talented developers | flexible teams | agile experts
  • 2. Kotlin basics - view here Stable 1.0 version is available from Feb 15, 2016
  • 3. Kotlin lang - advanced 1. Live templates 2. Enum translation 3. Calling extension functions from Kotlin/Java 4. Constructors with backing fields 5. Warnings 6. F-bound polymorphism 7. Variance (Covariance/Contravariance) 8. Variance comparison in Kotlin/Java/Scala 9. Annotation processing - KAPT 10. SAM conversions 11. Type equality 12. Lambda vs Closure 13. Reified generics 14. Fluent interfaces 15. Infix notation 16. Static extension methods in Kotlin 17. Generic types 18. Sealed classes 19. Dokka - documentation in Kotlin 20. J2K converter 21. Real-world example 22. Reflection AGENDA
  • 4. Live templates exfun fun Any.f(): Unit { } closure { x -> x } iter for (i in iterable) { } ● let’s start with something simple - templates
  • 5. Live templates exvar var Any.v: Any get() { } set(value) { } main fun main(args: Array<String>) { } inn if (i != null) { }
  • 6. Enum translation Kotlin enum class SliderActivityType private constructor(val title: Int) { PORTFOLIO(R.string.portfolio), TEAM(R.string.team) } Java public enum SliderActivityType { PORTFOLIO(R.string.portfolio), TEAM(R.string.team); private final int title; SliderActivityType(int title) { this.title = title; } public int getTitle() { return title; } } ● easier to read ● more concise ● help to avoid typos and boilerplate code In Kotlin translated enums are:
  • 7. Calling extension functions Get app-version ext. function: @file:JvmName("ActivityUtil") //@file:JvmMultifileClass package com.stxnext.stxinsider.util fun Activity.getAppVersion(activity: Activity): String { try { val manager = activity.packageManager val info = manager.getPackageInfo(activity.packageName, 0).versionName } catch (e: PackageManager.NameNotFoundException) { /* ignore */ } return "0.0.0" } Kotlin call: versionTextView.setText(getAppVersion(this)) Java call: versionTextView.setText(ActivityUtil.getAppVersion(MainActivity.this, MainActivity.this));
  • 8. Constructors with backing fields ● using constructors with backing fields in a proper way saves a lot of boiler-plate code “Java-style” kotlin code: class TeamCategoryFragment : Fragment() { internal val TAG = TeamCategoryFragment::class.simpleName lateinit var teamCategoryHeader: TeamCategoryHeader lateinit var teamListRecyclerView: RecyclerView fun teamCategoryHeader (teamCategoryHeader: TeamCategoryHeader): TeamCategoryFragment { this.teamCategoryHeader = teamCategoryHeader return this } override fun onCreateView(): View? { val view = inflater!!.inflate(R.layout.fragment_layout, container, false) teamListRecyclerView = view.findViewById(R.id.fragment_list) as RecyclerView return view; } } class TeamCategoryFragment (var teamCategoryHeader: TeamCategoryHeader) : Fragment() { internal val TAG = TeamCategoryFragment::class.simpleName lateinit var teamListRecyclerView: RecyclerView override fun onCreateView(): View? { val view = inflater!!.inflate(R.layout.fragment_layout, container, false) teamListRecyclerView = view.findViewById(R.id.fragment_list) as RecyclerView return view; } } Contructor with backing field
  • 9. Warnings Checks: Full list of supression contants: https://github.com/JetBrains/kotlin/blob/master/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @Suppress("UNCHECKED_CAST") @Suppress("CANNOT_CHECK_FOR_ERASED") @Suppress("SENSELESS_COMPARISON") @Suppress("GENERIC_THROWABLE_SUBCLASS") etc.
  • 10. F-bound polymorphism Kotlin: interface Movable { Movable move(int x, int y); } class Car implements Movable { @Override public Movable move(int x, int y) { return this; } } public class FBoundedExample { Movable moveMeOneInch (Movable m) { return m.move(1,1); } <T extends Movable > T moveMeOneInchFBound (T m) { m.move( 1,1); return m; } Car car1 = (Car) moveMeOneInch( new Car()); Car car2 = moveMeOneInchFBound( new Car()); } Java equivalent: interface Movable { fun move(x: Int, y: Int): Movable { return this } } class Car : Movable fun moveMeOneInch(m: Movable): Movable { return m.move(1, 1) } fun <T : Movable> moveMeOneInchFBound(m: T): T { m.move(1, 1) return m } val car1:Car = moveMeOneInch(Car()) as Car val car2:Car = moveMeOneInchFBound(Car()) ● in moveMeOneInch() we have to do unsafe casting to (Car) ● in moveMeOneInchFBound() no casting in necessary ● Kotlin&Java work the same but the syntax is differrent (<T : Movable> vs <T extends Movable> ● upper-bound generics no casting necessary
  • 11. Covariance Notes: ● Cat is a subclass of Animal ● Animal shelter puts animals and gets them for adoption ● We want to implement CatShelter and get&put Cats open class Animal class Cat : Animal() open class AnimalShelter { open fun getAnimalForAdoption() : Animal { return Animal() } open fun putAnimal(animal : Animal) { } } Base class: class CatShelter : AnimalShelter() { //covariant method return type override fun getAnimalForAdoption(): Cat { return Cat() } //covariant method argument type - NOT POSSIBLE override fun putAnimal(animal: Cat) { //overrides nothing super.putAnimal(animal) } } Derived class:
  • 12. Covariance Notes: ● Cat is a subclass of Animal ● Animal shelter puts animals and gets them for adoption ● We want to implement CatShelter and get&put Cats open class Animal class Cat : Animal() open class AnimalShelter2<in T> { open fun getAnimalForAdoption() : Animal { return Animal() } open fun putAnimal(animal : T) { } } Base class: class CatShelter2 : AnimalShelter2<Cat>() { //covariant method return type override fun getAnimalForAdoption(): Cat { return Cat() } //covariant method argument type override fun putAnimal(animal: Cat) { super.putAnimal(animal) } } Derived class:
  • 13. Contravariance Notes: ● Cat is a subclass of Animal ● Animal shelter puts animals and gets them for adoption ● We want to implement CatShelter and get&put Cats open class Animal class Cat : Animal() abstract class AnimalShelter3<out T> { abstract fun getAnimalForAdoption() : T open fun putAnimal(animal : Animal) { } } Base class: class CatShelter3 : AnimalShelter3<Any>() { //contravariant method return type override fun getAnimalForAdoption(): Any { return Cat() } } Derived class:
  • 14. Covariance Preserve List<T> type safety in Java: List<String> strs = new ArrayList<String>(); List<Object> objs = strs; // Java prohibits this! (Incompatible types) objs.add(1); //Cannot cast exception if compilation allowed the above line ● generic types in Java are invariant List<String> is not a subtype of List<Object> ● wildcard types in Java allow method argument type to be covariant Collection<String> is a subtype of Collection<? extends Object> (extends bound/upper-bound) interface Collection<E> ... { void addAll(Collection<? extends E> items); } which is why addAll() method from Collection<E> is: ● doesn’t have wildcard types ● uses declaration-site variance and type projections instead ● star-projections are present ● generic constraints (upper-bounds) are possible KOTLIN: use-site variance
  • 15. Variance comparison JAVA ● uses wildcards to express variance ● wildcards (use-site variance) are very expressive but also hard to understand and inconvienient for programmers KOTLIN ● developed mixed-site variance system in collaboration with Ross Tate ● combination of definition-site and use-site variance that avoids the failings of wildcards C<? extends T> covariant instantiation of C i.e. “C-of-some-subtype-of-T”. Example: fun <T : Comparable<T>> sort(list: List<T>) {} open class AnimalShelter2< in T> {} open class AnimalShelter2< out T> {}
  • 16. Annotation processing Implementation state: ● old implementation: kapt worked by intercepting communication between annotation processors and javac, and added already-compiled Kotlin classes on top of the Java classes ● new implementation of KAPT: generates stubs of Kotlin classes before running javac and llows the usage of APT based libraries we already have at our current java stack KAPT kapt { generateStubs = true } dependencies { kapt 'com.google.dagger:dagger-compiler:2.0.2' } Example config: ● JSR 269 Annotation Processing available in Kotlin since M12 ● Dagger 2 works :) ● DBFlow works
  • 17. SAM conversions SAM call: ● function literals can be converted into implementations of Java interfaces with a single non-default method ● the parameter types of the interface method must match the parameter types of the Kotlin function Lambda call: mInsiderApiService.getTeamsAsync({ list -> list.forEach { item -> print(item.description) } }, { /* do nothing on error */ } ) versionTextView.setOnClickListener( View.OnClickListener { print("Message content") } ) executor.execute(Runnable { println("This runs in a thread pool") }) mInsiderApiService.getTeamsAsync( object : Callback<List<SliderItem>> { override fun onResponse( p0: Call<List<SliderItem>>?, response: Response<List<SliderItem>>?) { /* something */ } override fun onFailure( p0: Call<List<SliderItem>>?, p1: Throwable?) { /* something */ } }) Java interface call:
  • 18. Type equality Checking type equality BaseClass TallItemView if (this instanceof TallItemView) { .... } // instanceof makes it very easy to be asymmetric if (this.getClass() .equals(TallItemView.class) ) { .... } Java if (this.javaClass .isAssignableFrom(TallItemView::class.java) ) Kotlin Referential equality referential equality is checked by the === operation Structural equality structural equality is checked by the == operation == is translated to: a?.equals(b) ?: (b === null) a == null is translated to: a === null if a is not null, it calls the equals(Any?) function, otherwise b === null
  • 19. Lambda vs Closure LAMBDA CLOSURE ● language construct ● a syntax for anonymous function ● can be assigned to a variable ● “closes over” the environment in which it was defined ● lambda which references fields external to its body ● function which is evaluated in its own environment
  • 20. Reified generics ● in Java generic type parameters are not reified: they are not available at runtime ● for inline functions (inserting the function code at the address of each function call) ● safe casting of generic types ● problem comes from type-erasure class MyClass<T> { private final T o; public MyClass() { this.o = new T(); //type parameter ‘T’ cannot be instantiated directly } } Example (Java) public class MyClass2<T> { @SuppressWarnings("unchecked") public T doSomething() { return (T) new MyClass(); //unchecked cast } } class MyClass2 { inline fun <reified T> doSomething() : T { return MyClass() as T; } } class MyClass Kotlin
  • 21. Fluent interfaces Kotlin: https://plugins.jetbrains.com/plugin/7903 Fluent setter generator plugin for Android Studio: (JAVA) public SampleActivity firstVariable(int firstVariable) { this.firstVariable = firstVariable; return this; } public SampleActivity secondVariable(int secondVariable) { this.secondVariable = secondVariable; return this; } ● almost like an internal DSL ● ideal for filtering, creating, customizing etc. ● used for model classes Java: Snakbar snack = Snackbar .make(mainView , "Sample snackbar" , Snackbar.LENGTH_LONG) .setAction( "Undo", undoClickListener) ; Fluent interface example: class Person(val name: String) { val parents : List<String> = arrayListOf() constructor(name: String, parent: String) : this(name) { parents.plus(parent) } fun parent(parent: String): Person { parents.plus(parent); return this } }
  • 22. Fluent interfaces /** * Fluent sort */ fun <T : kotlin.Comparable<T>> kotlin.collections.MutableList<T>. sortList(): MutableList<T> { sort() return this } /** * For-each fluent interface */ fun <T : kotlin.Comparable<T>> kotlin.collections.MutableList<T>. forEachList(action: (T) -> kotlin.Unit): MutableList<T> { for (elem in this) action.invoke(elem) return this } Additional functions: Fluent lists example: val list = listOf(1, 2, 3, 4, 5, 6, 7, 8) list .forEach { println(it) } list forEachLoop { println(it) } /** * In-place forEach loop (discouraged in 1.0 release) */ infix fun <T> kotlin.collections.Iterable<T> .forEachLoop(action: (T) -> kotlin.Unit): kotlin.Unit { this.forEach { action } } val outList = list .filter { it < 100 } .filterNot { it == 1 } .toMutableList() .sortList() .forEachList { it + 1 } .filter { it % 2 == 0 } .first() //result: 2
  • 23. Infix notation infix fun Int.minus(x: Int): Int { return this.minus(x) } infix extension function: val result = 1 minus 2 println(3 minus 4) type isPortfolio { println("Do something") } type isTeam { println("Do something else") } infix fun SliderActivityType.isPortfolio( execClosure : () -> Unit ) { if (this.equals(SliderActivityType.PORTFOLIO)) execClosure.invoke() } infix fun SliderActivityType.isTeam( execClosure : () -> Unit ) { if (this.equals(SliderActivityType.TEAM)) execClosure.invoke() } this displayToast "This is a message" infix fun Activity.displayToast(txt : String) { Toast.makeText(this, txt, Toast.LENGTH_SHORT).show() } ● only one method argument ● function literal can be passed outside the parentheses
  • 24. Infix notation if (this isGranted Manifest.permission.READ_CONTACTS) { //do something here } infix fun Activity.isGranted(permissionStr : String) : Boolean { if (ContextCompat.checkSelfPermission(this, permissionStr) != PackageManager.PERMISSION_GRANTED) return false return true } Handle Android permissions check: this loge "I really don't like errors" infix fun Activity.loge(txt : String) { Log.e(this.javaClass.simpleName, txt) } Log errors:
  • 25. Static extension methods fun Util.isDeviceOnline(context: Context): Boolean { val connMgr = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val networkInfo = connMgr.activeNetworkInfo return networkInfo != null && networkInfo.isConnected } fun Activity.isDeviceOnline(context: Context) = { Util().isDeviceOnline(context) } fun OkHttpClient.isDeviceOnline(context: Context) = { Util().isDeviceOnline(context) } Workaround (extension method for multiple classes): http://stackoverflow.com/questions/28210188/static-extension-methods-in-kotlin ● In Kotlin 1.0 there is no possibility to add a static extension method
  • 26. Generic types Create generic object instance: ● in JVM generic types are lost due to type erasure class MyClass<T> { private final T o; public MyClass() { this.o = new T(); //type parameter ‘T’ cannot be instantiated directly } }
  • 27. Generic types val bindFunc = { baseView: FrameLayout , item: ListItem , position: Int , clickListener: View.OnClickListener -> val nameTextView = baseView.findViewById(R.id. item_simple_list_main_header) as TextView nameTextView. text = item.title baseView.setOnClickListener(clickListener) } val adapter = SimpleItemListAdapter<ListItem , ListItemView<ListItem>>(onClickFunc , { ListItemView <ListItem> (R.layout. item_simple_list, bindFunc , baseContext , null /* attrs */ ) } ); Create generic object instance: ● in JVM generic types are lost due to type erasure override fun onCreateItemView(parent: ViewGroup, viewType: Int): TView { val view = factory() return view as TView } //not really convenient override fun onCreateItemView(parent: ViewGroup, viewType: Int, classParam : Class<T>): T { val v: T = classParam.constructors[0].newInstance(mContext, null) as T return v as T }
  • 28. Sealed classes sealed class Pet(val name: String) { class Dog(name: String): Pet(name) class Cat(name: String): Pet(name) } Sealed class: fun Pet.saySomething(): String { return when (this) { is Dog -> "woof" is Cat -> "meow" } } ● algebraic data type - i.e. composite data type which is formed by combining other types ● sealed classes - instead of open classes with private constructors ● “when” statement without “else” clause ● “Pet” cannot have other subclasses than “Dog” and “Cat” ● since M13 // private constructor to prevent creating more subclasses outside open class Pet private(val name: String) { class Dog(name: String): Pet(name) class Cat(name: String): Pet(name) }
  • 29. Dokka What is dokka: KDoc documentation: ● similar do Javadoc ● supports stale Javadoc out of the box ● markdown support included /** * # Beacon SDK initialization * * This method registers 3 beacons with IDs taken from Estimote Cloud. * Invoke this method in [onCreate]. * * ## Showcase demo * * Steps: * * Grant application bluetooth, GPS and WiFi permissions * * Wait for about 1 minute (beacons broadcast in 0.1 ~ 2.0 sec intervals) * * Snackbar should appear on the app's main activity * */ private fun initializeNearables() { ….. } ● generates documentation in html/markdown/javadoc ● maintained by Jetbrains ● generated from gradle/maven/ant ● standalone executable jar available ● [ref] instead of @see ref ● https://github.com/Kotlin/dokka
  • 30. Dokka Standalone jar: ● java -jar dokka-fatjar.jar ./src/ buildscript { dependencies { classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.7" } } sourceSets { main.java.srcDirs += 'src/main/kotlin' } dokka { outputFormat = 'html' //'markdown', 'javadoc' outputDirectory = "$buildDir/kotlindocs" } Dokka gradle plugin: HTML output with css styles:
  • 31. J2K converter Simple Activity conversion: Call Java 2 Kotlin converter: ● There is no Kotlin 2 Java as for now public class SampleActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } } class SampleActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } }
  • 32. Real-world example Method count: Library Method count cardview-v7/23.1.0 872 play-services-maps 1369 play-services-base 700 okhttp 1463 dagger-compiler 1582 kotlin-stdlib 2411 kotlin-runtime 705 support-vector-drawable 635 butterknife 635 okio 712 (617 after proguarding) LoC: 1857 kotlin + 503 java lines Compilation time (debug): 45.584 sec (6 sec incremental) Compilation time (release): 44.142 sec (proguard + zipaligning) Intel® Core™ i5-3470 CPU @ 3.20GHz × 4 8 GB RAM 1333 MHz, Ubuntu 15.10, Linux kernel 4.4.2-040402-generic
  • 33. Real-world example Method count: Library Method count joda-time 1707 converter-gson 236 com.google.android.gms 1912 kotterknife 456 com.google.dagger 290 retrofit-2.0.0-beta2 593 com.android.support/design 1017 com.android.support/recyclerview-v7 1579 LoC: 1857 kotlin + 503 java lines Compilation time (debug): 47.135 sec (6 sec incremental) Compilation time (release): 53.173 sec (proguard + zipaligning) Mac Mini late 2014, SSD 256 GB drive USB-3.0 2.6 GHz Intel Core i5 8 GB 1600 MHz DDR3, OsX El Capitan 10.11.2 (15C50) Try it yourself - STXInsider example project: https://github.com/kosiara/stx-insider
  • 34. Reflection Calling reflection: Text text text dependencies { compile 'org.jetbrains.kotlin:kotlin-reflect:1.0.0' } ● Reflection is moved into separate *.jar which reduces the size of runtime library val javaMethod = util.javaClass.methods[0] val javaConstructor = util.javaClass.constructors[0] val utilInstance = javaConstructor.newInstance() javaMethod.invoke(utilInstance) Java reflection in Kotlin: val classRef: KClass<Util> = Util::class val constructor = classRef.constructors.first() val method = classRef.functions.first() val util = constructor.call() method.call(util) val aFun = classRef.functions .filter { it.name.contains("aaa") }.first() val bFun = classRef.functions.filter { it.parameters.size == 1 }.first() aFun.call(util) bFun.call(util)
  • 35. Resources RESOURCES: ● https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science) ● https://kotlinlang.org/docs/reference/generics.html ● http://www.cs.cornell.edu/~ross/publications/mixedsite/mixedsite-tate-fool13.pdf ● http://blog.jetbrains.com/kotlin/2015/06/better-annotation-processing-supporting-stubs-in-kapt/ ● https://yanniss.github.io/varj-ecoop12.pdf ● https://schneide.wordpress.com/2015/05/11/declaration-site-and-use-site-variance-explained/ ● http://stackoverflow.com/questions/4231305/how-does-javas-use-site-variance-compare-to-cs-declaration-site-variance ● http://www.cs.cornell.edu/~ross/publications/tamewild/ ● http://stackoverflow.com/questions/26507099/lambda-expressions-in-kotlin ● http://gafter.blogspot.com/2006/11/reified-generics-for-java.html ● http://stackoverflow.com/questions/1927789/why-should-i-care-that-java-doesnt-have-reified-generics ● https://github.com/KeepSafe/dexcount-gradle-plugin ● http://blog.jetbrains.com/kotlin/2015/09/kotlin-m13-is-out/ ● http://blog.jetbrains.com/kotlin/2011/10/dsls-in-kotlin-part-1-whats-in-the-toolbox-builders/ ● http://stackoverflow.com/questions/28210188/static-extension-methods-in-kotlin ● http://antonioleiva.com/collection-operations-kotlin/
  • 36. Thankyou! Bartosz Kosarzycki bartosz.kosarzycki@stxnext.pl Twitter: @bkosarzycki Online compiler: http://try.kotlinlang.org/ STXInsider example project in Kotlin: https://github.com/kosiara/stx-insider