Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Kotlin lang - advanced
(Android projects)
Bartosz Kosarzycki - StxNext Lightning Talks - Mar 11, 2016
talented developers ...
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. Constructo...
Live templates
exfun
fun Any.f(): Unit {
}
closure
{ x -> x }
iter
for (i in iterable) {
}
● let’s start with something
si...
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),...
Calling extension
functions
Get app-version ext. function:
@file:JvmName("ActivityUtil") //@file:JvmMultifileClass
package...
Constructors with
backing fields
● using constructors with backing fields in
a proper way saves a lot of boiler-plate
code...
Warnings
Checks:
Full list of supression contants:
https://github.com/JetBrains/kotlin/blob/master/compiler/frontend/src/o...
F-bound
polymorphism
Kotlin:
interface Movable {
Movable move(int x, int y);
}
class Car implements Movable {
@Override
pu...
Covariance
Notes:
● Cat is a subclass of Animal
● Animal shelter puts animals and
gets them for adoption
● We want to impl...
Covariance
Notes:
● Cat is a subclass of Animal
● Animal shelter puts animals and
gets them for adoption
● We want to impl...
Contravariance
Notes:
● Cat is a subclass of Animal
● Animal shelter puts animals and
gets them for adoption
● We want to ...
Covariance
Preserve List<T> type
safety in Java:
List<String> strs = new ArrayList<String>();
List<Object> objs = strs; //...
Variance
comparison
JAVA
● uses wildcards to express variance
● wildcards (use-site variance) are very
expressive but also...
Annotation
processing
Implementation state:
● old implementation: kapt worked by intercepting
communication between annota...
SAM
conversions
SAM call:
● function literals can be converted into implementations
of Java interfaces with a single non-d...
Type equality
Checking type equality
BaseClass
TallItemView
if (this instanceof TallItemView) { .... }
// instanceof makes...
Lambda vs
Closure
LAMBDA CLOSURE
● language construct
● a syntax for
anonymous function
● can be assigned to a
variable
● ...
Reified generics
● in Java generic type parameters are not
reified: they are not available at runtime
● for inline functio...
Fluent interfaces
Kotlin:
https://plugins.jetbrains.com/plugin/7903
Fluent setter generator plugin for Android Studio:
(JA...
Fluent interfaces /**
* Fluent sort
*/
fun <T : kotlin.Comparable<T>> kotlin.collections.MutableList<T>.
sortList(): Mutab...
Infix notation
infix fun Int.minus(x: Int): Int {
return this.minus(x)
}
infix extension function:
val result = 1 minus 2
...
Infix notation
if (this isGranted Manifest.permission.READ_CONTACTS) {
//do something here
}
infix fun Activity.isGranted(...
Static extension
methods
fun Util.isDeviceOnline(context: Context): Boolean {
val connMgr = context.getSystemService(Conte...
Generic types
Create generic object instance:
● in JVM generic types are lost due to type erasure
class MyClass<T> {
priva...
Generic types
val bindFunc = { baseView: FrameLayout , item: ListItem , position: Int , clickListener: View.OnClickListene...
Sealed classes
sealed class Pet(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 i...
Dokka
Standalone jar:
● java -jar dokka-fatjar.jar ./src/
buildscript {
dependencies {
classpath "org.jetbrains.dokka:dokk...
J2K converter
Simple Activity
conversion:
Call Java 2 Kotlin converter:
● There is no Kotlin 2 Java as for now
public clas...
Real-world
example
Method count:
Library Method count
cardview-v7/23.1.0 872
play-services-maps 1369
play-services-base 70...
Real-world
example
Method count:
Library Method count
joda-time 1707
converter-gson 236
com.google.android.gms 1912
kotter...
Reflection
Calling reflection:
Text text text
dependencies {
compile 'org.jetbrains.kotlin:kotlin-reflect:1.0.0'
}
● Refle...
Resources
RESOURCES:
● https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
● https://kotlinlang...
Thankyou!
Bartosz Kosarzycki
bartosz.kosarzycki@stxnext.pl
Twitter: @bkosarzycki
Online compiler:
http://try.kotlinlang.or...
Upcoming SlideShare
Loading in …5
×

Kotlin advanced - language reference for android developers

4,345 views

Published on

StxNext Lightning Talks - Mar 11, 2016

Kotlin Advanced - language reference for Android developers

This presentation contains the second talk on Kotlin language we had at STXNext. We try go deeper into language specifics and look at the positive impact new syntax can have on boilerplate removal and readability improvement.
Kotlin really shines in Android development when one looks at “Enum translation”, “Extension functions”, “SAM conversions”, “Infix notation”, “Closures” and “Fluent interfaces” applied to lists. The talk, however, compares language-specifics of Java & Kotlin in terms of “Type Variance”, “Generics” and “IDE tools” as well.
We present real-world example based on Stx-Insider project written in Kotlin which incorporates Dagger 2, Kotterknife, Retrofit2 and is composed of 5+ Activities.


Full agenda
Live templates
Enum translation
Calling extension functions from Kotlin/Java
Constructors with backing fields
Warnings
F-bound polymorphism
Variance (Covariance/Contravariance)
Variance comparison in Kotlin/Java/Scala
Annotation processing - KAPT
SAM conversions
Type equality
Lambda vs Closure
Reified generics
Fluent interfaces
Infix notation
Static extension methods in Kotlin
Generic types
Sealed classes
Dokka - documentation in Kotlin
J2K converter
Real-world example
Reflection

Presentation is accompanied with an example project (StxInsider):
https://github.com/kosiara/stx-insider





Published in: Software

Kotlin advanced - language reference for android developers

  1. 1. Kotlin lang - advanced (Android projects) Bartosz Kosarzycki - StxNext Lightning Talks - Mar 11, 2016 talented developers | flexible teams | agile experts
  2. 2. Kotlin basics - view here Stable 1.0 version is available from Feb 15, 2016
  3. 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. 4. Live templates exfun fun Any.f(): Unit { } closure { x -> x } iter for (i in iterable) { } ● let’s start with something simple - templates
  5. 5. Live templates exvar var Any.v: Any get() { } set(value) { } main fun main(args: Array<String>) { } inn if (i != null) { }
  6. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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

×