1. Kotlin Programming Flashcards
What is Kotlin?
Kotlin is not just a better language to write code to run on the Java Virtual Machine. It is a multiplatform language that aims to be general purpose: Kotlin can be used to write native macOS and Windows applications, JavaScript applications, and, of course, Android applications. Platform independence means that Kotlin has a wide variety of uses.
How IntelliJ compiles the Kotlin code?
IntelliJ compiles the Kotlin code using the kotlinc-jvm compiler. This means IntelliJ translates the Kotlin code you wrote into bytecode, the language the JVM “speaks.”
What is a REPL?
REPL is short for “read, evaluate, print, loop.”
What does mean targeting JVM?
The JVM is a piece of software that knows how to execute a set of instructions, called bytecode. “Targeting the JVM” means compiling, or translating, your Kotlin source code into Java bytecode, with the intention of running that bytecode on the JVM
Each platform, such as Windows or macOS, has its own instruction set. The JVM acts as a bridge between the bytecode and the different hardware and software environments the JVM runs on, reading a piece of bytecode and calling the corresponding platform-specific instruction(s) that map to that bytecode. Therefore, there are different versions of the JVM for different platforms. This is what allows Kotlin developers to write platform-independent code that can be written one time and then compiled into bytecode and executed on different devices regardless of their operating systems.
Since Kotlin can be converted to bytecode that the JVM can execute, it is considered a JVM language. Java is perhaps the most well-known JVM language, because it was the first. However, other JVM languages, such as Scala and Kotlin, have emerged to address some shortcomings of Java from the developer perspective.
Is Kotlin limited to JVM?
Kotlin is not limited to the JVM, however. At the time of this writing, Kotlin can also be compiled into JavaScript or even into native binaries that run directly on a given platform – such as Windows, Linux, and macOS – negating the need for a virtual machine layer.
Why we specify data types and what that does tell to compiler?
Variables and constants have a data type that you specify. The type describes the data that is held by a variable or constant and tells the compiler how type checking will be handled, a feature in Kotlin that prevents the assignment of the wrong kind of data to a variable or constant.
What is static type system and static type checking?
Kotlin uses a static type system – meaning the compiler labels the source code you define with types so that it can ensure the code you wrote is valid. IntelliJ also checks code as you type it and notices when an instance of a particular type is incorrectly assigned to a variable of a different type. This feature is called static type checking, and it tells you about programming mistakes before you even compile the program.
Commonly used built-in types in Kotlin?
String - Textual data, Char - Single character, Boolean - True/false value, Int - Whole numbers, Double - Decimal numbers, List - Collection of elements, Set - Collection of unique elements, Map - Collection of key-value pairs
What is a Type Inference?
Kotlin includes a feature called type inference that allows you to omit the type definition for variables that are assigned a value when they are declared.
Type inference helps keep code clean, concise, and easier to modify as your program changes.
If you ever have a question about the type of a variable, click on its name and press Control-Shift-P. IntelliJ will display its type
What is compile time constants?
A compile-time constant must be defined outside of any function, including main, because its value must be assigned at compile time (that is, when the program compiles) – hence the name. main and your other functions are called during runtime (when the program is executed), and the variables within them are assigned their values then.
Compile-time constants also must be of one of the following basic types: String, Int, Double, Float, Long, Short, Byte, Char, Boolean.
Prepending a val with the const modifier tells the compiler that it can be sure that this val will never change.
This gives the compiler the flexibility to perform optimization behind the scenes.
How you can inspect Kotlin Bytecode?
press the Shift key twice to open the Search Everywhere dialog. Begin entering “show kotlin bytecode” in the search box, and select Show Kotlin Bytecode from the list of available actions when it appears.
You can also open tool window with Tools -> Kotlin -> Show Kotlin Bytecode.
You can translate the bytecode back to Java to see it represented in terms you may be more familiar with. In the bytecode tool window, click the Decompile button at the top left.
Java Primitive Types in Kotlin?
In Java, there are two kinds of types: reference types and primitive types. Reference types are defined in source code: A matching source code definition corresponds to the type. Java also offers primitive types (often called just “primitives”), which have no source file definition and are represented by special keywords instead.
A reference type in Java always begins with a capital letter, indicating that it is backed by a source definition for its type.
A Java primitive type starts with a lowercase letter.
All primitives in Java have a corresponding reference type. (But not all reference types have a corresponding primitive type.)
One reason for choosing a reference type is that there are certain features of the Java language that are only available when using reference types. Generics, for example, do not work with primitives. Reference types can also work with the object-oriented features of Java more readily than Java primitives.
On the other hand, primitives offer better performance and some other perks.
Unlike Java, Kotlin provides only one kind of type: reference types.
Kotlin made this design decision for several reasons. First, if there is no choice between kinds of types, you cannot code yourself into a corner as easily as you can with multiple kinds to choose from. For example, what if you define an instance of a primitive type, then realize later that you need to use the generic feature, which requires a reference type? Having only reference types in Kotlin means that you will never encounter this problem.
If you are familiar with Java, you may be thinking, “But primitives offer better performance than reference types!” This is true.
The Kotlin compiler will, where possible, use primitives in the Java bytecode, because they do indeed offer better performance.
Kotlin gives you the ease of reference types with the performance of primitives under the hood. In Kotlin you will find a corresponding reference type for the eight primitive types you may be familiar with in Java.
What is structural equality operator?
You express this with the ==.
What is called string concatenation?
Using the addition operator (+) to append a value to a string is called string concatenation.
How to evaluates whether the two instances point to the same reference?
You express this with the ===.
What is if else statement?
if (condition) { // expression } else { // expression }
Kotlin logical operator?
Logical operators allow you to combine comparison operators into a larger statement.
&& - Logical ‘and’: true if and only if both are true (false otherwise).
|| - Logical ‘or’: true if either is true (false only if both are false).
! - Logical ‘not’: true becomes false, false becomes true.
One note: When operators are combined, there is an order of precedence that determines what order they are evaluated in. Operators with the same precedence are applied from left to right. You can also group operations by surrounding the operators that should be evaluated as a group in parentheses.
Here is the order of operator precedence, from highest to lowest:
! (logical ‘not’)
< (less than), <= (less than or equal to), > (greater than), >= (greater than or equal to) == (structural equality), != (non-equality)
&& (logical ‘and’)
|| (logical ‘or’)
Logical operators are not only for conditionals. They can be used in many expressions, including in the declaration of a variable.
What is conditional expressions?
A conditional expression is like a conditional statement, except that you assign the if/else to a value that you can use later.
When is acceptable to removing braces from if/else expressions?
In cases where you have a single response for the matching condition, it is valid (at least, syntactically – more on that shortly) to omit the curly braces wrapping the expression. You can only omit the {}s when a branch contains only one expression – omitting them from a branch with more than one expression will affect how the code is evaluated.
We recommend that you do not omit braces for conditional statements or expressions that span more than one line.
Often, for one-line expressions, removing the curly braces is more readable.
Kotlin Ranges?
The .. operator, as in in 1..5, signals a range. A range includes all values from the value on the left of the .. operator to the value on the right, so 1..5 includes 1, 2, 3, 4, and 5. Ranges can also be a sequence of characters.
You use the in keyword to check whether a value is within a range. Refactor your healthStatus conditional expression to use ranges rather than comparison operators.
In addition to the .. operator, several functions exist for creating ranges. The downTo function creates a range that descends rather than ascends, for example. And the until function creates a range that excludes the upper bound of the range specified.
When expression?
The when expression is another control flow mechanism available in Kotlin. Like if/else, the when expression allows you to write conditions to check for and will execute corresponding code when the condition evaluates as true. when provides a more concise syntax and is an especially good fit for conditionals with three or more branches.
By default, a when expression behaves as though there were a == equality operator between the argument you provide in parentheses and the conditions you specify in the curly braces.
A when expression works similarly to an if/else expression in that you define conditions and branches that are executed if a condition is true. when is different in that it scopes the lefthand side of the condition automatically to whatever you provide as an argument to when.
when expressions also support greater flexibility than if/else statements in how they match branches against the conditions you define.
val healthStatus = when (healthPoints) { 100 -> "excellent" in 90..99 -> "has a few scratches" else -> "bla bla" }
String templates?
Kotlin features string templates to aid in this common need and, again, make your code more readable. Templates allow you to include the value of a variable inside a string’s quotation marks.
You added the values of variable display string by prefixing each with $. This special symbol indicates to Kotlin that you would like to template a val or var within a string you define, and it is provided as a convenience. Note that these templated values appear inside the quotation marks that define the string.
val name = “Pera”
println(“Name is $name”)
Kotlin also allows you to evaluate an expression within a string and interpolate the result – that is, to insert the result into the string. Any expression that you add within the curly braces after a dollar-sign character (${}) will be evaluated as a part of the string.
val numberOne = 1
val numberTwo = 2
println(“Sum is${numberOne + numberTwo}”)
What is a function?
A function is a reusable portion of code that accomplishes a specific task. Functions are a very important part of programming. In fact, programs are fundamentally a series of functions combined to accomplish more complex tasks.
How to extract code to function?
There is two (three) options:
- Right click on the code you selected and choose Refactor -> Extract -> Function …
- Use shortcut: Control + Command + M