Skip to product information
Kotlin in Action 2/e
Kotlin in Action 2/e
Description
Book Introduction
Kotlin, the official language for Android, is increasingly being used in various fields, including server programming, due to its practicality, simplicity, and interoperability with Java.
The biggest feature of the Kotlin language is its practicality.
This book was also written from a perspective that emphasizes practicality, and can be considered a kind of official book written directly by the Kotlin compiler developers at JetBrains, who developed the Kotlin language.
This book, which has been a de facto Kotlin reference since its first edition in 2017, is now in its second edition, revised for Kotlin 2.0.


This book introduces the basics of Kotlin and explains object-orientation, generics, higher-order functions and functional programming, and the use of the standard collection library.
Here, we will explain in detail how Kotlin has improved the Java language and what to watch out for when using Kotlin together with existing Java projects.
The second half details design and implementation techniques, covering real-world library examples of annotations, reflection, DSLs, and asynchronous programming (suspending functions, coroutines, and flow).
  • You can preview some of the book's contents.
    Preview

index
Part 1: Introduction to Kotlin

Chapter 1: What is Kotlin and Why Do I Need It?

1.1 A Taste of Kotlin
1.2 Key Features of Kotlin
1.2.1 Kotlin Use Cases: Android, Servers, Anywhere Java Runs, and More
1.2.2 Kotlin's performance, reliability, and maintainability are all good due to static typing.
Azim
1.2.3 The combination of functional programming and object-oriented programming makes Kotlin safe and
Be flexible
1.2.4 Coroutines allow you to write concurrent and asynchronous code in a natural and structured way.
there is
1.2.5 Kotlin can be used for all purposes.
Kotlin is open source, and you
is open to contributions
1.3 Areas where Kotlin is frequently used
1.3.1 Backend Support: Kotlin Server Programming
1.3.2 Mobile Development: Android is Kotlin First
1.3.3 Multi-platform: Share business logic across iOS, JVM, JS and other platforms.
Minimize code duplication and ambiguity
1.4 Kotlin's Philosophy
1.4.1 Kotlin is a practical language
1.4.2 Kotlin is concise
1.4.3 Kotlin is safe
1.4.4 Kotlin is interoperable
1.5 Using Kotlin Tools
1.5.1 Setting up and running Kotlin code
1.5.2 Compiling Kotlin Code
summation

Chapter 2: Kotlin Basics

2.1 Basic Elements: Functions and Variables
2.1.1 Writing Your First Kotlin Program: Hello, World!
2.1.2 Declaring a function with parameters and return values
2.1.3 Defining functions more concisely using expression bodies
2.1.4 Declare variables to store data
2.1.5 Marking variables as read-only or reassignable
2.1.6 Formatting Strings Easier: String Templates
2.2 Behavior and Data Encapsulation: Classes and Properties
2.2.1 Associating Classes with Data and Making Them Accessible: Properties
2.2.2 Calculating property values ​​without storing them: Custom accessors
2.2.3 Kotlin Source Code Structure: Directories and Packages
2.3 Selection Expressions and Processing: Inum and when
2.3.1 Enum class and enum constant definitions
2.3.2 Handling enum classes with when
2.3.3 Capturing the target of the when expression in a variable
2.3.4 Using arbitrary objects in when branch conditions
2.3.5 Using when without arguments
2.3.6 Smart Cast: Combining Type Checking and Type Casting
2.3.7 Refactoring: Change if to when
2.3.8 Using blocks in if and when branches
2.4 Target Iteration: while and for loops
2.4.1 Repeating code while a condition is true: the while loop
2.4.2 Iteration over numbers: ranges and permutations
2.4.3 Iteration on the map
2.4.4 Inspecting elements of a collection or range in
2.5 Throwing and Catching Exceptions in Kotlin
2.5.1 Exception handling and error recovery using try, catch, and finally
2.5.2 Using try as an expression
summation

Chapter 3 Function Definition and Calling

3.1 Creating Collections in Kotlin
3.2 Making functions easier to call
3.2.1 Named arguments
3.2.2 Default parameter values
3.2.3 Eliminating Static Utility Classes: Top-Level Functions and Properties
3.3 Adding Methods to Other Classes: Extension Functions and Extension Properties
3.3.1 Import and Extension Functions
3.3.2 Calling Extension Functions from Java
3.3.3 Defining utility functions as extension functions
3.3.4 Extension functions cannot be overridden
3.3.5 Extension Properties
3.4 Collection Handling: Variable-Length Arguments, Infix Function Calls, and Library Support
3.4.1 Java Collection API Extensions
3.4.2 Variadic Functions: Defining functions that can have a variable number of arguments
3.4.3 Handling Pairs (Tuples): Infix Calls and Destructuring Declarations
3.5 Handling Strings and Regular Expressions
3.5.1 Splitting strings
3.5.2 Regular Expressions and Triple-Quoted Strings
3.5.3 Multiline triple-quoted strings
3.6 Cleaning up your code: Local functions and extensions
summation

Chapter 4 Classes, Objects, and Interfaces

4.1 Defining the class hierarchy
4.1.1 Kotlin Interfaces
4.1.2 open, final, abstract modifiers: final by default
4.1.3 Visibility modifier: public by default
4.1.4 Inner and Nested Classes: Nested Classes by Default
4.1.5 Sealed Classes: Defining a Class Hierarchy with Restricted Extensions
4.2 Declaring a class with non-obvious constructors or properties
4.2.1 Class Initialization: Primary Constructor and Initialization Block
4.2.2 Secondary Constructors: Initializing the Superclass in a Different Way
4.2.3 Implementing properties declared in an interface
4.2.4 Accessing fields backed by getters and setters
4.2.5 Changing the visibility of an accessor
4.3 Compiler-generated methods: data classes and class delegation
4.3.1 Methods that every class must define
4.3.2 Data classes: Automatically generate methods that every class must define.
4.4 object keyword: Declare a class and create an instance at the same time
4.4.1 Object Declaration: Creating Singletons Easily
4.4.2 Companion Objects: Where Factory Methods and Static Members Go
4.4.3 Using companion objects like regular objects
4.4.4 Object Expressions: Writing Anonymous Inner Classes Alternatives
4.5 Adding Type Safety Without Extra Cost: Inline Classes
summation

Chapter 5 Programming with Lambda

5.1 Lambda Expressions and Member References
5.1.1 Introducing Lambdas: Treating Code Blocks as Values
5.1.2 Lambdas and Collections
5.1.3 Lambda Expression Grammar
5.1.4 Accessing variables in the current scope
5.1.5 Member Reference
5.1.6 Callable References Associated with Values
5.2 Using Java's Functional Interfaces: Single Abstract Method
5.2.1 Passing Lambdas as Parameters to Java Methods
5.2.2 SAM Conversion: Explicitly Converting Lambdas to Functional Interfaces
5.3 Defining a SAM interface in Kotlin: fun interface
5.4 Lambdas for specifying receiver objects: with, apply,also
5.4.1 with function
5.4.2 apply function
5.4.3 Performing additional operations on objects: also
summation

Chapter 6 Collections and Sequences

6.1 Functional API for Collections
6.1.1 Element Removal and Transformation: Filter and Map
6.1.2 Accumulating Collection Values: reduce and fold
6.1.3 Applying predicates to collections: all, any, none, count, find
6.1.4 Splitting a list into pairs of lists: partition
6.1.5 Converting a list into a map of multiple groups: groupBy
6.1.6 Converting a Collection to a Map: associate, associateWith, associateBy
6.1.7 Changing elements of a mutable collection: replaceAll, fill
6.1.8 Handling Special Cases in Collections: ifEmpty
6.1.9 Splitting a Collection: Chunked and Windowed
6.1.10 Merging Collections: zip
6.1.11 Manipulating Elements of Nested Collections: flatMap and flatten
6.2 Lazy Collection Operations: Sequences
6.2.1 Executing Sequence Operations: Intermediate and Final Operations
6.2.2 Creating a Sequence
summation

Chapter 7: Values ​​that can be null

7.1 Avoiding NullPointerException and Handling Absence of Values: The Possibility of Nulls
7.2 Specifying a variable that can be null as a type that can be null
7.3 A closer look at the meaning of types
7.4 Combining null checking and method calls with the safe call operator: ?.
7.5 Providing a default value for null with the Elvis operator: ?:
7.6 Casting types safely without raising exceptions: as?
7.7 Not you assertion: !!
7.8 let function
7.9 Non-null types that are not directly initialized: lazy initialization properties
7.10 Type extensions without safe call operators: Extensions to nullable types
7.11 Nullability of Type Parameters
7.12 Null Possibility and Java
7.12.1 Platform Type
7.12.2 Inheritance
summation

Chapter 8 Basic Types, Collections, and Arrays

8.1 Primitive and Basic Types
8.1.1 Representing integers, floating-point numbers, characters, and boolean values ​​as primitive types
8.1.2 Using the full bit range to represent positive numbers: unsigned number types
8.1.3 Primitive types that can be null: Int?, Boolean?, etc.
8.1.4 Number Conversion
8.1.5 Any and Any?: The Roots of Kotlin's Type Hierarchy
8.1.6 Unit Type: Kotlin's Void
8.1.7 Nothing type: This function never returns.
8.2 Collections and Arrays
8.2.1 Collections of values ​​that can be null and collections that can be null
8.2.2 Read-only and mutable collections
8.2.3 Kotlin collections and Java collections are closely related.
8.2.4 Collections declared in Java appear as platform types in Kotlin.
8.2.5 Creating arrays of objects or arrays of primitive types for performance and interoperability
summation

Part 2: Using Kotlin the Kotlin Way

Chapter 9 Operator Overloading and Other Conventions

9.1 Overloading arithmetic operators to make operations on arbitrary classes more convenient
9.1.1 plus, times, divide, etc.: Overloading Binary Arithmetic Operations
9.1.2 Applying an operation and then assigning the result directly: Compound assignment operator overload
Ding
9.1.3 Operators with Only One Operand: Unary Operator Overloading
9.2 Easily check relationships between objects by overloading comparison operators.
9.2.1 Equality Operator: equals
9.2.2 Order Operators: compareTo (〈, 〉, 〈=, 〉=)
9.3 Conventions for Writing About Collections and Ranges
9.3.1 Accessing elements by index: get and set
9.3.2 Checking if an object is in a collection: the in convention
9.3.3 Creating Ranges from Objects: The rangeTo and rangeUntil Conventions
9.3.4 Looping over your own type: the iterator convention
9.4 Providing destructuring declarations using component functions
9.4.1 Destructuring Declarations and Loops
9.4.2 _ Ignoring destructuring values ​​using characters
9.5 Reusing Property Accessor Logic: Delegated Properties
9.5.1 Basic syntax and internal operation of delegated properties
9.5.2 Using Delegated Properties: Lazy Initialization with by lazy()
9.5.3 Implementing Delegated Properties
9.5.4 Delegated properties are converted to hidden properties with custom accessors.
9.5.5 Dynamically accessing attributes by delegating to a map
9.5.6 How Real-World Frameworks Use Delegated Properties
summation

Chapter 10 Higher-Order Functions: Using Lambdas as Parameters and Return Values

10.1 Defining functions that take other functions as arguments or return other functions: Higher-order functions
10.1.1 The function type specifies the parameter types and return type of the lambda.
10.1.2 Calling a function passed as an argument
10.1.3 Using Kotlin Function Types in Java
10.1.4 You can specify default values ​​for parameters of function type, and they can be null.
there is
10.1.5 Returning a function from a function
10.1.6 Using Lambda to Reduce Duplication and Increase Code Reusability
10.2 Eliminating the overhead of lambdas using inline functions
10.2.1 How Inlining Works
10.2.2 Restrictions on inline functions
10.2.3 Collection Operation Inlining
10.2.4 Deciding When to Declare a Function Inline
10.2.5 Using Inlined Lambdas for Resource Management with withLock, use, and useLines
10.3 Returning from Lambdas: Controlling Flow in Higher-Order Functions
10.3.1 Return statement in lambda: Returning from the function surrounding the lambda
10.3.2 Returning from Lambdas: Returning with Labels
10.3.3 Anonymous functions: local return by default
summation

Chapter 11 Generics

11.1 Creating types that take type arguments: Generic type parameters
11.1.1 Functions and properties that work with generic types
11.1.2 Declare a generic class using square bracket syntax
11.1.3 Restricting the types that can be used by generic classes or functions: Type parameter restrictions
approximately
11.1.4 Excluding nullable type arguments by explicitly marking type parameters as non-nullable
11.2 Runtime Generics Behavior: Erased and Reified Type Parameters
11.2.1 Limitations when finding type information for generic classes at runtime: Type checking and
Casting
11.2.2 A function that uses an instantiated type parameter returns the type argument at runtime.
can be mentioned
11.2.3 Replacing class references with instantiated type parameters in java.lang.Class
Avoiding parameters
11.2.4 Defining Accessors with Reified Type Parameters
11.2.5 Constraints on Materialized Type Parameters
11.3 Variance describes the subtype relationship between a generic and its type arguments.
11.3.1 Variance allows us to determine whether it is safe to pass arguments to a function.
11.3.2 Classes, Types, and Subtypes
11.3.3 Covariance preserves subtype relationships
11.3.4 Contravariance reverses subtyping relationships
11.3.5 Specifying variance at the point where a type is mentioned using point-of-use variance
11.3.6 Star Projection: Using * to indicate that there is no information about a generic type argument
11.3.7 Type Alias
summation

Chapter 12 Annotations and Reflection

12.1 Declaring and applying annotations
12.1.1 Marking declarations with annotations
12.1.2 Specifying the exact declarations an annotation can reference: Annotation Targets
12.1.3 Controlling JSON Serialization Using Annotations
12.1.4 Annotation Declaration
12.1.5 Metaannotations: Controlling How Annotations Are Processed
12.1.6 Using classes as annotation parameters
12.1.7 Receiving a generic class as an annotation parameter
12.2 Reflection: Observing Kotlin Objects at Runtime
12.2.1 Kotlin Reflection API: KClass, KCallable, KFunction, KProperty
12.2.2 Implementing Object Serialization Using Reflection
Control serialization using the 12,2,3 annotations
12.2.4 JSON Parsing and Object Deserialization
12.2.5 Final Deserialization Step: Creating Objects Using CallBy() and Reflection
summation

Chapter 13: Creating a DSL

13.1 From API to DSL: Creating Expressive Custom Code Structures
13.1.1 Domain-Specific Languages
13.1.2 The internal DSL integrates seamlessly with the rest of the program.
13.1.3 DSL Structure
13.1.4 Creating HTML with an Internal DSL
13.2 Building a Structured API: Using Lambdas to Specify Received Objects in the DSL
13.2.1 Lambda and extension function types for specifying receiver objects
13.2.2 Using a lambda specifying a receiver object within an HTML builder
13.2.3 Kotlin Builders: Enabling Abstraction and Reuse
13.3 Using the invoke convention to nest blocks more flexibly
13.3.1 Using the invoke convention to nest blocks more flexibly
13.3.2 DSL Invoke Conventions: Declaring Gradle Dependencies
13.4 Kotlin DSL in Practice
13.4.1 Chaining Intermediate Calls: The Test Framework's Should Function
13.4.2 Defining Extension Functions for Primitive Types: Date Handling
13.4.3 Member Extension Functions: An Internal DSL for SQL
summation

Part 3: Concurrent Programming with Coroutines and Flow

Chapter 14 Coroutines


14.1 Concurrency and Parallelism
14.2 How to Handle Concurrency in Kotlin: Suspending Functions and Coroutines
14.3 Comparison of Threads and Coroutines
14.4 Functions that can pause: Suspend functions
14.4.1 Code using the suspend function appears sequential.
14.5 Comparing Coroutines with Other Approaches
14.5.1 Calling the Suspend Function
14.6 Entering the World of Coroutines: Coroutine Builder
14.6.1 From Regular Code to the World of Coroutines: The runBlocking Function
14.6.2 Creating a Forget-After-Launch Coroutine: The Launch Function
14.6.3 Waitable Operations: Async Builders
14.7 Deciding Where to Run Code: The Dispatcher
14.7.1 Selecting a Dispatcher
14.7.2 Passing a Dispatcher to a Coroutine Builder
14.7.3 Changing the dispatcher within a coroutine using withContext
14.7.4 Coroutines and dispatchers are not a magic solution to thread safety problems.
no
14.8 Coroutines contain additional information in their coroutine context.
summation

Chapter 15 Structured Concurrency

15.1 Coroutine scope establishes structure between coroutines.
15.1.1 Creating a Coroutine Scope: The coroutineScope Function
15.1.2 Associating a Coroutine Scope with a Component: CoroutineScope
15.1.3 Risks of GlobalScope
15.1.4 Coroutine Contexts and Structured Concurrency
15.2 Cancellation
15.2.1 Cancellation Trigger
15.2.2 Automatically cancel call after time limit is exceeded
15.2.3 Cancellation propagates to all child coroutines.
15.2.4 A cancelled coroutine throws a CancellationException at a special point.
15.2.5 Cancellation is cooperative
15.2.6 Checking if a coroutine has been cancelled
15.2.7 Giving Other Coroutines a Chance: The Yield Function
15.2.8 Keep cancellation in mind when acquiring resources
15.2.9 The framework can cancel for you.
summation

Chapter 16 Flow

16.1 Flow models a stream of continuous values.
16.1.1 Flow allows you to process elements as soon as they are emitted.
16.1.2 Different Types of Kotlin Flow
16.2 Cold Flow
16.2.1 Creating a cold flow using the flow builder function
16.2.2 Cold flow does not perform any work until it is collected.
16.2.3 Cancel Flow Collection
16.2.4 Internal Implementation of Cold Flow
16.2.5 Concurrent Flows Using Channel Flows
16.3 Hot Flow
16.3.1 A shared flow broadcasts values ​​to subscribers.
16.3.2 Tracking System State: State Flow
16.3.3 Comparison of State Flow and Shared Flow
16.3.4 Hot Flow, Cold Flow, Shared Flow, Stateful Flow: When to Use Which Flow?
summation

Chapter 17 Flow Operators

17.1 Manipulating Flow with Flow Operators
17.2 Intermediate operators are applied to the upstream flow and return the downstream flow.
17.2.1 Emitting random values ​​for each upstream element: the transform function
17.2.2 take and related operators can cancel the flow
17.2.3 Hooking each step of the flow: onStart, onEach, onCompletion, onEmpty
17.2.4 Element Buffering for Downstream Operators and Collectors: The Buffer Operator
17.2.5 Operator that discards intermediate values: conflate operator
17.2.6 Operator to filter values ​​over a period of time: debounce operator
17.2.7 Changing the coroutine context in which a flow is executed: The flowOn operator
17.3 Creating Custom Intermediate Operators
17.4 The final operator executes the upstream flow and computes the value.
17.4.1 The framework provides custom operators.
summation

Chapter 18 Error Handling and Testing

18.1 Handling Errors Thrown Inside Coroutines
18.2 Error Propagation in Kotlin Coroutines
18.2.1 A coroutine that cancels all children if a child fails.
18.2.2 Structured concurrency only affects exceptions that extend the coroutine scope.
18.2.3 Supervisors ensure that parents and siblings are not cancelled.
18.3 CoroutineExceptionHandler: A Last Resort for Exception Handling
18.3.1 Differences between applying CoroutineExceptionHandler to launch and async
18.4 Exception Handling in Flow
18.4.1 Handling Upstream Exceptions with the Catch Operator
18.4.2 Retrying the collection of flows when the predicate is true: the retry operator
18.5 Coroutines and Flow Testing
18.5.1 Quickly Writing Tests Using Coroutines: Virtual Time and the Test Dispatcher
18.5.2 Flow Test with Turbine
summation

Appendix A Building a Kotlin Project
Appendix B Documenting Kotlin Code
Appendix C: Kotlin Ecosystem

Publisher's Review
◈ What this book covers ◈

◆ Guide from Kotlin Team Members
◆ Domain-Specific Language (DSL)
◆ Kotlin Coroutines and Flow

◈ Target audience of this book ◈

This book is primarily aimed at developers with some Java experience.
Kotlin builds on many concepts and techniques found in Java, and this book leverages readers' existing knowledge to help them quickly learn Kotlin.

Readers with experience with other programming languages, such as C# or JavaScript, will need other resources to understand the intricacies of Kotlin's interaction with the JVM, but they can still use this book to learn Kotlin.
This book covers the entire Kotlin language and does not focus on any specific problem domain.
So it will be helpful for server developers, Android developers, or any developer building projects to run on the JVM.

◈ Author's Note ◈

The idea for the Kotlin language originated at JetBrains in 2010.
At the time, JetBrains was a well-known and fairly successful company that provided development tools for various languages ​​such as Java, C#, JavaScript, Python, Ruby, and PHP.
JetBrains' flagship product, the Java IDE IntelliJ IDEA, also includes plugins to assist with Scala and Groovy development.

Our experience developing tools for such a diverse range of languages ​​has given us a unique perspective and understanding of the entire programming language landscape.
And all IDEs that use IntelliJ as a platform, including IntelliJ IDEA itself, were developed in Java.
We were so envious of our colleagues on the .Net team who were developing in C#, a modern, powerful, and fast-evolving language, but we couldn't find a language that could replace Java.
What requirements did we have for a language to replace Java?

The first and most obvious requirement was static typing.
There is no other way to develop a code base that is millions of lines long without going crazy, other than static typing.
Second, we needed a language that was fully compatible with existing Java code.
Our existing codebase is an incredibly valuable asset to JetBrains, and we couldn't afford to lose it or have its value diminished due to lack of interoperability.
Thirdly, we did not want to compromise on tool availability.
As a company, JetBrains' most important value is development productivity, and achieving high productivity requires great tools.
Finally, we needed a language that was easy to learn and easy to reason about the code.

Around the time we discovered this unmet need within our company, we realized that some companies were in a similar situation.
Therefore, we could expect that if we could create a solution that could meet the needs within JetBrains, we would find more users outside of JetBrains.
With this in mind, we decided to start a project to create a new language: Kotlin.

The development period for the language has been longer than initially expected, and Kotlin 1.0 was released more than five years after the first repository commit.
Since then, Kotlin has found a user base that wants it, and its own ecosystem has developed beautifully, and that progress continues to this day.

Kotlin is based in St. Petersburg, Russia.
It is the name of an island near St. Petersburg.
The choice of the island's name follows the traditions of the Javanese and Ceylonese languages.

As Kotlin's official release nears, I thought it would be helpful to have a book written by people who were involved in the design of the language and can confidently explain why the language's features are the way they are.
This book is part of that effort, and I hope that readers will learn and understand the Kotlin language better through this book.
Good luck and I hope you always have fun developing.

◈ Translator's Note ◈

In 2017, when the first edition of this book was translated, Kotlin was beginning to be used in earnest on Android, and functional programming concepts were slowly entering the mainstream programming language world through Scala, Hadoop, and others.
So, the 'Translator's Note' of the first edition had to explain the relevant content at length.
However, as time goes by, Kotlin has become firmly established in Android programming, the number of developers and companies using Kotlin in server programming has increased significantly, and the concept of functional programming has also become firmly established to some extent, so I think it is no longer necessary to explain the features or advantages of the Kotlin language and the features or advantages of functional programming.
Any developer who picks up this book will be ready to fall in love with the language just by hearing the name Kotlin.

Kotlin is now moving beyond its position as a better Java replacement on the JVM to establish itself as a standalone programming language with its own concurrent programming framework and multi-platform support.
Through this book, you can learn the basic philosophy and grammar of the Kotlin language, collection processing using basic functional programming techniques, internal DSL and rich API development methods using the Kotlin language's DSL support features, and concurrent/parallel programming using Kotlin coroutines and Flow.
You will also learn how to use Java and Kotlin together in your projects on the JVM.
Developers who have a solid foundation in Kotlin through this book will be able to utilize Kotlin in various fields, such as developing multi-platform apps through Compose Multiplatform or developing clean architecture servers that integrate Java libraries such as Spring.
For example, Mobility42, where the translator works, has developed its own Kotlin multi-platform library and is using it to develop various applications such as servers (database modeling using its own Spring-based server library and internal DSL), web (JavaScript + its own developed component library), and Compose Desktop.

I sincerely hope that through this book, Kotlin will become a tool that you can comfortably use when working, like a well-crafted club that fits comfortably in your hand.
And I hope that the increased productivity you gain through Kotlin will allow you to enjoy more leisurely evenings.
GOODS SPECIFICS
- Date of issue: February 27, 2025
- Page count, weight, size: 804 pages | 188*235*37mm
- ISBN13: 9791161759692
- ISBN10: 1161759697

You may also like

카테고리