Thema: Kotlin 1.4 in Action
Referent: Tobse Fritz
Beginn: 18:00 Uhr
Sechs Städte. Ein Format. Jede Menge spannende Themen.
In Action
Kotlin 1.4
Quarantäne Ed.
Quarantäne Ed.
Quarantäne Ed.
Kotlin Das bessere Java
golem - 06.11.2020
Kotlin 1.4 mit neuen Sprachfunktionen und Tools
dev-inside - 21.08.2020
Kotlin jetzt zweitbeliebteste JVM-Sprache hinter Java
t3n- 06.02.2020
Loved Language Platz 4.
62.9 % Der Kotlin Entwickler möchten auch weiterhin damit entwicklen
insights.stackoverflow - 27.05.2020
Quarantäne Ed.
Kotlin Das bessere Java
golem - 06.11.2020
Kotlin 1.4 mit neuen Sprachfunktionen und Tools
dev-inside - 21.08.2020
Kotlin jetzt zweitbeliebteste JVM-Sprache hinter Java
t3n- 06.02.2020
Loved Language Platz 4.
62.9 % Der Kotlin Entwickler möchten auch weiterhin damit entwicklen
insights.stackoverflow - 27.05.2020
Jetpack Compose for Desktop: Milestone 1 Released
jetbrains blog - 05.11.2020
Kotlin Multiplatform Mobile Goes Alpha (KMM)
jetbrains blog - 31.08.2020
menti.com
86 26 64 2
Wie sehr bist Du schon vom
Kotlin Virus infiziert ?
A Überhaupt kein Kontakt
C Ich bin ein Super-Spreader
B Erste Symptome vorhanden
Q Kotlin gibt es gar nicht
Tobse Fritz
- Reich
- Gut aussehend
- Kotlin Fanboy
- Java Entwickler
- Clean Coder
- Hobby Photographer
- Gaming Nerd
- ITscope GmbH
github.com/TobseF
stackoverflow.com/story/tobse
unsplash.com/@tobsef
Was
macht
meine Lieblingssprache aus?
menti.com
86 26 64 2
Wichtig
- Intuitive Sprache
- Sehr gute IDE Unterstützung
- Entwicklung macht Spaß
- Sinnvolle Standardlib
- Libs, Libs und PackageManager
- Gute Community
Bedeutend
A programming language
that doesn’t change the way
you think about programming
is not worth knowing.
Alan Perlis, 1922-1990
Nice to have
- Einfacher Wechsel
- Produktiver
- Weniger Fehler
- Open Source
- Regelmäßig Updates
Mein PO ist auch begeistert
Kotlin Features
- Prägnant
- Sicher
- Interoperabel
- Optimales Tooling
Kotlin Features
Prägnant
public class Person {
private final String firstName;
private final String lastName;
private final LocalDate birthDay;
public Person(String firstName, String lastName,
LocalDate birthDay) {
this.firstName = firstName;
this.lastName = lastName;
this.birthDay = birthDay;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public LocalDate getBirthDay() {
return birthDay;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(firstName, person.firstName) &&
Objects.equals(lastName, person.lastName) &&
Objects.equals(birthDay, person.birthDay);
}
@Override
public int hashCode() {
return Objects.hash(firstName, lastName, birthDay);
}
@Override
public String toString() {
return "Person{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", birthDay=" + birthDay +
'}';
}
}
data class PersonK(
val firstName: String,
val lastName: String,
val birthDay: LocalDate
)
Java
Kotlin
Kotlin Features
Sicher
var output: String
output = null
Kotlin
val name: String? = null
println(name.length)
fun calculateTotal(obj: Any) {
if (obj is Invoice){
obj.calculateTotal()
}
}
fun isCloneBaby(father: Person, son: Person): Boolean {
return father == son
}
// Compile Error
// Compile Error
// Autocast
// equals()
Kotlin Features
Interoperabel
- iOS (arm32, arm64, simulator x86_64)
- MacOS (x86_64)
- Android (arm32, arm64)
- Windows (mingw x86_64, x86)
- Linux (x86_64, arm32, MIPS, MIPS little endian, Raspberry Pi)
- WebAssembly (wasm32)
Kotlin Features
Interoperabel
fun callJava(){
val backend = LegacyBackend()
backend.sendMail("Be prepared... we deploy")
}
Kotlin
private void callKotlin(){
var backend = new NewBackend();
backend.sendSlack("We introduced NetID oAuth!");
}
Java
Kotlin Features
Optimales Tooling
Wer hat's erfunden?
Jul 2011 - Öffentliche Bekanntmachung
Feb 2016 - Release Version 1.0
Nov 2017 - Release Version 1.2
Mai 2017 - Offizielle Sprache für Android
Aug 2020 - Release Version 1.4.10
Kotlin Native v0.4 & Multiplatform
Okt 2018 - Gründung Kotlin Foundation
Kotlin Features
- Prägnant
- Sicher
- Interoperabel
- Optimales Tooling
- Frei & OpenSource
Kotlin Highlights
- Unveränderbare Typen
- String Builders
- Typisierte Lamdas
- Ein Leben ohne NPEs
- Data - Klassen
- Delegations
- Extensions
- Coroutines
- •••
Sprach
Bin ich ?
val theSolution = 42
theSolution = 24
// compile Error
var daysBeforeChristmas = 66
daysBeforeChristmas = 37
Und wenn Ja, wie lange?
You will never change me!
val daltons = listOf("Joe", "William", "Jack", "Averell ")
daltons += "Lucky Luke"
// compile Error
val characters = mutableListOf("Joe", "William", "Jack", "Averell ")
characters += "Lucky Luke"
Ein String sie zu knechten
val ringNumber = 2
val logMessage = "💍 This ring No $ringNumber was destroyed at ${System.currentTimeMillis()}"
val htmlSnippet = """
<h1>🗺 Die Welt</h1>
<ul>
<li>Gondor</li>
<li>Mordor</li>
<li>Eriador</li>
</ul>
</li>
""".trimIndent()
Type Safe Builders
fun theWorld() = html {
body {
h1 { + "🗺 Die Welt" }
p { + "Gondor" }
p { + "Mordor" }
p { + "Eriador" }
a (href = "https://en.wikipedia.org/wiki/Minor_places_in_Middle-earth") {
+"Middle Earth"
}
}
}
Bob der Baumeister
<html>
<body>
<h1>🗺 Die Welt</h1>
<p>Gondor</p>
<p>Mordor</p>
<p>Eriador</p>
<a href="https://en.wikipedia.org/wiki/Minor_places_in_Middle-earth">Middle Earth</a>
</body>
</html>
Lamdas
Richtige konkrete Typen
fun message(messageKey: String, locale: Locale) = "Lorem ipsum"
fun getCurrentUserLocale() = Locale.GERMANY
fun localize(messageKey: String, translateable: (String, Locale) -> String): String {
return translateable.invoke(messageKey, getCurrentUserLocale())
}
Klasse Klasse
class Company(name: String)
class Company(val name: String)
class Company(var name: String)
- Konstruktor Param name
Du bekommst
- Alles vom ersten Paket
- + getName()
- Alles vom zweiten Paket
- + setName()
data class Company(var name: String)
- Alles vom dritten Paket
- + hashCode()
- + equals()
- + toString()
ANGEBOT
„Hasta la vista NPE!“
class Company(val name: String)
fun loadCompany(): Company {
return Company("Reynholm Industries")
}
val company = loadCompany()
println(company.name)
fun loadCompanyByName(name: String): Company? {
return Company(name)
}
val loadedCompany = loadCompanyByName("Die Anstalt")
if (loadedCompany != null) {
println(loadedCompany.name)
}
Prima Parameter
fun sendMail(address: String, subject: String, message : String){
// ...
}
fun sendMail(
address: String, subject: String, message: String,
cc: String, bcc: String = "", attachment: Attachment?,
timeout: Duration
) {...}
fun sendMail(
address: String = "", subject: String = "", message: String = "",
cc: String = "", bcc: String = "", attachment: Attachment? = null,
timeout: Duration = Duration.ofSeconds(12)
) {...}
sendMail(address = "diskette@mail.org", message = "Your time is over")
Extensions
Nie wieder Util Klassen
val email = "Tobse4Git@gmail.com"
email.toLowerCase()
val username = "emil"
println(username.toFirstUpperCase())
fun String.toFirstUpperCase(): String {
return if (this.isEmpty()) {
""
} else {
this[0].toTitleCase() + this.substring(1)
}
}
Value types schon heute
Inline Classes
Inline Classes
inline class CM(val number: Double = 1.0){
fun toInch() = number * 2.54
fun toFeet() = number * 0.0328084
override fun toString(): String {
return "$number cm"
}
}
fun main() {
println(CM(1.0))
println(CM(1.0).toFeet())
println(CM(1.0).toInch())
cutTheRope(length = CM(20.0))
}
var ropeLength = CM(100.0)
fun cutTheRope(length:CM ){
ropeLength = CM(ropeLength.number + length.number)
println("Remaining rope: $length")
}
Inline Classes
fun weeNeedBoxedValue(value: CM?){
value?.apply (::println)
}
Boxing
Inline Classes
public static final void cutTheRope(double length) {
ropeLength = CM.constructor-impl(ropeLength + length);
String var2 = "Remaining rope: " + CM.toString-impl(length);
System.out.println(var2);
}
public static final void weeNeedBoxedValue(@Nullable CM value) {
if (value != null) {
System.out.println(value);
}
}
Compiliert
Delegation
Komposition statt Vererbung
Delegation
Delegation
Delegation
Delegation
IRectangle by Rectangle(), IMoveable by Moveable()
class PacMan :
Rectangle()
IRectangle by Rectangle()
class GameField :
class GameField :
Delegation
Toll ein anderer macht's
val lazyValue: String by lazy {
println("computed!")
"Hello Kotliners"
}
println(lazyValue)
println(lazyValue)
computed!
Hello Kotliners
Hello Kotliners
Delegation
var name by CountAccess()
class CountAccess {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "Do you need help?"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("Hallo my name is $value... and I will help you'")
}
}
name = "Hannibal"
name = "Murdock"
name = "Face"
println(name)
Hallo my name is Hannibal... and I will help you'
Hallo my name is Murdock... and I will help you'
Hallo my name is Face... and I will help you'
Do you need help?
- Callback Hell
- Was kostet ein Thread?
Coroutines
Coroutines
synchron & blockierend
main Thread
IO
Verarbeitung
App tut nix. CPU schläft.
Coroutines
Neue Threads
sind teuer!
komplex!
asynchron & blockierend
main Thread
wait & join
Coroutines
Coroutinen sind leichtgewichtige Threads.
Sie können angehalten werden,
ohne den Thread zu blockieren.
Suspending
Launch startet eine Coroutine und
gibt einen Job zurück.
Async ist wie Launch, nur mit Rückgabewert.
Await wartet auf den Rückgabewert.
Async / Await
Launch
Coroutines
suspend fun checkPosition(): Position {
delay(1000)
println("🔍 Checked Position")
return Position()
}
suspend fun getWeather(): Weather {
delay(1000)
println("☀ Checked Weather")
return Weather()
}
suspend fun playForecast() {
delay(1000)
println("🔊 Play Forecast")
}
val start = System.currentTimeMillis()
val position = launch { checkPosition() }
println("Having so much time 💤")
val weather = launch { getWeather() }
println("We can do everything 💤")
val forecast = launch { playForecast() }
println("Lets count Kotliners 💤")
forecast.join()
position.join()
weather.join()
println(System.currentTimeMillis() - start)
Having so much time 💤
We can do everything 💤
Lets count Kotliners 💤
🔍 Checked Position
☀ Checked Weather
🔊 Play Forecast
1013
Coroutines
suspend fun checkPosition(): Position {
delay(1000)
println("🔍 Checked Position")
return Position()
}
suspend fun getWeather(): Weather {
delay(1000)
println("☀ Checked Weather")
return Weather()
}
suspend fun playForecast() {
delay(1000)
println("🔊 Play Forecast")
}
val start = System.currentTimeMillis()
val position = launch { checkPosition() }
println("Having so much time 💤")
val weather = launch { getWeather() }
println("We can do everything 💤")
val forecast = launch { playForecast() }
println("Lets count Kotliners 💤")
forecast.join()
position.join()
weather.join()
println(System.currentTimeMillis() - start)
Having so much time 💤
We can do everything 💤
Lets count Kotliners 💤
🔍 Checked Position
☀ Checked Weather
🔊 Play Forecast
1013
Coroutines
val fibonacci = sequence {
yield(1) // first Fibonacci number
var current = 1
var next = 1
while (true) {
yield(next) // next Fibonacci number
val tmp = current + next
current = next
next = tmp
}
}
println(fibonacci.take(42).joinToString())
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296
Coroutines
fun loopWithThreads() {
val c = AtomicLong()
println("🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇")
measureTime {
for (i in 1..100_000) {
thread(start = true) {
c.addAndGet(1).printProgress()
}
}
}
}
fun loopWithCoroutine() {
val c = AtomicLong()
println("🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇")
measureTime {
for (i in 1..100_000) {
GlobalScope.launch {
c.addAndGet(1).printProgress()
}
}
}
}
🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇
💉💉💉
// injectometer
Coroutines
fun loopWithThreads() {
val c = AtomicLong()
println("🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇")
measureTime {
for (i in 1..loopCount) {
thread(start = true) {
c.addAndGet(1).printProgress()
}
}
}
}
fun loopWithCoroutine() {
val c = AtomicLong()
println("🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇")
measureTime {
for (i in 1..loopCount) {
GlobalScope.launch {
c.addAndGet(1).printProgress()
}
}
}
}
🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇
💉💉💉💉💉💉💉💉💉💉
time: 0m 5s 363ms
🦇🦇🦇🦇🦇🦇🦇🦇🦇🦇
💉💉💉💉💉💉💉💉💉💉
time: 0m 0s 145ms
Coroutines
- Leserlich wie imperativer Code
- Keine Callback Hell
-
Leichtgewichtiger als Threads
- Geringerer Speicherverbrauch
- Schneller Wechsel
- Syntax ist unabhängig von Implementierung
- Verfügbar in JVM, JS und Native Kotlin
- Channel
- Actor
- Sequence Builder
- Coroutine Dispatcher
- Coroutine Scope
Coroutines
Wie sehr könnte sich der Einsatz von Coroutines in euren Projekten lohnen?
A Gar nicht oder kaum
C Darauf habe ich gewartet
B Bietet mit Sicherheit Mehrwerte
D Keine Ahnung oder irrelevant
menti.com
86 26 64 2
Ausblick
- Operator Overloading
- Unsigned Integers
- Sealed Classes
- Contracts
- Gradle DSL
- Multiplatform
- Kotlin Native
Kotlin Multiplatform
Pac-Man
Kotlin JVM
Kotlin Native
Kotlin JS
Android
Desktop
IOS
JAR
APK
Native Exe
Native App
Web
App
Kotlin Multiplatform
Native Android
Kotlin Multiplatform
Mobile (KMM)
Native IOS
10110
01010
10101
10110
01010
10101
Kotlin Multiplatform
Kotlin Multiplatform
Kotlin JS
JS
Kotlin JVM
Kotlin Script
Kotlin Native
10110
01010
10101
Kotlin Multiplattform...
A Gar nicht oder kaum
C Darauf habe ich gewartet
B Bietet mit Sicherheit Mehrwerte
Q Keine Ahnung oder irrelevant
menti.com
86 26 64 2
Kotlin Everywhere
https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html
@RestController
public class HelloController {
@GetMapping("/hello")
public String handle() {
return "Hello WebFlux";
}
}
Spring WebFlux provides an annotation-based programming model, where @Controller and @RestController components use annotations to express request mappings, request input, handle exceptions, and more. Annotated controllers have flexible method signatures and do not have to extend base classes nor implement specific interfaces.
The following listing shows a basic example:
https://docs.spring.io/spring/docs/.../web-reactive.html
Kotlin
Java
Kotlin Everywhere
@RestController
class HelloController {
@GetMapping("/hello")
fun handle() = "Hello WebFlux"
}
Spring WebFlux provides an annotation-based programming model, where @Controller and @RestController components use annotations to express request mappings, request input, handle exceptions, and more. Annotated controllers have flexible method signatures and do not have to extend base classes nor implement specific interfaces.
The following listing shows a basic example:
https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html
https://docs.spring.io/spring/docs/.../web-reactive.html
Kotlin
Java
Kotlin
Java
Kotlin Everywhere
Kotlin Everywhere
plugins {
kotlin("jvm") version "1.3.30"
java
}
group = "de.tfr.presentation"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
implementation(kotlin("stdlib-js"))
testCompile("junit", "junit", "4.12")
}
configure<JavaPluginConvention> {
sourceCompatibility = JavaVersion.VERSION_1_8
}
build.gradle.kts
Kotlin Everywhere
Java
Kotlin Everywhere
https://stackshare.io/kotlin
https://octoverse.github.com
https://github.com/ygaller/kotlin-companies/wiki
https://blog.jetbrains.com/kotlin/2020/11/productive-server-side-development-with-kotlin-stories/
Trello
Evernote
Trivago
Runtastic
Tinder
Uber
My Taxi
Klarna
Mastercard
N26
182 %
Wachstum auf GitHub 2019
📢
📧
Kotlin Everywhere
Kotlin Everywhere
Kotliners 2020 - 5 Juni 2020
🎤
Effective Kotlin - Marcin Moskala
📚
Kotlin Everywhere
- Backend
- Frontend
- Geiles Tooling
- Interoperabel
- Loved
- Mobile
- Native
- Open Source
- Performant
- Prägnant
- Sicher
- Weit verbreitet
Konnte ich Dich mit dem
Kotlin Virus infizieren?
A Ich bin völlig immun geblieben!
C Mich hat es voll erwischt,
wo gibt es das Gegenmittel?
B Es juckt schon in der Nase!
D Versuche auf dem Weg zur Intensivstation
möglichst viele Kollegen mit anzustecken!
menti.com
62 39 78 6
GAME OVER
Kotlin infected the whole world and reached first place of the TIOBE index. 98% of all Git-commits contain Kotlin code. The last Nullpointer Exception was seen over 12 months ago.
CREDITS
- kotlinlang.org/docs/reference/
- https://stackshare.io/kotlin
- https://github.com/ygaller/kotlin-companies/wiki
- https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html
- https://stackabuse.com/spring-reactor-tutorial/
- https://github.com/korlibs/korge
- https://octoverse.github.com
- flaticon.com
- kotlinlang.org/community/kotlin-nights.html
- https://hipwallpaper.com/release-the-panic-backgrounds/
Frankfurter Entwicklertag - 03./04. März 2021
Online-IT-Konferenz
Sechs Städte. Ein Format. Jede Menge spannende Themen.
Alle Infos zur Konferenz erhaltet ihr hier:
Spendenaufruf
Sechs Städte. Ein Format. Jede Menge spannende Themen.
Wir laden euch dazu ein für die Tafel Frankfurt zu spenden:
Online Umfrage zu dieser ObjektForum Online Edition
Sechs Städte. Ein Format. Jede Menge spannende Themen.
Wir möchten euch bitten uns Feedback zu geben:
https://umfrage.andrena.de/index.php?r=survey/index&sid=527626&lang=de-informal
Kotlin 1.4 in Action
By Tobse Fritz
Kotlin 1.4 in Action
Lass dich auch dem Kotlin Virus infizieren und erlebe state of the Art Software engineering.
- 907