Java and Kotlin: A Comprehensive Guide to New and Key Features Across Versions
Java and Kotlin: A Comprehensive Guide to New and Key Features Across Versions ź“ė Ø
Introduction
In the previous article (kotlin-academy
), I explored which version of Java and Kotlin you can or cannot use depending on your AGP, Android Studio etc.. Lets continue that journey by specifying which features you have in each version of Java and Kotlin. It never hurts to refresh our memory from time to time right?
Java and Kotlin are the two core languages for Android development. While Java has been around for decades, Kotlinās rise as a modern alternative has made it an official language for Android. Keeping up with the latest language features is crucial for writing optimized, clean, and maintainable code. This guide outlines the most important features introduced in each version of Java and Kotlin, with a focus on Android development.
Java Features by Version
Java 8 (2014)
Java 8 is still the most widely used version in Android development due to its long-lasting support. Key features include:
Simplifies the syntax for anonymous classes.
List<String> names = Arrays.asList("John", "Jane", "Doe");
names.forEach(name -> System.out.println(name));
Used for functional-style operations on collections.
List<String> names = Arrays.asList("John", "Jane", "Doe");
names.stream().filter(name -> name.startsWith("J"))
.forEach(System.out::println);
Allows interfaces to have default method implementations.
interface Walkable {
default void walk() {
System.out.println("Walking...");
}
}
Java 9 (2017)
Module System (Project Jigsaw)
Organizes large codebases into modules for better encapsulation.
JShell (REPL)
Java introduced a Read-Eval-Print Loop (REPL) tool for testing code snippets interactively.
Java 10 (2018)
Local-Variable Type Inference (var
)
Allows you to declare variables without specifying their types explicitly.
var list = List.of("Apple", "Banana", "Orange");
Java 11 (2018 ā LTS)
HTTP Client API
Introduces a standard HTTP client to replace HttpURLConnection
.
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com"))
.build();
Java 14 (2020)
Switch Expressions (Preview)
Improves the switch statement with a new concise syntax.
String result = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> "Weekend";
case TUESDAY -> "Weekday";
default -> "Unknown";
};
Java 17 (2021 ā LTS)
Sealed Classes
Restricts which other classes can extend a class, improving security and code readability.
public sealed class Shape permits Circle, Rectangle {
// Codeā¦
}
Kotlin Features by Version
Kotlin 1.0 (2016)
Prevents null pointer exceptions.
val name: String? = null
println(name?.length)
Allows you to add functions to classes without modifying their source code.
fun String.addExclamation(): String = this + "!"
println("Hello".addExclamation())
Kotlin 1.1 (2017)
Coroutines (Experimental)
Simplifies asynchronous programming by eliminating callbacks.
GlobalScope.launch {
val result = async { someLongRunningTask() }
println(result.await())
}
Kotlin 1.3 (2018)
Stable Coroutines*
Coroutines become officially stable and a key part of Android development.
Inline Classes (Experimental)
Inline classes provide an efficient way to define types that avoid allocation.
inline class UserId(val id: String)
Kotlin 1.4 (2020)
SAM Conversion for Kotlin Interfaces
In Kotlin 1.4,Ā SAM ConversionĀ allows you to pass lambda expressions for single abstract method (SAM) interfaces directly, without the need to explicitly create an object or override the method. This simplifies the code when using functional interfaces.
Example
Before Kotlin 1.4 (Without SAM Conversion for Kotlin Interfaces)
If you wanted to use aĀ Runnable
Ā in Kotlin (which has only one methodĀ run()
), you had to instantiate it like this:
val runnable: Runnable = Runnable {
println("Running with SAM conversion...")
}
Thread(runnable).start()
Kotlin 1.4 (With SAM Conversion for Kotlin Interfaces)
With SAM conversion, you can pass a lambda directly:
val runnable: Runnable = Runnable {
println("Running with SAM conversion...")
}
Thread(runnable).start()
Alternatively, you can pass the lambda directly in the constructor if the interface expects it:
Thread {
println("Running directly with lambda!")
}.start()
This makes the code more concise and easier to read, especially when dealing with functional interfaces or APIs that use single abstract methods like event listeners or background tasks.
Kotlin 1.5 (2021)
ā Sealed Interfaces
Sealed interfaces in Kotlin 1.5 extend the concept of sealed classes to interfaces, allowing you to control which types can implement an interface. Like sealed classes, sealed interfaces ensure that all possible implementations are known at compile time, enabling the compiler to enforce exhaustiveĀ when
Ā statements. This is especially useful when modeling hierarchies where only a specific set of types is allowed, improving code safety and clarity. By restricting the set of implementors, sealed interfaces prevent unexpected or unintended classes from implementing the interface, which can reduce runtime errors.sealed interface Shape
ā Value Classes (Experimental)
Value classes in Kotlin, introduced as an experimental feature, provide a way to wrap a value in a type while avoiding the overhead of creating a full-fledged object. By using theĀ @JvmInline
Ā annotation, the compiler treats the value class as an inline type, meaning the wrapped value is directly used in memory without additional allocation. This leads to more efficient memory usage, especially for simple data types likeĀ String
,Ā Int
, orĀ Long
, which are frequently used in performance-critical parts of the code.@JvmInline
value class Password(val value: String)
Kotlin 1.6 (2021)
ā Stable Value Classes
Value classes are now stable, offering better memory efficiency.
Kotlin 1.9 (2023)
ā Optimized JVM performance
Improvements that make Kotlin code run more efficiently on the JVM.
Impact on Android Development
- Java: While Androidās runtime (ART) supports Java 8, most of the new language features in later versions like local variable inference (
var
), records, and sealed classes are unavailable unless using third-party libraries like D8 desugaring. - Kotlin: Kotlin is highly integrated into Android development. Features like coroutines are essential for handling background tasks without blocking the UI, making Kotlin a popular choice for Android apps.
Conclusion
Staying updated on Java and Kotlin versions ensures that developers can take advantage of the latest improvements in code efficiency, readability, and performance. While Androidās support for newer Java features is limited, Kotlinās integration with Android is growing stronger with every release, making it the go-to choice for modern Android development.
Dobri Kostadinov
Android Consultant | Trainer
Email meĀ |Ā Follow me on LinkedIn (dobrikostadinov
)Ā |Ā Follow me on Medium (dobri.kostadinov
)Ā |Ā Buy me a coffee
This article is previously published on proandroiddev.com (proandroiddev
)com