32,36 €
Delve into the world of Kotlin and learn to build powerful Android and web applications
Key Features
Book Description
Kotlin is a general-purpose programming language used for developing cross-platform applications. Complete with a comprehensive introduction and projects covering the full set of Kotlin programming features, this book will take you through the fundamentals of Kotlin and get you up to speed in no time.
Learn Kotlin Programming covers the installation, tools, and how to write basic programs in Kotlin. You'll learn how to implement object-oriented programming in Kotlin and easily reuse your program or parts of it. The book explains DSL construction, serialization, null safety aspects, and type parameterization to help you build robust apps. You'll learn how to destructure expressions and write your own. You'll then get to grips with building scalable apps by exploring advanced topics such as testing, concurrency, microservices, coroutines, and Kotlin DSL builders. Furthermore, you'll be introduced to the kotlinx.serialization framework, which is used to persist objects in JSON, Protobuf, and other formats.
By the end of this book, you'll be well versed with all the new features in Kotlin and will be able to build robust applications skillfully.
What you will learn
Who this book is for
If you're a beginner or intermediate programmer who wants to learn Kotlin to build applications, this book is for you. You'll also find this book useful if you're a Java developer interested in switching to Kotlin.
Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:
Seitenzahl: 633
Veröffentlichungsjahr: 2019
Copyright © 2019 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the authors, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
Commissioning Editor: Richa TripathiAcquisition Editor: Denim PintoContent Development Editor: Manjusha MantriTechnical Editor:Mayank DubeyCopy Editor: Safis EditingProject Coordinator:Prajakta NaikProofreader: Safis EditingIndexer: Tejal Daruwale SoniGraphics:Jisha ChirayilProduction Coordinator: Nilesh Mohite
First published: Feb 2017Second edition: May 2019
Production reference: 1270519
Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.
ISBN 978-1-78980-235-1
www.packtpub.com
Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.
Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals
Improve your learning with Skill Plans built especially for you
Get a free eBook or video every month
Mapt is fully searchable
Copy and paste, print, and bookmark content
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.packt.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.
At www.packt.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.
Stephen Samuel is an accomplished developer with over 17 years of experience. He has worked with Java throughout his career, and in the past five years has focused on Scala. He has a passion for concurrency and big data technologies. Having spent the last few years in investment banking, he is currently working with Kotlin on a major big data investment project. Stephen is also active in the open source community, being the author of several high-profile Scala and Kotlin libraries
Stefan Bocutiu is a big data consultant with over 13 years of experience in software development. He enjoys coding in Scala and C#, and has a passion for stream processing technologies. With the team at DataMountaineer, he focuses on providing scalable, unified, real-time data pipelines to allow reactive decision making, analytics, and Hadoop integration.
Stefan is passionate about motorsports, and while his racing skills are not good enough to allow him to compete, he tries to attend as many MotoGP races as possible. When he is not coding, he can be found at the climbing wall or at the gym. Occasionally, hiking and scrambling trips are on his calendar, and during the winter season, skiing trips are a must for him.
Ehsun Behravesh is a senior software engineer employed by Atlassian. He fell in love with computer programming when he was 15. Ehsun is holding a master's degree in computer science, and he has worked as a software engineer in five countries.
Rivu Chakraborty is a speaker, author, community contributor, Google-certified Android developer, and Caster.io instructor. He has over seven years of professional experience, and is currently working as a senior software engineer (Android) at BYJU'S The Learning App. Rivu considers himself a Kotlin and Android enthusiast-cum-evangelist. He has been using Kotlin since December 2015. Rivu created the Kotlin Kolkata User Group, and before moving out to Bangalore, he had been the lead organizer for both the Kotlin Kolkata User Group and GDG Kolkata. Along with organizing events, he also speaks at local events and conferences all over India, including DroidJam India and DevFests. Rivu has authored multiple books on Kotlin and Android development.
If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.
Title Page
Copyright and Credits
Learn Kotlin Programming Second Edition
About Packt
Why subscribe?
Packt.com
Contributors
About the authors
About the reviewers
Packt is searching for authors like you
Preface
Who this book is for
What this book covers
To get the most out of this book
Download the example code files
Download the color images
Conventions used
Get in touch
Reviews
Section 1: Fundamental Concepts in Kotlin
Getting Started with Kotlin
Technical requirements
Using the command line to compile and run Kotlin code
Kotlin runtime
The REPL
Kotlin for scripting
Kotlin with Gradle
Kotlin with Maven
IntelliJ and Kotlin
Eclipse and Kotlin
Mixing Kotlin and Java in a project
Summary
Kotlin Basics
val and var
Type inference
Basic types in Kotlin
Numbers
Unsigned integers
Booleans
Chars
Strings
Arrays
Comments
Packages
Imports
Wildcard imports
Import renaming
String templates
Ranges
Loops
Exception handling
Instantiating classes
Referential equality and structural equality
This expression
Scope
Visibility modifiers
Private
Protected
Internal
Control flow as expressions
The null syntax
Smart casts
Explicit casting
The when expression
When (value)
The when without argument
Function return
Type hierarchy
Code contracts
Contracts API
Contracts on a function return value
Contracts on method invocation
Limitations
Summary
Object-Oriented Programming in Kotlin
Classes
Access levels
Nested classes
Data classes
Inline classes
Enum classes
Static methods and companion objects
Interfaces
Inheritance
Visibility modifiers
Abstract classes
Interface or abstract classes
Polymorphism
Overriding rules
Inheritance versus composition
Class delegation
Sealed classes
Summary
Section 2: Practical Concepts in Kotlin
Functions in Kotlin
Defining functions
Single expression functions
Member functions
Local functions
Top-level functions
Named parameters
Default parameters
Extension functions
Extension function precedence
Extension functions on null values
Member extension functions
Overriding member extension functions
Companion object extensions
Multiple return values
Infix functions
Operators
Operator overloading
Basic operators
in/contains
Get/set
Invoke
Comparison
Assignment
Java interop
Function literals
Tail recursive functions
Varargs
Spread operator
Standard library functions
Apply
Let
With
Run
Lazy
Use
Repeat
Require/assert/check
Generic functions
Pure functions
Java from Kotlin
Getters and setters
Single abstract methods
Escaping Kotlin identifiers
Java void methods
Kotlin from Java
Top-level functions
Default parameters
Object and static methods
Erasure naming
Checked exceptions
Summary
Higher-Order Functions and Functional Programming
Higher-order functions
Returning a function
Assigning a function 
Closures
Anonymous functions
Function references
Top-level function references
Member and extension function references
Bound references
Function-literal receivers
Functions in the JVM
Bytecode
Function composition
Inline functions
Noinline
Currying and partial application
Currying in action
Adding currying support
Memoization
Implementing memoization
Type alias
Either
Fold
Projection
Further projection functions
Custom DSLs
Infix functions as keywords
Using function receivers in a DSL
Validation and error accumulation
Summary
Properties
Why use properties?
Overriding getters and setters
Visibility
Late initialization
Delegated properties
Lazy initializations
Lateinit versus lazy
Observables
A non-null property delegate
Properties or methods?
Summary
Null Safety, Reflection, and Annotations
Nullable types
Smart cast
Safe null access
Force operator
Elvis operator
Safe casting
Optional
Creating and returning an Optional
Using an Optional
Reflection
KClass
Instantiation using reflection
Constructors
Instantiation with callBy
Objects and companions
Useful KClass properties
Reflective functions and properties
Invoking a function reflectively
Declared and undeclared
Annotations
Annotation parameters
Standard annotations
@JvmName
@JvmStatic
@Throws
@JvmOverloads
Runtime annotation discovery
Summary
Generics
Parameterized functions
Parameterized types
Bounded polymorphism
Upper bounds
Multiple bounds
Type variance
Invariance
Covariance
Covariant return
Contravariance
Variance overview
Nothing type
Type projection
Type erasure
Type reification
Recursive type bounds
Algebraic data types
Summary
Data Classes
Introduction to data classes
Automatic creation of getters and setters
The copy method
toString out of the box
The hashCode and equals methods generated for you
Destructed declarations
Destructing types
Data class definition rules
Limitations
Summary
Collections
Class hierarchy
Arrays
Lists
Maps
Sets
Read-only views
Indexed access
Sequences
Summary
Testing in Kotlin
Getting started
Choosing a spec
Matchers
String matchers
Collection matchers
Floating point matchers
Expecting exceptions
Combining matchers
Custom matchers
Inspectors
Interceptors
The test case interceptor
The spec interceptor
Project config
Property testing
Specifying a generator
A custom generator
Table-driven testing
Testing non-deterministic code
Tags, conditions, and config
Config
Conditions
Tags
One instance
Resources
Summary
Microservices with Kotlin
Definition
Drawbacks
Why microservices?
Lagom
Defining services
Implementing a Lagom service
Summary
Section 3: Advanced Concepts in Kotlin
Concurrency
Threads
Blocking
Creating a thread
Stopping a thread
Thread interrupts
CPU-bound versus I/O-bound
Deadlocks and livelocks
The Dining Philosophers Problem
Executors
Race conditions
Monitors
Locks
Read-write locks
Semaphores
he bounded buffer problem
Concurrent collections
ConcurrentHashMap
A blocking queue
Atomic variables
CountDownLatch
CyclicBarrier
Non-blocking I/O and asynchronous programming
Futures
Summary
Coroutines
Suspending functions
Coroutine builders
Launch builder
runBlocking Builder
Structured concurrency
Nested coroutines
Parent-child relationship
Jobs
Cancellation
Join
Job state
Context and scope
Global scope
Cancellation and failure
Cancellation or failure in a parent
Failure in a child coroutine
Supervisor scope
Async
Coroutine dispatchers
Dispatcher inheritance
Wrapping Java executors
With context
Error handling
Summary 
Application of Coroutines
Channels
Rendezvous channels
Closing a channel
Producers
Conflated channels
 Ticker channels
select expression
Using select for channels
Using select for deferred
Debugging coroutines
Coroutines in action
 Concurrent HTTP requests
Blocking IO with coroutines
Using callbacks with coroutines
Summary
Kotlin Serialization
Setup 
Json serialization and deserialization
How it works
Protobuf serialization and deserialization
Annotations
Rules
Summary
Other Books You May Enjoy
Leave a review - let other readers know what you think
Kotlin is typically associated with Android development, and most discussions surrounding it gravitate around this. However, the language has much more to offer and is ideal for modern server-side developers. While any Android developer will find useful snippets in this book, it is primarily aimed at Java and Scala developers. The book starts with an introduction to Kotlin and explains how you set up your environment before moving on to the basic concepts. Once the basics are out of the way, the focus shifts toward more advanced concepts, and don't be surprised if you see a few bytecode listings. Once you have completed the book, you should have all the knowledge required to start using Kotlin for your next project.
This book is aimed at those who have little or no Kotlin experience and who wish to learn the language quickly. The focus of the book is on server-side development in Kotlin, and would be best suited to a developer who is currently a server-side developer, or who wishes to learn. No prior knowledge of functional or object-orientated programming is required, but knowledge of another programming language is recommended.
Some chapters contain brief sections comparing Java implementations to their Kotlin cousins, but these pages can be skipped by those who have no prior Java knowledge.
Chapter 1, Getting Started with Kotlin, covers how to install Kotlin, the Jetbrains Intellij IDEA, and the Gradle build system. Once the setup of the tool chain is complete, the chapter shows how to write your first Kotlin program.
Chapter 2, Kotlin Basics, dives head first into the basics of Kotlin, including the basic types, basic syntax, and program control flow structures, such as if statements, for loops, and while loops. The chapter concludes with Kotlin-specific additions, such as when expressions and type inference.
Chapter 3, Object-Oriented Code in Kotlin, focuses on the object-oriented aspects of the language. It introduces classes, interfaces, objects and the relationship between them, as well as subtypes and polymorphism.
Chapter 4, Functions in Kotlin, shows that functions, also known as procedures or methods, are the basic building blocks of any language. This chapter covers the syntax for functions, including Kotlin enhancements such as named parameters, default parameters, and function literals.
Chapter 5, Higher-Order Functions and Functional Programming, focuses on the functional programming side of Kotlin, including closures, also known as lambdas, and function references. It also covers functional programming techniques, such as partial application, function composition, and error accumulation.
Chapter 6, Properties, explains that properties work hand in hand with object-orientated programming to expose values on a class or object. This chapter covers how properties work, how the user can best make use of them, and also how they are represented in the bytecode.
Chapter 7, Null Safety, Reflection, and Annotations, explains that null safety is one of the main features that Kotlin provides, and the first part of this chapter covers in depth the whys and how's of null safety in Kotlin. The second part of the chapter introduces reflection—runtime introspection of code—and how it can be used for meta programming with annotations.
Chapter 8, Generics, explains that generics, or parameterized types, are a key component of any advanced type system, and the type system in Kotlin is substantially more advanced than that available in Java. This chapter covers variance, the type system, including the nothing type, and algebraic data types.
Chapter 9, Data Classes, shows that immutability and boilerplate-free domain classes are a current hot topic, due to the way they facilitate more robust code and simplify concurrent programming. Kotlin has many features focused on this area, which it calls data classes.
Chapter 10, Collections, explains that collections are one of the most commonly used aspects of any standard library, and Java collections are no different. This chapter describes the enhancements that Kotlin has made to the JDK collections, including functional operations such as map, fold, and filter.
Chapter 11, Testing in Kotlin, explains that one of the gateways into any new language is using it as a language for writing test code. This chapter shows how the exciting test framework, KotlinTest, can be used to write expressive, human-readable tests, with much more power than the standard JUnit tests allow.
Chapter 12, Microservices in Kotlin, shows that microservices have come to dominate server-side architecture in recent years, and Kotlin is an excellent choice for writing such services. This chapter introduces the Lagom microservice framework and shows how it can be used to great effect with Kotlin.
Chapter 13, Concurrency, explains that, as multicore-aware programs are becoming more and more important in server-side platforms, this chapter is focused on a solid introduction to concurrent programming techniques that are vital in modern development, including threads, concurrency primitives, and futures.
Chapter 14, Coroutines, covers the powerful Kotlin concurrency library known as coroutines that enable thread-safe code to be written in a simple, imperative way. This chapter focuses on introducing the core constructs of coroutines, how they work, and perhaps, most importantly, why they are useful.
Chapter 15, Application of Coroutines, focuses on real-world scenarios and use cases of coroutines. This chapter expands on the previous chapter, covering use cases such as producers and consumers, channels, debugging in a multithreaded context, and how to bridge normal threaded code with the coroutine world.
Chapter 16, Kotlin Serialization, introduces a compiler plugin, written by Jetbrains, that generates serialization and deserialization functions for Kotlin classes that do not use runtime reflection for introspection. This results in more performant code. This chapter also includes information on several different serialization formats available for this library.
This book requires a computer running macOS, Linux, or Windows, and that is capable of running the latest versions of Java. It is recommended that the machine has sufficient memory to run a recent version of Jetbrains' Intellij IDEA.
You can download the example code files for this book from your account at www.packt.com. If you purchased this book elsewhere, you can visit www.packt.com/support and register to have the files emailed directly to you.
You can download the code files by following these steps:
Log in or register at
www.packt.com
.
Select the
SUPPORT
tab.
Click on
Code Downloads & Errata
.
Enter the name of the book in the
Search
box and follow the onscreen instructions.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
WinRAR/7-Zip for Windows
Zipeg/iZip/UnRarX for Mac
7-Zip/PeaZip for Linux
The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Learn-Kotlin-Programming. In case there's an update to the code, it will be updated on the existing GitHub repository.
We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: http://www.packtpub.com/sites/default/files/downloads/9781789802351_ColorImages.pdf.
Feedback from our readers is always welcome.
General feedback: If you have questions about any aspect of this book, mention the book title in the subject of your message and email us at [email protected].
Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packt.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.
Piracy: If you come across any illegal copies of our works in any form on the internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise in, and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.
Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!
For more information about Packt, please visit packt.com.
In the first section of the book, you will be introduced to Kotlin. You will learn how to set up your system to write your first Kotlin program and run it. This will include configuring a build system, such as Gradle or Maven, to handle dependencies used by your programs. Then, the core concepts of Kotlin, such as basic syntax for variables and values, expressions, and loops, will be explained, giving you the basic building blocks required to write a non-trivial program. In addition, the types available in Kotlin, and how nulls interact with them, will also be covered. Finally, you will see how the basic constructs of Kotlin can be combined to form objects, and how these objects can interact in what is known as object-oriented programming.
The following chapters will be covered in this section:
Chapter 1
,
Getting Started with Kotlin
Chapter 2
,
Kotlin Basics
Chapter 3
,
Object-Oriented Programming in Kotlin
It is time to write code. In this chapter, we will go over and write the typical entry code example for every language—the famous Hello World!. In order to do this, we will need to set up the initial environment required to develop software with Kotlin. We will provide a few examples using the compiler from the command line, and then we will look at the typical way of programming using the integrated development environments (IDEs) and build tools available.
Kotlin is a Java virtual machine (JVM) language, and so the compiler will emit Java bytecode. Because of this, naturally, Kotlin code can call Java code, and vice versa! Therefore, you need to have the Java Development Kit (JDK) installed on your machine. To be able to write code for Android, where the most recent supported Java version is 6, the compiler needs to translate your code to bytecode that is at least compatible with Java 6.
In this chapter, you will learn how to do the following:
Use the command line to compile and execute code written in Kotlin
Use the REPL and write Kotlin scripts
Create a Gradle project with Kotlin enabled
Create a Maven project with Kotlin enabled
Use IntelliJ to create a Kotlin project
Use Eclipse IDE to create a Kotlin project
Mix Kotlin and Java code in the same project
Throughout this book, all the code examples will run with JDK 8. If you are new to the JVM world, you can get the latest version from http://www.oracle.com/technetwork/java/javase/downloads/index.html.
In Chapter 7, Null Safety, Reflection, and Annotations, the examples will draw heavily on classes provided by the reflection API. This API is available through the kotlin-reflect.jar located on maven central at https://search.maven.org/search?q=a:kotlin-reflect.
Additionally, the code snippets used in this book can be found on GitHub at the following repository https://github.com/PacktPublishing/Programming-Kotlin.
To write and execute code written in Kotlin, you will need its runtime and the compiler. At the time of writing, the stable release of Kotlin is 1.3.31. Every runtime release comes with its own compiler version. To get your hands on it, navigate to https://github.com/JetBrains/kotlin/releases/tag/v1.3.31, scroll to the bottom of the page, and download and unpack the ZIP archive, kotlin-compiler-1.3-31.zip, to a known location on your machine. The output folder will contain a directory called binwith all the scripts required to compile and run Kotlin on Windows, Linux, or macOS. You need to make sure thebinfolder location is part of your system path in order to callkotlincwithout having to specify the full path.
If your machine runs Linux or macOS, there is an even easier way to install the compiler by using sdkman. All you need to do is execute the following commands in a Terminal:
$ curl -s https://get.sdkman.io | bash $ bash $ sdk install kotlin 1.3.31
Alternatively, if you are using macOS and you have homebrew installed, you could run the following commands to achieve the same thing:
$ brew update
$ brew install [email protected]
Now that all of this is done, we can finally write our first Kotlin code. The application we will be writing does nothing other than display the text Hello World! on the console. Start by creating a new file named HelloWorld.kt and type the following:
fun main(args: Array<String>) { println("Hello, World!") }
From the command line, invoke the compiler to produce the JAR assembly, as follows (include-runtime is a flag for the compiler to produce a self-contained and runnable JAR by including the Kotlin runtime in the resulting assembly):
kotlinc HelloWorld.kt -include-runtime -d HelloWorld.jar
Now you are ready to run your program by typing the following on your command line. Make sure that your JAVA_HOME variable is set and added to the system path:
$ java -jar HelloWorld.jar
The code is pretty straightforward. It defines the entry point function for your program, and, in the first and only line of code, it prints the text to the console.
If you have been working with the Java or Scala languages, you might raise an eyebrow because you noticed the lack of the typical class that would normally define the standard static main program entry point. How does it work then? Let's have a look at what actually happens. First, let's just compile the preceding code by running the following command. This will create a HelloWorld.class in the same folder:
$ kotlinc HelloWorld.kt
Now that we have the bytecode generated, let's look at it by using the javap tool available with the JDK, as follows (please note that the file name contains a suffix, Kt):
$ javap -c HelloWorldKt.class
Once the execution completes, you should see the following printed on your Terminal:
Compiled from "HelloWorld.kt" public final class HelloWorldKt { public static final void main(java.lang.String[]); Code: 0: aload_0 1: ldc #9 // String args 3: invokestatic #15 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Ob ject;Ljava/lang/String;)V 6: ldc #17 // String Hello, World! 8: astore_1 9: nop 10: getstatic #23 // Field java/lang/System.out:Ljava/io/PrintStream; 13: aload_1 14: invokevirtual #29 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V 17: return }
You don't have to be an expert in bytecode to understand what the compiler has actually done for us. As you can see in the snippet, a class has been generated for us, and it contains the program entry point with the instructions to print Hello World! to the console.
I would not expect you to work with the command-line compiler on a daily basis; rather, you should use the tools at hand to delegate this, as we will see shortly.
When we compiled Hello World! and produced the JAR, we instructed the compiler to bundle in the Kotlin runtime. Why is the runtime needed? Take a closer look at the following bytecode that was generated, if you haven't already done so. To be more specific, look at line 3. It invokes a method to validate the fact that the args variable is not null; therefore, if you compile the code without asking for the runtime to be bundled in, and then try to run it, you will get an exception:
$ kotlinc HelloWorld.kt -d HelloWorld.jar
$ java -jar HelloWorld.jar
Exception in thread "main" java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
at HelloWorldKt.main(HelloWorld.kt)
Caused by: java.lang.ClassNotFoundException: kotlin.jvm.internal.Intrinsics
The runtime footprint is very small; at approximately 800 K, you can't argue otherwise. Kotlin comes with its own standard class library (Kotlin runtime), which is different from the Java library. As a result, you need to merge it into the resulting JAR, or provide it in the classpath, as follows:
$ java -cp $KOTLIN_HOME/lib/kotlin-runtime.jar:HelloWorld.jar HelloWorldKt
If you develop a library for the exclusive use of other Kotlin libraries or applications, then you don't have to include the runtime. Alternatively, there is a shorter path that involves passing a flag to the Kotlin compiler, as follows:
$ kotlinc -include-runtime HelloWorld.kt -d HelloWorld
The preceding code will include the runtime when assembling the final JAR file.
These days, most languages provide an interactive shell, and Kotlin is no exception. If you want to quickly write some code that you won't use again, then the REPL is a good tool to have. Some people prefer to test their methods quickly, but you should always write unit tests rather than using the REPL to validate that the output is correct.
You can start the REPL by adding dependencies to the classpath in order to make them available within the instance. To look at an example, we will use the Joda library to deal with the date and time. First, we need to download the JAR. In a Terminal window, use the following commands:
$ wget https://github.com/JodaOrg/joda-time/releases/download/v2.9.4/joda-time-2.9.4-dist.tar.gz
$ tar xvf joda-time-2.9.4-dist.tar.gz
Now, you are ready to start the REPL. Attach the Joda library to its running instance, and import and use the classes it provides, as follows:
$ kotlinc-jvm -cp joda-time-2.9.4/joda-time-2.9.4.jar
Welcome to Kotlin version 1.1-M04 (JRE 1.8.0_66-internal-b17)
Type :help for help, :quit for quit
>>> import org.joda.time.DateTime
>>> DateTime.now()
2016-08-25T22:53:41.017+01:00
Running the preceding code will execute the now function of the DateTime class provided by the Joda library. The output is simply the current date and time.
If you still prefer to stick with good old Maven, there is no problem. There is a plugin for it to support Kotlin as well. If you don't have Maven on your machine, you can follow the instructions at https://maven.apache.org/install.html to get it installed on your local machine.
Just as we did with Gradle, let's use the built-in templates to generate the project folder and file structure. From the Terminal, run the following command in an empty directory:
$ mvn archetype:generate -DgroupId=com.programming.kotlin
-DartifactId=chapter01 -DarchetypeArtifactId=maven-archetype-quickstart
-DinteractiveMode=false
maven-archetype- quickstart => maven-archetype-quickstart
This will generate the pom.xml file and the src folder for Maven. But before we add the file containing the kotlin code, we need to enable the plugin. Just as before, start by deleting App.java and AppTest.java from src/main/java/com/programming/kotlin and src/test/java/com/programming/kotlin, and create the src/main/kotlin directory (the subdirectory structure matches the namespace name), as shown in the following code:
$ mkdir -p src/main/kotlin/com/programming/kotlin/chapter01
$ mkdir -p src/test/kotlin/com/programming/kotlin/chapter01
In an editor of your choice, open up the generated pom.xml file and add the following:
<properties> <kotlin.version>1.3.31</kotlin.version> <kotlin.test.version>3.3.2</kotlin.test.version> </properties> <build> <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory> <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory> <plugins> <plugin> <artifactId>kotlin-maven-plugin</artifactId> <groupId>org.jetbrains.kotlin</groupId> <version>${kotlin.version}</version> <executions> <execution> <id>compile</id> <phase>process-sources</phase> <goals> <goal>compile</goal> </goals> </execution> <execution> <id>test-compile</id> <phase>process-test-sources</phase> <goals> <goal>test-compile</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
All we have done so far is enable the Kotlin plugin and make it run in the process-stages phase to allow the mixing of Java code as well. There are cases where you might have part of the source code written in good old Java. I am sure you also noticed the addition of source directory tags, allowing for the kotlin files to be included in the build.
The only thing left to do now is to add the library dependencies for the Kotlin runtime, as well as the unit tests. We are not going to touch upon the testing framework until later in the book. Replace the entire dependencies section with the following:
<dependencies> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib</artifactId> <version>${kotlin.version}</version> </dependency> <dependency> <groupId>io.kotlintest</groupId> <artifactId>kotlintest-runner-junit5</artifactId> <version>${kotlin.test.version}</version> <scope>test</scope> </dependency> </dependencies>
It is now time to add theHello World!code; this step is similar to the one we took earlier when we discussed Gradle, as you can see from the following code:
$ echo "" >> src/main/kotlin/com/programming/kotlin/chapter01/Program.kt $cat <<EOF >> src/main/kotlin/com/programming/kotlin/chapter01/Program.kt package com.programming.kotlin.chapter01 fun main(args: Array<String>) { println("Hello World!") }
We are now in a position to compile and build the JAR file for the sample program using the following code:
$ mvn package
$ mvn exec:java - Dexec.mainClass="com.programming.kotlin.chapter01.ProgramKt"
The last instruction should end up printing the Hello World! text to the console. Of course, we can run the program outside Maven by going back to executing Java, but we need to add the Kotlin runtime to the classpath, as follows:
$java -cp $KOTLIN_HOME/lib/kotlin-runtime.jar:target/chapter01-1.0- SNAPSHOT.jar "com.programming.kotlin.chapter01.ProgramKt"
If you want to avoid the classpath dependency setup when you run the application, there is an option to bundle all the dependencies in the result JAR and produce what is called a fat jar. For that, however, another plugin needs to be added, as shown in the following code:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.4.3</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestRe sourceTransformer"> <mainClass>com.programming.kotlin.chapter01.ProgramKt</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
We can execute the command to run our JAR without having to worry about setting the classpath since this has been taken care of by the plugin, as follows:
$ java -jar target/chapter01-1.0-SNAPSHOT.jar
The result of executing this command is to launch the JAR and execute the program.
Coding using Vim/nano is not everyone's first choice. Working without the help of an IDE with its code completion, IntelliSense, shortcuts for adding files, or refactoring code can prove challenging depending on how complex the project is.
For a while now, in the JVM world, people's first choice when it comes to their integrated development environment has been IntelliJ. The tool is made by the same company that created Kotlin—JetBrains. Given the integration between the two of them, it would be my first choice of IDE to use, but, as we will see in the next section, it is not the only option.
IntelliJ comes in two versions—Ultimate and Community (free). For the code we will be using over the course of this book, the free version is sufficient. If you don't already have it installed, you can download it from https://www.jetbrains.com/idea/download.
From version 15.0 onward, IntelliJ comes bundled with Kotlin, but if you have an older version, you can still get support for the language by installing the plugin. Just go to Settings | Plugins | Install IntelliJ plugins, and type Kotlin in the search box.
We are going to use the IDE to create a Gradle project with Kotlin enabled, just as we did in the previous section. Once you have started IntelliJ, click Create new project. You will then see a dialog window from which you should select Gradle from the left-hand side section;. Then, check the Kotlin(Java) option from the right-hand side, as shown in the following screenshot:
You should already have the system variable JAVA_HOME set up for the tool to pick it up automatically (see the Project SDK at the top of the screenshot). If this isn't the case, click the New button and navigate to where your JDK is. Once you have selected it, you are ready to go to the next step by clicking on the Next button available on the bottom right-hand side of the screen.
The next window presented to you asks you to provide the Group Id and Artifact Id. Let's go with com.programming.kotlin and chapter01, respectively. Once you have entered these fields, you can move to the next step of the process where you tick the Use auto-import flag and Create directories for empty directory roots automatically options. Carry on to the next step, where you will be asked where you wish to store the project on your machine. Set the project location, expand More Settings, type chapter01 for the Module name, and hit the Finish button.
IntelliJ will go on and create the project, and you should see the outcome shown in the following screenshot:
With the kotlin folder selected, right-click, select the New | Package option, and type com.programming.kotlin.chapter01, as shown in the following screenshot:
You should see a new folder appear below the kotlin folder, matching what was typed earlier. Right-click on that, chooseNew|Kotlin File/Class, and typeProgram.kt, as shown in the following screenshot:
We are now ready to start typing our Hello World! string. Use the same code we created earlier in the chapter. You should notice the Kotlin brand icon on the left-hand side of the file editor. If you click on it, you will get the option to run the code, and if you look at the bottom of your IntelliJ window, you should see the text Hello World!, printed out, as shown in the following screenshot:
Well done! You have written your first Kotlin program. It was easy and quick to set up the project and code, and then to run the program. If you prefer, you can have a Maven rather than a Gradle project. When you choose New | Project, you have to select Maven from the left-hand side and check Create from archetype while selecting org.jetbrains.kotlin:kotlin-archetype-jvm from the list presented, as shown in the following screenshot:
As the screenshot shows, the Maven option should be selected from the various archetypes.
There might be some of you who still prefer Eclipse IDE to IntelliJ; don't worry, you can still develop Kotlin code without having to move away from it. At this point, I assume you already have the tool installed. From the menu, navigate to Help | Eclipse Marketplace, look for the Kotlin plugin, and install it (I am working with the latest distribution—Eclipse Neon).
Once you have installed the plugin and restarted the IDE, you are ready to create your first Kotlin project. From the menu, select File | New | Project, and you should see the following dialog:
Click the Next button to move to the next step, and once you have chosen the source code location, click the Finish button. This is not a Gradle or Maven project! You can choose one of the two, but then you will have to manually modify the build.gradle or pom.xml file, as we did in the Kotlin with Gradle and Kotlin with Maven sections of this chapter. As you did with the IntelliJ project, click on the src folder, select New package, and name it com.programming.kotlin.chapter01. To add our Program.kt file, you will need to right-click on the newly created package, select New | Other, and then select Kotlin | Kotlin File from the list. Once the file has been created, type the simple lines of code to print out the text to the console. You should have the following result in your Eclipse IDE:
Now, you are ready to run the code. From the menu, select Run | Run. You should be able to trigger the execution. If it is successful, you should see the Hello World! text printed out in theConsoletab at the bottom of your IDE.
This chapter described how you can set up your development environment with Gradle, Maven, IntelliJ, or Eclipse. Now, you are able to run and execute the examples given in the rest of the book, as well as experiment with your own Kotlin code.
In Chapter 2, Kotlin Basics, we will delve into the basic constructs you will use on a daily basis when coding in Kotlin.
It's time to discover the fundamental building blocks in Kotlin. For those coming from a Java background, this chapter will highlight some of the key similarities and differences between Kotlin and Java, and how Kotlin's language features compare to those in Java and on the Java virtual machine (JVM). For those who are not Java programmers, these differences can be safely skipped.
In this chapter, we will cover the following topics:
Variables and values
Control flow and expressions
Type inference
Smart casting
Basic types and the Kotlin type hierarchy
Code contracts
One of the big changes in Kotlin from Java is that, in Kotlin, everything is an object. If you come from a Java background, then you will already be aware that in Java there are special primitive types that are treated differently from objects. They cannot be used as generic types, do not support method/function calls, and cannot be assigned null. An example is the boolean primitive type.
Java introduced wrapper objects to offer a workaround in which primitive types are wrapped in objects, so that java.lang.Boolean wraps a boolean primitive type in order to smooth over the distinctions. Kotlin removes this necessity entirely from the language by promoting the primitives to full objects.
Whenever possible, the Kotlin compiler will map basic types back to JVM primitives for performance reasons. However, sometimes the values must be boxed, such as when the type is nullable, or when it is used in generics. Boxing is the conversion from a primitive type to a wrapper type, which takes place whenever an object is required but a primitive is presented.
The built-in number types are as follows:
Type
Width
Long
64
Int
32
Short
16
Byte
8
Double
64
Float
32
To create a number literal, use one of the following forms:
