Thema: Kotlin 1.4 in Action
Referent: Tobse Fritz
Beginn: 18:00 Uhr
Sechs Städte. Ein Format. Jede Menge spannende Themen.
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
github.com/TobseF
stackoverflow.com/story/tobse
unsplash.com/@tobsef
menti.com
86 26 64 2
A programming language
that doesn’t change the way
you think about programming
is not worth knowing.
Alan Perlis, 1922-1990
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
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()
Interoperabel
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
Optimales Tooling
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
val theSolution = 42
theSolution = 24
// compile Error
var daysBeforeChristmas = 66
daysBeforeChristmas = 37
val daltons = listOf("Joe", "William", "Jack", "Averell ")
daltons += "Lucky Luke"
// compile Error
val characters = mutableListOf("Joe", "William", "Jack", "Averell ")
characters += "Lucky Luke"
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()
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"
}
}
}
<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>
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())
}
class Company(name: String)
class Company(val name: String)
class Company(var name: String)
Du bekommst
data class Company(var name: String)
ANGEBOT
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)
}
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")
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)
}
}
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")
}
fun weeNeedBoxedValue(value: CM?){
value?.apply (::println)
}
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);
}
}
IRectangle by Rectangle(), IMoveable by Moveable()
class PacMan :
Rectangle()
IRectangle by Rectangle()
class GameField :
class GameField :
val lazyValue: String by lazy {
println("computed!")
"Hello Kotliners"
}
println(lazyValue)
println(lazyValue)
computed!
Hello Kotliners
Hello Kotliners
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?
synchron & blockierend
main Thread
IO
Verarbeitung
App tut nix. CPU schläft.
Neue Threads
sind teuer!
komplex!
asynchron & blockierend
main Thread
wait & join
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
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
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
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
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
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
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
Pac-Man
Kotlin JVM
Kotlin Native
Kotlin JS
Android
Desktop
IOS
JAR
APK
Native Exe
Native App
Web
App
Native Android
Kotlin Multiplatform
Mobile (KMM)
Native IOS
10110
01010
10101
10110
01010
10101
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
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
@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
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
Java
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
📢
📧
Kotliners 2020 - 5 Juni 2020
🎤
Effective Kotlin - Marcin Moskala
📚
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
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.
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