
Nullable and NotNull annotations from a number of libraries that define such annotations. These annotations are helpful but do not offer the safety that Kotlin offers. Nevertheless, in order to respect this convention, Kotlin also marks its types using Nullable and NotNull annotations when compiled to JVM[^051_3].class MessageSender { fun sendMessage(title: String, content: String?) {} }
// Compiles to the analog of the following Java code final class MessageSender { public void sendMessage( @NotNull String title, @Nullable String content ) { Intrinsics.checkNotNullParameter(title, "title"); } }
Nullable and NotNull annotations, it treats these types accordingly as nullable and non-nullable types[^051_0].public class JavaClass { public static @NotNull String produceNonNullable() { return "ABC"; } public static @Nullable String produceNullable() { return null; } }

Observable<List<User>>, which in Kotlin is seen as Observable<List<User?>?>?. There would be so many types to unpack, even though we know none of them should actually be nullable.// Java public class UserRepo { public Observable<List<User>> fetchUsers() { //*** } }
// Kotlin, if unannotated types were considered nullable val repo = UserRepo() val users: Observable<List<User>> = repo.fetchUsers()!! .map { it!!.map { it!! } }
! after the type name, such as String!, but this notation cannot be used in code. Platform types are non-denotable, meaning that they can’t be written explicitly in code. When a platform value is assigned to a Kotlin variable or property, it can be inferred, but it cannot be explicitly set. Instead, we can choose the type that we expect: either a nullable or a non-null type.// Kotlin val repo = UserRepo() val user1 = repo.fetchUsers() // The type of user1 is Observable<List<User!>!>! val user2: Observable<List<User>> = repo.fetchUsers() val user3: Observable<List<User?>?>? = repo.fetchUsers()

java.lang.String in Java maps to kotlin.String in Kotlin. This means that when a Kotlin file is compiled to Java, kotlin.String becomes java.lang.String. This also means that java.lang.String in a Java file is treated like it is kotlin.String. You could say that kotlin.String is type aliased to java.lang.String. Here are a few other Kotlin types with associated Java types:|-----------------------|--------------------------|
|
kotlin.Any | java.lang.Object ||
kotlin.Cloneable | java.lang.Cloneable ||
kotlin.Comparable | java.lang.Comparable ||
kotlin.Enum | java.lang.Enum ||
kotlin.Annotation | java.lang.Annotation ||
kotlin.Deprecated | java.lang.Deprecated ||
kotlin.CharSequence | java.lang.CharSequence ||
kotlin.String | java.lang.String ||
kotlin.Number | java.lang.Number ||
kotlin.Throwable | java.lang.Throwable |Byte, Short, Int, Long, Float, Double, Char, and Boolean types use primitives under the hood. So, for example, when you use Int as a parameter, it will be int under the hood.// KotlinFile.kt fun multiply(a: Int, b: Int) = a * b
// Compiles to the analog of the following Java code public final class KotlinFileKt { public static final int multiply(int a, int b) { return a * b; } }
|-------------|-----------|
|
Byte | byte ||
Short | short ||
Int | int ||
Long | long ||
Float | float ||
Double | double ||
Char | char ||
Boolean | boolean |Integer or Boolean are just simple wrappers over primitive values.|-------------|-----------|
|
Byte? | Byte ||
Short? | Short ||
Int? | Integer ||
Long? | Long ||
Float? | Float ||
Double? | Double ||
Char? | Char ||
Boolean? | Boolean ||----------------------|----------------------|
|
List<Int> | List<Integer> ||
Set<Long> | Set<Long> ||
Map<Float, Double> | Map<Float, Double> |IntArray, where Array<Int> represents an array of wrapped types.|--------------|-------------|
|
Array<Int> | Integer[] ||
IntArray | int[] ||----------------|-------------|
|
ByteArray | byte[] ||
ShortArray | short[] ||
IntArray | int[] ||
LongArray | long[] ||
FloatArray | float[] ||
DoubleArray | double[] ||
CharArray | char[] ||
BooleanArray | boolean[] ||-----------------------------|---------------|
|
Array<IntArray> | int[][] ||
Array<Array<LongArray>> | long[][][] ||
Array<Array<Int>> | Integer[][] ||
Array<Array<Array<Long>>> | Long[][][] |List interface, which includes methods that allow list modification. But in Java we also use immutable collections, and they implement the same interface. Their methods for collection modification, like add or remove, throw UnsupportedOperationException if they are called.// Java public final class JavaClass { public static void main(String[] args) { List<Integer> numbers = List.of(1, 2, 3); numbers.add(4); // throws UnsupportedOperationException } }
List interface, it does not know if this list should be considered mutable or not, so the result type is (Mutable)List, which can be used as both List and MutableList.
List.// KotlinFile.kt fun readOnlyList(): List<Int> = listOf(1, 2, 3) fun mutableList(): MutableList<Int> = mutableListOf(1, 2, 3)
// Compiles to analog of the following Java code public final class KotlinFileKt { @NotNull public static final List readOnlyList() { return CollectionsKt.listOf(new Integer[]{1, 2, 3}); } @NotNull public static final List mutableList() { return CollectionsKt.mutableListOf(new Integer[]{1,2,3}); } }

add or remove, so using them in Java might lead to exceptions.// Java public final class JavaClass { public static void main(String[] args) { List<Integer> integers = KotlinFileKt.readOnlyList(); integers.add(20); // UnsupportedOperationException } }
List type contract[^051_2].List interface on JVM implement Java List, so methods like add or remove are generated for them. The default implementations of these methods throw UnsupportedOperationException. The same can be said about Set and Map.
Nullable and NotNull annotations from a variety of libraries, including JSR-305, Eclipse, and Android.[^051_1]: More about handling platform types in Effective Kotlin, Item 3: Eliminate platform types as soon as possible.
[^051_2]: See Effective Kotlin, Item 31: Respect abstraction contracts.
[^051_3]: Kotlin, when compiled to JVM, uses
Nullable and NotNull annotations from the org.jetbrains.annotations package.