This article was translated from JavaScript by Claude Code.
※ In Notes articles, I write down (roughly) in English the content of English session videos or podcasts. This article is intended to be read as a reference while watching the video. I hope this article is helpful when watching the video. (If there are any errors or typos in the content, please let me know.)
This article is about Kotlin Types: Exposed by Svetlana Isakova (KotlinConf 2017).

Agenda#
Basic Types
Nullable types
Collection types
How those types interact with Java and what happens when we mix types of Kotlin and Java
fun foo(): Int = 1
fun bar(): Int? = 1public static final int foo() {
return 1;
}
public static final Integer bar() {
return Integer.of(1);
}If you want to know what is going on under the hood, you can “show kotlin bytecode” (and also decompile the bytecode) in Android Studio
Correspondence between Kotlin and Java types
Intin Kotlin =>intin JavaInt?in Kotlin =>java.lang.Integerin Java
Kotlin does not have primitive types in the language, yet Kotlin still has primitive types in the bytecode level by making use of wrapper types and nullable types
Generic arguments#
List<Int>in Kotlin =>List<Integer>in JavaArray<Int>in Kotlin =>Integer[]in Java
Arrays of primitive types#
If you want to use primitive types of array, then use IntArray in Kotlin:
IntArrayin Kotlin =>int[]in Java
String#
kotlin.String in Kotlin => java.lang.String in Java
kotlin.String hides some confusing methods:
e.g. replaceAll method
In Java:
"one.two.".replaceAll(".", "*") => *******In Kotlin:
"one.two.".replace(".", "*") => one*two
"one.two.".replace(".".toRegex(), "*") => one*twoAny#
Anyin Kotlin =>java.lang.Objectin JavaAnytype is the super type for ALL types, includingIntor anything
Boxing under the hood#
log(2017) // the value is autoboxed
fun log(any: Any) {
println("Value: $any")
}
fun log(i: Int) {
println("Value: $i")
}Unit (Kotlin) vs Nothing (Kotlin) vs void (Java)?#
The concept comes from functional programming; from the type system
Unit: “a type that allows only one value and thus can hold no information” => The function completes
Nothing: “a type that has no values” => The function never completes
Unit instead of void#
Whenever you use void in Java, you use Unit in Kotlin
Unit
No meaningful value is returned
No explicit returned type implies you return
Unitby defaultTwo equivalent syntactic forms:
fun f() { /*…*/ }
fun f(): Unit { /*…*/ }Under the hood, Unit is still void in the bytecode
Nothing is different to Unit/void#
Unit and Nothing are two very different types even though in the bytecode level both mean void type
Nothingmeans “this function never returns”
Any & Nothing types#
Anyis a super type for all the other typesNothingis a subtype for all the other types
e.g. fail function below returns Unit
val answer = if (timeHasPassed()) {
42
} else {
fail("Not ready")
}
fun fail(message: String) {
throw IllegalStateException(message)
}If 42 is returned then the returned type of the expression function is
IntIf fail function is called then the returned type of the expression function is
Unit
=> Kotlin compiler thinks that the expression function returns Any type because the super type of both Int and Unit is Any
Returning Any means the variable answer will be initialized even if it fails, which is not what we expect; we expect it not to be initialized when it fails. => We can use Nothing in this case
Nothing is a subtype for all the other types, so that means the returned type of the expression function is now Int, which is what we expect
Type of null#
var user = null // => var user: Nothing? = null
user = User("svtk") // Error: Type mismatch
val users = mutableListOf(null) // => var users: List<Nothing?> = mutableListOf(null)
users.add(User("svtk")) // Error: Type mismatchNullable types & Java#
Nullable Types Under the Hood => Just annotations
If your returned type is annotated with @Nullable in Java, then in Kotlin, the type will become nullable
How to still prevent NPEs?#
Annotate your Java types
@Nullable type
@NotNull type
Non-null by default (JSR-305):
@javax.annotation.Nonnull
@TypeQualifierDefault(ElementType.PARAMETER, …)
annotation class MyNonnullByDefaultpackage-info.java:
@MyNonnullByDefault
package mypackage;Then, Kotlin will give you warning when assigning null to values:
@MyNonnullByDefault
public class Session {
public void setDescription(String description) {
this.description = description;
}
}Calling Java code from Kotlin:
val session = Session()
session.setDescription(null) // => Warning: Expected type doesn't accept nulls in Java …If you prefer errors in compile time rather than warnings:
build.gradle
compileKotlin {
kotlinOptions {
freeCompilerArgs += "-Xjsr305=strict"
}
}Then, Kotlin will give you errors when assigning null to values:
@MyNonnullByDefault
public class Session {
public void setDescription(String description) {
this.description = description;
}
}Calling Java code from Kotlin:
val session = Session()
session.setDescription(null) // => Error: Null can not be a value of a non-null type …- Specify types explicitly
public class Session {
public void setDescription(String description) {
this.description = description;
}
}val session = Session()
val description: String? = session.description ✅Or, the code below gives you IllegalStateException in runtime which notifies you very early what is wrong with your code:
val session = Session()
val description: String = session.description // IllegalStateException: session.description must not be nullHow it works?
- Intrinsic checks
The code below will be generated by compiler:
Intrinsics.checkExpressionValueisNotNull()Collections#
Read-only interfaces improve API
- How read-only collections and mutable collections work in Kotlin
List & MutableList#
Two interfaces declared in
kotlinpackageMutableListextendsList
Read-only DOES NOT mean immutable
- Read-only interface just lacks mutating methods
The actual list can be changed by another reference:
val mutableList = mutableListOf(1, 2, 3)
val list: List<Int> = mutableList
println(list) // [1, 2, 3]
mutableList.add(4)
println(list) // [1, 2, 3, 4]In Kotlin, there is a plan to provide immutable data structures in the standard library, but it is not ready yet
String!= notation, not syntax; platform type, which is a type that comes from Java
Platform types: summary
Good compromise between safety and convenience
Summary#
Primitives under the hood, and boxing is possible
Use
Nothingwhenever possiblePreventing NPE for Java interop: annotations, explicit types
Read-only does not mean immutable
That’s all!