Kotlin as a Modernized Java
Programming in XXI Century
Presented at JavaOne, 2018
email elizarov@
Roman Elizarov
@relizarov
Slide 2
Slide 2 text
1995 2003 2004 2011
Slide 3
Slide 3 text
What if Java was designed in 201x?
Slide 4
Slide 4 text
Error handling
Slide 5
Slide 5 text
Error handling
int res = fread(buf, n, file);
Slide 6
Slide 6 text
Error handling
int res = fread(buf, n, file);
if (res < n) { // error or EOF
if (ferror(file) != 0) {
// handle error
}
return;
}
Slide 7
Slide 7 text
Error handling
int res = fread(buf, n, file);
if (res < n) { … }
res = fread(buf, m, file);
if (res < n) { // error or EOF
if (ferror(file) != 0) {
// handle error
}
return;
}
Slide 8
Slide 8 text
Exceptions
try {
FileInputStream file = new FileInputStream(fileName);
// …
int res = file.read(buf, 0, n); // throws exception
// …
} catch (IOException e) {
// handle error
}
Slide 9
Slide 9 text
Exceptions
try {
FileInputStream file = new FileInputStream(fileName);
// …
int res = file.read(buf, 0, n);
// …
res = file.read(buf, 0, m); // throws exception
// …
} catch (IOException e) {
// handle error
}
Slide 10
Slide 10 text
Exceptions
try {
Data result = work(fileName);
} catch (IOException e) {
// handle error
}
Slide 11
Slide 11 text
Checked Exceptions
Data work(String fileName) throws IOException {
FileInputStream file = new FileInputStream(fileName);
// …
int res = file.read(buf, 0, n);
// …
res = file.read(buf, 0, m);
// …
}
Slide 12
Slide 12 text
No content
Slide 13
Slide 13 text
1995
1.0
2004
5
Generics
Slide 14
Slide 14 text
1995
1.0
2004
5
Generics
Lambdas (FP)
2014
8
Slide 15
Slide 15 text
Imperative
List results = new ArrayList<>();
for (String fileName : fileNames) {
Result work = work(fileName);
results.add(work);
}
Local variable type inference
1995
1.0
2004
5
2018
10
2014
8
Slide 50
Slide 50 text
Before type inference
int count = …
double average = …
List strings = …
Map> items = …
Slide 51
Slide 51 text
With type inference
var count = …
var average = …
var strings = …
var items = …
Slide 52
Slide 52 text
With type inference
var count = …
var average = …
var strings = …
Map> items = …
Slide 53
Slide 53 text
Types on right!
var count = …
var average = …
var strings = …
var items: Map> = …
Slide 54
Slide 54 text
Where is the type in XXI Century?
Left Right
Slide 55
Slide 55 text
Where is the type in XXI Century?
Left Right
Slide 56
Slide 56 text
If Java was designed in 201x
It would have been designed for type
inference with types on the right
Slide 57
Slide 57 text
Type safety
Slide 58
Slide 58 text
How type-safe is that?
int process(List input) { … }
Slide 59
Slide 59 text
How type-safe is that?
int process(List input) { … }
Slide 60
Slide 60 text
How type-safe is that?
int process(List input) { … }
process(null);
Oops!
Slide 61
Slide 61 text
Null in Kotlin
fun process(input: List): Int { … }
process(null)
Slide 62
Slide 62 text
Null in Kotlin is forbidden by default
fun process(input: List): Int { … }
process(null)
Slide 63
Slide 63 text
Opt-in to use nulls
fun process(input: List?): Int { … }
process(null)
Slide 64
Slide 64 text
fun process(input: List?): Int {
…
return input.size
}
process(null)
Slide 65
Slide 65 text
fun process(input: List?): Int {
…
return input.size
}
process(null)
Slide 66
Slide 66 text
fun process(input: List?): Int {
…
return input?.size
}
process(null)
Slide 67
Slide 67 text
fun process(input: List?): Int {
…
return input?.size
}
process(null)
Slide 68
Slide 68 text
fun process(input: List?): Int? {
…
return input?.size
}
process(null)
Slide 69
Slide 69 text
If Java was designed in 201x
It would have had null-safety
Slide 70
Slide 70 text
How type-safe is that?
int process(List input) { … }
Slide 71
Slide 71 text
How type-safe is that?
int process(List input) {
input.removeIf(data -> !data.isGood());
return input.size();
}
Slide 72
Slide 72 text
How type-safe is that?
int process(List input) {
input.removeIf(data -> !data.isGood());
return input.size();
}
Oops!
Slide 73
Slide 73 text
Collections in Kotlin
fun process(input: List): Int {
input.removeIf { data -> !data.isGood() }
return input.size
}
Slide 74
Slide 74 text
Collections in Kotlin are read-only
fun process(input: List): Int {
input.removeIf { data -> !data.isGood() }
return input.size
}
Slide 75
Slide 75 text
Opt-in to mutability
fun process(input: MutableList): Int {
input.removeIf { data -> !data.isGood() }
return input.size
}
Slide 76
Slide 76 text
How type-safe is that?
int process(List input) {
…
int size = input.size();
…
return size;
}
Slide 77
Slide 77 text
How type-safe is that?
int process(List input) {
…
final int size = input.size();
…
return size;
}
Slide 78
Slide 78 text
Kotlin: Make val not var
fun process(input: List): Int {
…
val size = input.size
…
return size
}
Slide 79
Slide 79 text
Choice of Defaults
Slide 80
Slide 80 text
Defaults
Null/Not-null
Slide 81
Slide 81 text
Defaults
Java
Null/Not-null Nullable
Slide 82
Slide 82 text
Defaults
Java Real life
Null/Not-null Nullable Non-nullable
Slide 83
Slide 83 text
Defaults
Java Real life
Null/Not-null Nullable Non-nullable
Mutable/Immutable
Slide 84
Slide 84 text
Defaults
Java Real life
Null/Not-null Nullable Non-nullable
Mutable/Immutable Mutable
Slide 85
Slide 85 text
Defaults
Java Real life
Null/Not-null Nullable Non-nullable
Mutable/Immutable Mutable Immutable
Slide 86
Slide 86 text
Defaults
Java Real life
Null/Not-null Nullable Non-nullable
Mutable/Immutable Mutable Immutable
Open/Final
Slide 87
Slide 87 text
Defaults
Java Real life
Null/Not-null Nullable Non-nullable
Mutable/Immutable Mutable Immutable
Open/Final Open
Slide 88
Slide 88 text
Defaults
Java Real life
Null/Not-null Nullable Non-nullable
Mutable/Immutable Mutable Immutable
Open/Final Open Final
Slide 89
Slide 89 text
Defaults
Java Real life
Null/Not-null Nullable Non-nullable
Mutable/Immutable Mutable Immutable
Open/Final Open Final
Private/Public
Slide 90
Slide 90 text
Defaults
Java Real life
Null/Not-null Nullable Non-nullable
Mutable/Immutable Mutable Immutable
Open/Final Open Final
Private/Public Pkg private
Slide 91
Slide 91 text
Defaults
Java Real life
Null/Not-null Nullable Non-nullable
Mutable/Immutable Mutable Immutable
Open/Final Open Final
Private/Public Pkg private Public
Slide 92
Slide 92 text
If Java was designed in 201x
It would have very different defaults
Slide 93
Slide 93 text
Syntax
Slide 94
Slide 94 text
Semicolon
foo(); bar();
Slide 95
Slide 95 text
Semicolon
foo();
bar();
Slide 96
Slide 96 text
Semicolon
foo();
bar();
Slide 97
Slide 97 text
Semicolon
foo()
bar()
Slide 98
Slide 98 text
Where is the semicolon in XXI Century?
Mandatory None/Optional
Slide 99
Slide 99 text
Where is the semicolon in XXI Century?
Mandatory None/Optional
Slide 100
Slide 100 text
If Java was designed in 201x
It would have optional semicolon
Slide 101
Slide 101 text
What if Java was designed in 201x?
ØNo checked exceptions
ØDesigned for type inference
ØFunctional by design
ØNo exposed primitives
ØNull safety
ØWell-founded defaults
ØOptional semicolon
Slide 102
Slide 102 text
Syntactic sugar
Slide 103
Slide 103 text
Properties in Java
public class Person {
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
…
Slide 104
Slide 104 text
Properties in Kotlin
class Person {
var firstName: String? = null
var lastName: String? = null
}
Slide 105
Slide 105 text
Primary constructor in Java
public class Person {
private String firstName;
private String lastName;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
…
Slide 106
Slide 106 text
Primary constructor in Kotlin
class Person(
var firstName: String?,
var lastName: String?
)
Slide 107
Slide 107 text
Primary constructor + null-safety = ❤
class Person(
var firstName: String,
var lastName: String
)
Slide 108
Slide 108 text
Equals/hashCode/etc in Java
public class Person {
private String firstName;
private String lastName;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
return Objects.equals(firstName, person.firstName) &&
Objects.equals(lastName, person.lastName);
}
…
Slide 109
Slide 109 text
Data class in Kotlin
data class Person(
var firstName: String,
var lastName: String
)
Slide 110
Slide 110 text
String concatenation in Java
public class Person {
@Override
public String toString() {
return firstName + " " + lastName;
}
…
Slide 111
Slide 111 text
String format in Java
public class Person {
@Override
public String toString() {
return String.format("%s %s", firstName, lastName);
}
…
Slide 112
Slide 112 text
String interpolation in Kotlin
class Person(…) {
override fun toString(): String {
return "$firstName $lastName";
}
…
Slide 113
Slide 113 text
String interpolation in Kotlin
class Person(…) {
override fun toString(): String =
"$firstName $lastName"
…
Slide 114
Slide 114 text
Singleton in Java
public class Singleton {
public static final INSTANCE = new Singleton();
private Singleton() {}
…
}
Slide 115
Slide 115 text
Singleton in Kotlin
object Singleton {
…
}
Slide 116
Slide 116 text
Why Kotlin?
Slide 117
Slide 117 text
Kotlin was designed as a modernized Java
Slide 118
Slide 118 text
Kotlin
ØInteroperability with JVM ecosystem
ØEasy to learn for Java developers by design
ØExtensible, DSL-friendly
ØPragmatic
ØFun to work with