Lexical Structure and Style
|
This section documents Kotlin 2.4.x on the JVM, as published at kotlinlang.org, which is the reference these pages are written and verified against. This content was generated with the assistance of AI and should be verified against kotlinlang.org before being relied on in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
Kotlin’s surface syntax will feel familiar coming from Java, with a handful of deliberate simplifications: optional semicolons, a package declaration that need not match the directory layout, and a documentation-comment format (KDoc) built for its own tooling.
File and Package Structure
A .kt file may declare any number of top-level classes, functions, and properties, and its package
declaration — unlike Java’s — does not need to match the containing directory, though following the
convention keeps a project navigable and is what every real project does:
package com.example.billing
import kotlin.math.max
const val MAX_RETRIES = 3 // top-level property, no enclosing class needed
fun retryDelay(attempt: Int): Int = // top-level function, no enclosing class needed
max(attempt * 100, 1000)
class InvoiceService // an ordinary top-level class
A file with no package declaration belongs to the default package. import works as in Java, plus two
Kotlin-specific forms: importing a top-level function directly, and aliasing on import to resolve a name clash — import kotlin.math.PI as MathPi.
Identifiers
Identifiers follow the usual rules (start with a letter or underscore, then letters/digits/underscores) with one notable Kotlin addition: backtick-escaped identifiers allow any Unicode text, including spaces and reserved words, most commonly used for descriptive test-method names:
class `given an empty cart` {
@org.junit.jupiter.api.Test
fun `checkout should fail with an empty-cart error`() {
// ...
}
}
This is why a JUnit report for Kotlin test code so often reads like a full sentence — the backtick-quoted method
name is the display name, no @DisplayName annotation needed.
Comments
Kotlin has the same three C-style comment forms as Java, plus KDoc for API documentation:
// a single-line comment
/* a
multi-line comment (can nest, unlike Java's) */
/**
* KDoc: Kotlin's documentation-comment format.
*
* @param name the customer's display name
* @return a greeting string
*/
fun greet(name: String): String = "Hello, $name!"
KDoc is processed by Dokka (Kotlin’s Javadoc equivalent); its tag set is a superset of Javadoc’s, with Markdown allowed in the description body.
Optional Semicolons
A statement terminator is inferred at the end of a line wherever the parser can tell the statement is complete, so semicolons are almost always omitted in idiomatic Kotlin:
val a = 1
val b = 2
println(a + b) // no semicolons needed
val c = 1; val d = 2 // still legal on one line, just uncommon
The inference has a well-known gotcha: a line that could plausibly continue (ending in an operator, or the line
below starting with ., (, or [) is treated as continuing, which occasionally produces surprises with a
value expression placed right before a lambda — covered concretely in
Functions and
Lambdas and Higher-Order Functions.
Literals
| Kind | Examples |
|---|---|
Integer |
|
Floating-point |
|
Unsigned |
|
Boolean |
|
Character |
|
String |
|
|
the sole value of every nullable type — see Null Safety |
Official Coding Conventions
JetBrains publishes an official
Kotlin coding conventions document (4-space indentation, no
tabs, 120-character soft line limit, UpperCamelCase for types, lowerCamelCase for functions/properties,
UPPER_SNAKE_CASE for const val top-level/companion constants). ktlint enforces
this convention automatically and is the de facto formatter/linter for most Kotlin projects (see
Build and Tooling for wiring it into a build).
See Also
-
Basic Types and Variables —
val/varand type inference. -
Build and Tooling —
ktlint/detektstatic analysis.