Chapter 2: Kotlin basics
This chapter introduction previews Kotlin basics and explains what it means to write idiomatic Kotlin.
After this chapter you will be able to
- Idiomatic Kotlin Code. Explain what idiomatic Kotlin means and how a developer develops a feel for it.
- Top-level main function. Explain how Kotlin declares an application entry point: use fun to declare main, which can appear at the top level of a file without a class or additional arguments.
- Function declaration and calls. Describe the syntax for declaring a function that takes parameters and returns a value, and how to call it. Use the max example to identify the parameters, their types, and the returned result.
- Expressions and assignment statements. Distinguish expressions from statements in Kotlin, explaining why if can provide a value for a result but an assignment cannot.
- Expression and block bodies. Describe how to turn a single-expression function such as max into an expression-body function, and distinguish it from a block-body function.
- Expression body return inference. Explain how Kotlin determines an omitted return type for an expression-body function and why the same omission is not allowed for a value-returning block-body function.
- Variable declaration form. Describe a Kotlin variable declaration as a `val` or `var` keyword followed by a name, with an optional explicit type after the name.
- Initializer-based type inference. Explain that, when a variable has an initializer and no explicit type, the compiler uses the initializer’s type; if initialization happens later, the type must be specified explicitly.
- Read-only and reassignable references. Distinguish val from var: a val reference can be assigned once, while a var reference can be reassigned. Explain why the section recommends starting with val and using var only when needed.
- Reference versus object mutability. Distinguish an unchangeable val reference from the mutability of the object it refers to, using the section’s mutable-list example.
- Variable interpolation in strings. Explain how to insert a local variable into a Kotlin string with `$`, how this compares with concatenation, and how to include a literal dollar sign.
- Expressions inside string templates. Describe how curly braces let a string template insert the result of an expression, including an `if` expression that chooses the greeting text.
- Concise Kotlin class declarations. Explain why a simple data-holding class can be shorter in Kotlin than in Java, using the Person example.
- Property declarations and accessors. Explain how val and var declare class properties and what accessors Kotlin provides for each.
- Property access across languages. Describe how Kotlin and Java access properties, including how Kotlin treats Java getter and setter methods as properties.
- Computed property getters. Explain how Rectangle's isSquare property can use a custom getter to compare width and height whenever the property is accessed, rather than storing a separate value.
- Package membership of declarations. Explain how a package statement assigns the declarations in a Kotlin file to a package.
- Flexible Kotlin source layout. Distinguish Kotlin's file and directory layout rules from Java's, and explain the recommended practice for mixed projects.
- When compared with switch. Explain how the section positions Kotlin’s `when` construct relative to Java’s `switch`.
- Enum declaration and keywords. Describe Kotlin’s `enum class` declaration and distinguish the soft keyword `enum` from the hard keyword `class`.
- Data and behavior on constants. Explain how the Color enum can associate each constant with RGB components and define a computed property and a method.
- Value Returning When Expression. Explain that Kotlin’s `when` is an expression that returns a value, so a function can return it directly from an expression body.
- Enum Branch Matching And Grouping. Describe how `when` selects the branch matching an enum value, executes only that branch without a `break`, and can put multiple values in one branch by separating them with commas.
- Local when subject variable. Explain why a when expression can capture its subject in a variable and where that variable can be used.
- Order Independent Color Pairs. Explain why comparing sets lets the mix function recognize the same two colors in either order.
- Object Matching And Default Branch. Describe how when matches the color set against its branches and why the mix function needs an else branch.
- Argumentless when branch conditions. Explain that when a when expression has no argument, each branch condition can be any Boolean expression.
- Recursive expression evaluation. Explain how evaluation handles each of the two expression types.
- Type checks and smart casts. Explain how an `is` check lets Kotlin access subtype-specific properties without an explicit cast, and when that smart cast is valid.
- Type-Checking When Branches. Describe how a `when` expression can replace a cascade of `if` expressions in `eval` by checking argument types and using smart casts.
- Results of block branches. Explain how an if or when branch can perform multiple actions in a block while producing a result, and distinguish this rule from returns in a regular function with a block body.
- Basic Kotlin loop forms. Describe the two loop forms introduced here: while uses a traditional form familiar from other languages, and for uses `for (<item> in <elements>)`, resembling Java’s for-each loop.
- Labels in nested loops. Explain how to declare a label for a nested loop and how break or continue can refer to it.
- Range boundaries and iteration. Explain how a Kotlin for loop iterates over an integer range, and distinguish the inclusive `..` range from the half-open `..<` range.
- Progression direction and step. Describe how a progression visits values and how `downTo` and `step` change a numeric loop.
- Map entry unpacking. Explain how a for loop can unpack each map entry into a key and a value. Describe how the example uses a character range from A through F to fill the map.
- Map bracket access. Distinguish reading a map value with map[key] from setting one with map[key] = value, as illustrated by binaryReps[char] = binary.
- Range membership checks. Explain how `in` checks whether a value belongs to a range and `!in` checks whether it does not, using character validation as an example.
- Exception handling and propagation. Explain that a Kotlin function can finish normally or throw an exception when an error occurs, and that its caller can catch and process the exception or let it propagate up the stack.
- Throw as an expression. Describe how Kotlin uses the throw keyword to raise an exception and allows throw within another expression. Explain that, in the percentage example, a valid condition initializes percentage with number, while the other path throws and leaves it uninitialized.
- Exception recovery with try. Describe how try with catch and finally is used to handle exceptions, including the example that returns a parsed number or null when a line is not a valid number.
- Kotlin exception handling choice. Distinguish Kotlin’s exception rules from Java’s checked-exception rules and explain why Kotlin leaves handling decisions to the programmer.
- Try expression result. Explain how a try expression can be assigned to a variable and how its result is chosen when the try block succeeds or an exception is caught.
Section by section
Introduction
This chapter introduction previews Kotlin basics and explains what it means to write idiomatic Kotlin.
- Idiomatic Kotlin Code: Explain what idiomatic Kotlin means and how a developer develops a feel for it.
Why it matters: It gives you a way to distinguish code that merely works from code that feels natural to Kotlin developers.
Key terms: idiomatic Kotlin, idioms, syntactic sugar
2.1 Basic elements: Functions and variables
The section previews the introduction of Kotlin functions and variables, type inference, and a preference for avoiding mutable data.
2.1.1 Writing your first Kotlin program: “Hello, world!”
Introduces a minimal Kotlin “Hello, world!” program and uses it to point out basic function and output syntax.
- Top-level main function: Explain how Kotlin declares an application entry point: use fun to declare main, which can appear at the top level of a file without a class or additional arguments.
Why it matters: These are the pieces needed to recognize the structure of the first Kotlin program. - Concise console output syntax: Describe how the example displays text with println and why the section presents that call as concise; state whether a line-ending semicolon is needed.
Why it matters: It shows how the small example avoids Java-style ceremony.
Key terms: fun, main function, top level, entry point, println, Kotlin standard library, semicolon
2.1.2 Declaring functions with parameters and return values
This section explains how to declare and call a Kotlin function with parameters and a return value, and why expressions such as if can supply a result while assignments cannot.
- Function declaration and calls: Describe the syntax for declaring a function that takes parameters and returns a value, and how to call it. Use the max example to identify the parameters, their types, and the returned result.
Why it matters: This is the basic syntax for writing functions that compute results and for using those functions. - Expressions and assignment statements: Distinguish expressions from statements in Kotlin, explaining why if can provide a value for a result but an assignment cannot.
Why it matters: The distinction explains both how a conditional can compute a function’s result and why assignment cannot be used as a value. - Main function signature: State the parameter options and return behavior of Kotlin’s main function, including what its string-array elements represent.
Why it matters: It clarifies how the program’s entry point differs from a function written to return a computed result.
Key terms: fun, parameter, Int, return type, arguments, expression, statement, if, assignment, main
2.1.3 Making function definitions more concise by using expression bodies
This section shows how expression bodies shorten Kotlin functions, how their return types can be inferred, and when explicit return types remain useful.
- Expression and block bodies: Describe how to turn a single-expression function such as max into an expression-body function, and distinguish it from a block-body function.
Why it matters: This distinction helps you read and write concise Kotlin functions. - Expression body return inference: Explain how Kotlin determines an omitted return type for an expression-body function and why the same omission is not allowed for a value-returning block-body function.
Why it matters: It explains why a function can lack a written return type while remaining statically typed. - Explicit public API return types: Justify specifying return types for functions in a library’s public API even when Kotlin could infer them.
Why it matters: A convenient shorthand in your implementation can become a compatibility problem for library users.
Key terms: expression body, block body, type inference, return type, inferred return types, public API, signature changes
2.1.4 Declaring variables to store data
This section shows how to declare Kotlin variables and when their types can be inferred from initializers.
- Variable declaration form: Describe a Kotlin variable declaration as a `val` or `var` keyword followed by a name, with an optional explicit type after the name.
Why it matters: This is the basic form you need to recognize and write variables in Kotlin. - Initializer-based type inference: Explain that, when a variable has an initializer and no explicit type, the compiler uses the initializer’s type; if initialization happens later, the type must be specified explicitly.
Why it matters: It tells you when you can omit a type and when the compiler needs you to supply one.
Key terms: variable declaration, val, var, type, type inference, initializer expression, Int, Double
2.1.5 Marking a variable as read only or reassignable
This section explains how val and var control reassignment, why val is preferred, and what those declarations do not change about objects or variable types.
- Read-only and reassignable references: Distinguish val from var: a val reference can be assigned once, while a var reference can be reassigned. Explain why the section recommends starting with val and using var only when needed.
Why it matters: Choosing val by default makes unintended reassignment less likely. - Conditional val initialization: Explain how a val can receive different values on different branches of a condition without becoming reassignable.
Why it matters: A result chosen by a condition can still be declared val when it is assigned only once. - Reference versus object mutability: Distinguish an unchangeable val reference from the mutability of the object it refers to, using the section’s mutable-list example.
Why it matters: This distinction prevents mistaking a read-only reference for an immutable object. - Fixed type of var: Explain why a var can be reassigned but cannot later hold a value of an incompatible type, and how its type is inferred when declared with an initializer.
Why it matters: Knowing that var changes values, not types, helps explain incompatible-assignment errors.
Key terms: val, var, read-only reference, reassignable reference, initialized exactly once, val reference, mutable list, read only, String, Int
2.1.6 Easier string formatting: String templates
This section shows how Kotlin string templates insert variables and expressions into strings, including a greeting chosen from user input.
- Variable interpolation in strings: Explain how to insert a local variable into a Kotlin string with `$`, how this compares with concatenation, and how to include a literal dollar sign.
Why it matters: You can format strings without assembling them through concatenation. - Expressions inside string templates: Describe how curly braces let a string template insert the result of an expression, including an `if` expression that chooses the greeting text.
Why it matters: You can calculate or choose text directly where it appears in a string.
Key terms: string templates, $, string concatenation, expression, curly braces, if expression
2.2 Encapsulating behavior and data: Classes and properties
Introduces Kotlin classes by comparing a simple Java Person class with its shorter Kotlin equivalent and noting Kotlin’s default public visibility.
- Concise Kotlin class declarations: Explain why a simple data-holding class can be shorter in Kotlin than in Java, using the Person example.
Why it matters: This comparison shows why Kotlin classes containing mainly data can be much more concise. - Default public visibility: State why the public modifier disappears when the Person class is converted from Java to Kotlin.
Why it matters: It explains one visible difference between the Java and Kotlin class declarations.
Key terms: class, property, getter function, boilerplate, public, default visibility
2.2.1 Associating data with a class and making it accessible: Properties
Explains how Kotlin properties package class data with accessors and how Java and Kotlin code access them.
- Property declarations and accessors: Explain how val and var declare class properties and what accessors Kotlin provides for each.
Why it matters: A short property declaration provides the data access that would require fields and accessor methods in Java. - Property access across languages: Describe how Kotlin and Java access properties, including how Kotlin treats Java getter and setter methods as properties.
Why it matters: Property syntax makes Kotlin code concise without preventing access from Java or to Java classes.
Key terms: property, val, var, getter, setter, backing field, property syntax, getName, isStudent, setStudent
2.2.2 Computing properties instead of storing their values: Custom accessors
This section shows how a custom getter can compute a property from other properties and explains when that characteristic is better expressed as a property than a member function.
- Computed property getters: Explain how Rectangle's isSquare property can use a custom getter to compare width and height whenever the property is accessed, rather than storing a separate value.
Why it matters: A computed property can present a derived characteristic without storing a value that duplicates other data. - Getter expression-body syntax: Describe the shorter expression-body form of the getter and what the compiler can infer from it.
Why it matters: The concise getter changes how the property is defined, not how Kotlin code reads it. - Property versus member function: Distinguish when to express something as a property with a custom getter rather than as a member function.
Why it matters: Choosing the form that matches the meaning makes a class easier to read.
Key terms: custom getter, property accessor, isSquare, expression-body syntax, type inference, property, member function
2.2.3 Kotlin source code layout: Directories and packages
This section explains how Kotlin packages organize declarations, how imports make declarations available across packages, and how source-file layout relates to package structure.
- Package membership of declarations: Explain how a package statement assigns the declarations in a Kotlin file to a package.
Why it matters: Packages give declarations an organizational home as a project grows. - Imports across package boundaries: Describe when declarations need importing and what Kotlin's import and wildcard import can make available.
Why it matters: Imports let code use declarations across package boundaries without treating functions differently from classes. - Flexible Kotlin source layout: Distinguish Kotlin's file and directory layout rules from Java's, and explain the recommended practice for mixed projects.
Why it matters: Kotlin gives you layout flexibility while leaving a familiar directory convention useful for maintaining mixed-language projects.
Key terms: package statement, package, declarations, import, star import, wildcard import, top-level functions, source files, directory structure, package structure
2.3 Representing and handling choices: Enums and when
Introduces Kotlin’s `when` construct as a more powerful, commonly used alternative to Java’s `switch`, while previewing enums and smart casts.
- When compared with switch: Explain how the section positions Kotlin’s `when` construct relative to Java’s `switch`.
Why it matters: This comparison gives Java developers a familiar starting point for understanding `when`.
Key terms: when construct, switch construct
2.3.1 Declaring enum classes and enum constants
This section introduces Kotlin enum declarations and shows how color constants can carry properties and methods.
- Enum declaration and keywords: Describe Kotlin’s `enum class` declaration and distinguish the soft keyword `enum` from the hard keyword `class`.
Why it matters: It helps you recognize an enum declaration without assuming both words are reserved in the same way. - Data and behavior on constants: Explain how the Color enum can associate each constant with RGB components and define a computed property and a method.
Why it matters: An enum can represent more than a set of names: its constants can carry useful data and behavior. - Enum method separator: State when a semicolon is required in the enum class shown here and what it separates.
Why it matters: The separator makes the boundary between constants and methods clear in an enum declaration.
Key terms: enum class, soft keyword, hard keyword, enum constants, r, g, and b, rgb, printColor, semicolon, enum constant list, method definitions
2.3.2 Using the when expression to deal with enum classes
Introduces `when` as a value-returning way to choose behavior for enum constants, including grouped branches and shorter names through imports.
- Value Returning When Expression: Explain that Kotlin’s `when` is an expression that returns a value, so a function can return it directly from an expression body.
Why it matters: This lets you use `when` to write a concise function that chooses and returns a result. - Enum Branch Matching And Grouping: Describe how `when` selects the branch matching an enum value, executes only that branch without a `break`, and can put multiple values in one branch by separating them with commas.
Why it matters: Grouping values avoids repeated branches, while the lack of fallthrough avoids a common switch-statement error. - Imported Enum Constant Names: Explain that importing enum constants lets a `when` expression refer to them without repeatedly writing the enum class name.
Why it matters: It makes a `when` with many enum constants less repetitive to read and write.
Key terms: when, expression body, when branch, enum constants, break, importing, Color enum class
2.3.3 Capturing the subject of a when expression in a variable
This section shows how to keep a when subject local to the expression and explains why a when used as an expression must cover every possible path.
- Local when subject variable: Explain why a when expression can capture its subject in a variable and where that variable can be used.
Why it matters: You can use the subject in the branches without leaving an unnecessary variable in the surrounding code. - Exhaustive when expressions: Explain what the compiler requires when a when construct is used as an expression, and how enum cases or else can meet that requirement.
Why it matters: If your code uses a when result, no possible path can be left without a value.
Key terms: subject, when expression, scope, exhaustive, else
2.3.4 Using the when expression with arbitrary objects
This section uses sets in a when expression to match color pairs regardless of their order.
- Order Independent Color Pairs: Explain why comparing sets lets the mix function recognize the same two colors in either order.
Why it matters: Set comparison avoids writing a separate branch for each ordering of a color pair. - Object Matching And Default Branch: Describe how when matches the color set against its branches and why the mix function needs an else branch.
Why it matters: This explains both how the set-based branches are selected and why the expression needs a fallback result.
Key terms: setOf, Set, set comparison, when expression, branch condition, else branch, exhaustive
2.3.5 Using the when expression without an argument
This section shows how an argumentless when expression can check Boolean conditions while avoiding temporary Set objects at a cost to readability.
- Argumentless when branch conditions: Explain that when a when expression has no argument, each branch condition can be any Boolean expression.
Why it matters: This lets you recognize what the branches of an argumentless when are testing. - Allocation and readability tradeoff: Justify replacing Set-based color matching with an argumentless when in the example: it avoids creating short-lived Set instances on every call, but makes the code harder to read.
Why it matters: The example shows why a less readable form may be worthwhile in frequently called code.
Key terms: when expression, branch condition, Boolean expression, Set instances, mixOptimized, short-lived objects, garbage collector
2.3.6 Smart casts: Combining type checks and casts
This section uses a simple arithmetic-expression tree to show how Kotlin’s `is` checks enable smart casts when evaluating different object types.
- Arithmetic expression tree: Describe how `Expr`, `Num`, and `Sum` represent an expression such as `(1 + 2) + 4`.
Why it matters: The tree explains why evaluating one expression may require evaluating smaller expressions inside it. - Recursive expression evaluation: Explain how evaluation handles each of the two expression types.
Why it matters: This is the behavior the section’s `eval` function must implement for nested expressions. - Type checks and smart casts: Explain how an `is` check lets Kotlin access subtype-specific properties without an explicit cast, and when that smart cast is valid.
Why it matters: Smart casts make the subtype checks in `eval` usable without repetitive explicit casts.
Key terms: Expr, marker interface, Num, Sum, eval, recursively, is, smart cast, val, custom accessor
2.3.7 Refactoring: Replacing an if with a when expression
Shows how to make an `eval` function more concise by using `if` as a value-producing expression, then replacing an `if` cascade with a type-checking `when`.
- Value-Producing If Expressions: Explain why an `if` expression can serve as an expression-bodied function’s body, and how its branches produce values.
Why it matters: It explains how the first refactoring keeps `eval`’s result while removing syntax. - Type-Checking When Branches: Describe how a `when` expression can replace a cascade of `if` expressions in `eval` by checking argument types and using smart casts.
Why it matters: It lets you recognize when one `when` expression can express an `if` cascade more clearly.
Key terms: if expression, expression-body syntax, if branch, when expression, when branches, type check, smart cast, Num, Sum
2.3.8 Blocks as branches of if and when
Explains how block branches in if and when produce results, including when they contain logging statements.
- Results of block branches: Explain how an if or when branch can perform multiple actions in a block while producing a result, and distinguish this rule from returns in a regular function with a block body.
Why it matters: This lets you add actions such as logging to a branch without changing the value it produces.
Key terms: if, when, block, last expression, expression body, block body
2.4 Iterating over things: while and for loops
Introduces Kotlin’s familiar while loop and the basic syntax of its for loop.
- Basic Kotlin loop forms: Describe the two loop forms introduced here: while uses a traditional form familiar from other languages, and for uses `for (<item> in <elements>)`, resembling Java’s for-each loop.
Why it matters: These familiar forms give you a starting point for recognizing loops in Kotlin code.
Key terms: while loop, for loop, in
2.4.1 Repeating code while a condition is true: The while loop
The section introduces Kotlin’s while and do-while loops and explains how labels can direct break and continue in nested loops.
- Labels in nested loops: Explain how to declare a label for a nested loop and how break or continue can refer to it.
Why it matters: Labels let you specify which loop a break or continue refers to when loops are nested. - Kotlin while loop forms: State which two while-loop forms Kotlin provides.
Why it matters: These are the two while-loop forms the section introduces.
Key terms: label, break, continue, while, do-while
2.4.2 Iterating over numbers: Ranges and progressions
This section shows how Kotlin uses ranges and progressions to iterate over numbers, including backward and stepped iteration.
- Range boundaries and iteration: Explain how a Kotlin for loop iterates over an integer range, and distinguish the inclusive `..` range from the half-open `..<` range.
Why it matters: Choosing the right range boundary determines whether the loop visits its end value. - Progression direction and step: Describe how a progression visits values and how `downTo` and `step` change a numeric loop.
Why it matters: Progressions let you express backward counting and skipped values directly in a loop.
Key terms: range, closed, inclusive, half-closed range, .., ..<, progression, downTo, step
2.4.3 Iterating over maps
This section shows how to iterate over maps, use bracket syntax for map entries, and obtain indices while iterating over a collection.
- Map entry unpacking: Explain how a for loop can unpack each map entry into a key and a value. Describe how the example uses a character range from A through F to fill the map.
Why it matters: Unpacking lets you use a map’s keys and values directly inside a loop. - Map bracket access: Distinguish reading a map value with map[key] from setting one with map[key] = value, as illustrated by binaryReps[char] = binary.
Why it matters: Bracket syntax makes map lookups and updates easier to read. - Indexed collection iteration: Describe how withIndex lets a loop unpack both an element and its index without manually maintaining an index variable.
Why it matters: withIndex avoids a separate index variable that you would have to increment yourself.
Key terms: for loop, map, key-value pairs, destructuring syntax, range, map[key], map[key] = value, get, put, withIndex
2.4.4 Using in to check collection and range membership
This section explains how `in` and `!in` check membership in ranges and collections, including within `when` expressions.
- Range membership checks: Explain how `in` checks whether a value belongs to a range and `!in` checks whether it does not, using character validation as an example.
Why it matters: You can express boundary checks clearly without writing the comparisons yourself. - Membership checks in when: Describe how `in` and `!in` can be used in `when` expressions to check different ranges, and state that `in` also works with collections.
Why it matters: The same membership notation applies when selecting among ranges or checking a collection. - Comparable object ranges: Explain why a range of comparable objects can support an `in` check even when its members cannot be enumerated, using the section’s string example.
Why it matters: A range can express ordered membership without being a sequence you can list or iterate through.
Key terms: in, !in, range, when expressions, collections, kotlin.Comparable, String
2.5 Throwing and catching exceptions in Kotlin
Introduces how Kotlin exceptions are thrown and propagated, and shows that throw can be used within an expression.
- Exception handling and propagation: Explain that a Kotlin function can finish normally or throw an exception when an error occurs, and that its caller can catch and process the exception or let it propagate up the stack.
Why it matters: This is the basic flow behind catching errors in Kotlin. - Throw as an expression: Describe how Kotlin uses the throw keyword to raise an exception and allows throw within another expression. Explain that, in the percentage example, a valid condition initializes percentage with number, while the other path throws and leaves it uninitialized.
Why it matters: It explains why a value-producing expression can include an error path.
Key terms: exception, catch, stack, throw, expression
2.5.1 Handling exceptions and recovering from errors: try, catch, and finally
This section explains how Kotlin handles exceptions with try, catch, and finally, and why it does not enforce Java-style checked exceptions.
- Exception recovery with try: Describe how try with catch and finally is used to handle exceptions, including the example that returns a parsed number or null when a line is not a valid number.
Why it matters: It gives you a way to describe recovery from bad input rather than only throwing an error. - Kotlin exception handling choice: Distinguish Kotlin’s exception rules from Java’s checked-exception rules and explain why Kotlin leaves handling decisions to the programmer.
Why it matters: It explains why Kotlin lets you choose which failures warrant recovery code. - Try-with-resources library alternative: State how Kotlin provides the functionality associated with Java’s try-with-resources, without describing its implementation.
Why it matters: It prevents you from looking for a Kotlin language construct identical to Java’s try-with-resources.
Key terms: try, catch, finally, BufferedReader, throws clause, checked exceptions, unchecked exceptions, NumberFormatException, IOException, try-with-resources
2.5.2 Using try as an expression
This section shows how Kotlin’s try expression produces a value from either a successful try block or a catch block.
- Try expression result: Explain how a try expression can be assigned to a variable and how its result is chosen when the try block succeeds or an exception is caught.
Why it matters: This lets you use exception handling directly where your code needs a value. - Catch fallback or return: Distinguish a catch block that returns from the enclosing function from one that supplies a fallback value so execution can continue.
Why it matters: You can choose whether an error ends the function or provides a value for the following code.
Key terms: try expression, catch block, last expression, catch clause, return statement, fallback values, NumberFormatException
2.6 Summary
Where this is used later
- Getting rid of static utility classes: Top-level functions and properties (chapter 3) · Develops the idea of top-level declarations further.
- Named arguments (chapter 3) · Functions have named parameters that receive argument values.
- Default parameter values (chapter 3) · Declaring functions with parameters.
- Visibility modifiers: Public by default (chapter 4) · The section points ahead to tooling that checks explicit return types in public APIs.
- Syntax for lambda expressions (chapter 5) · Local-variable type inference provides a comparison for omitting explicit types.
- Data classes: Autogenerated implementations of universal methods (chapter 4) · The distinction between read-only val and reassignable var declarations.
- Accessing variables in scope (chapter 5) · The distinction between read-only val and reassignable var.
- Basic syntax and inner workings of delegated properties (chapter 9) · The distinction between read-only and reassignable properties.
Concepts explained in this chapter
- when expressionA when expression is Kotlin's conditional expression that selects a branch based on matching conditions, including Boolean conditions when no subject argument is supplied.
- loopA loop is a control structure that repeatedly executes a block of code according to a condition or over a sequence of values.
- expression bodyAn expression body is a Kotlin function body consisting of a single expression written after an equals sign instead of a block and explicit return statements.
- intervalAn interval is a connected set or span of values between specified lower and upper endpoints, with endpoint inclusion determined by its definition.
- valA read-only variable is a variable whose binding cannot be reassigned after initialization.
- attributeAn annotation is a declaration-associated metadata construct whose availability and retention can be configured for source processing, compiled class files, or runtime access.
- accessor methodA property accessor is a getter or setter that defines how a Kotlin property value is read or changed.
- conditional logicA Boolean expression is an expression whose evaluation produces a Boolean value.
- KotlinKotlin is a statically typed programming language designed to interoperate with Java and run across multiple execution environments.
- smart castA smart cast is Kotlin's compiler-supported automatic treatment of a value as a checked subtype within a valid control-flow branch.
- membership operatorThe `in` operator tests whether a value belongs to a collection, range, or other container by invoking its containment operation.
- return typeA return type is the statically determined type of the value returned by a function.
- enumAn enum is a Kotlin type whose instances are restricted to a fixed set of named constants.
- classA class is a Kotlin declaration that defines the structure and behavior of objects through members such as properties, functions, and constructors.
- exceptionException is the Java base class for conditions that a program may catch and handle, excluding serious errors represented by Error.
- type checkingA type check is a Kotlin operation that tests whether a value has a specified runtime type.
- try-catch statementA try-catch is a Kotlin exception-handling construct that executes a protected block and handles matching exceptions in catch clauses.
- mutable propertyA mutable property is a Kotlin property whose value can be changed after initialization.
- read-only propertyA read-only property is a Kotlin property that can be accessed but not reassigned through its public declaration.
- MapHashMap is a hash-table-based Java map implementation that stores key-value associations and uses key hash codes for lookup.
- finallyA finally block is an exception-handling block that executes after a protected block regardless of whether an exception was thrown.
- atomic typeA type is a classification that specifies the values an expression or variable can represent and the operations allowed on them.
- type inferenceType inference is the compiler's ability to determine expression types without requiring explicit type annotations everywhere.
- captured variableA captured variable is a variable that stores the subject of a Kotlin when expression and is accessible within that expression's branches.
- data conversionData conversion is the transformation of a value or data from one type, format, or representation to another, explicitly or implicitly.
- backing fieldA backing field is the compiler-managed field that stores a Kotlin property's value when storage is required.
- collectionA collection is a container or aggregate that holds multiple elements and supports operations such as membership testing.
- public visibilityVisibility is the access-control property that determines which code can refer to a declaration.
- initializerA constructor is a Kotlin class member that initializes a new instance and receives constructor arguments.
These guides are generated from the text of Manning books by Manning's knowledge graph and link to the sections they draw on. The full books are available on liveBook and at manning.com.
