Panduan gaya Kotlin

Dokumen ini berfungsi sebagai definisi lengkap standar coding Android Google untuk kode sumber dalam Bahasa Pemrograman Kotlin. File sumber Kotlin digambarkan seperti dalam Gaya Google Android jika dan hanya jika mematuhi aturan di sini.

Seperti panduan gaya pemrograman lainnya, masalah yang dibahas tidak hanya mencakup permasalahan estetika pemformatan, tetapi juga jenis konvensi atau standar coding lainnya. Akan tetapi, dokumen ini berfokus terutama pada aturan keras dan cepat yang kami ikuti secara universal, dan menghindari pemberian saran yang tidak dapat diberlakukan secara jelas (baik oleh manusia maupun alat).

Terakhir diperbarui: 06-09-2023

File sumber

Semua file sumber harus dienkode sebagai UTF-8.

Penamaan

Jika file sumber hanya berisi satu class level atas, nama file harus merefleksikan nama yang peka huruf besar/kecil dan ekstensi .kt. Atau, jika file sumber berisi beberapa deklarasi level atas, pilih nama yang menjelaskan isi file, terapkan PascalCase (camelCase dapat diterima jika nama filenya jamak), dan tambahkan ekstensi .kt.

// MyClass.kt
class MyClass { }
// Bar.kt
class Bar { }
fun Runnable.toBar(): Bar = // …
// Map.kt
fun <T, O> Set<T>.map(func: (T) -> O): List<O> = // …
fun <T, O> List<T>.map(func: (T) -> O): List<O> = // …
// extensions.kt
fun MyClass.process() = // …
fun MyResult.print() = // …

Karakter Khusus

Karakter spasi kosong

Selain dari urutan terminator baris, karakter spasi ASCII horizontal (0x20) adalah satu-satunya karakter spasi kosong yang muncul di mana saja dalam file sumber. Ini berarti bahwa:

  • Semua karakter spasi putih lainnya dalam string dan literal karakter akan di-escape.
  • Karakter tab tidak digunakan untuk indentasi.

Urutan escape khusus

Untuk setiap karakter yang memiliki urutan escape khusus (\b, \n, \r, \t, \', \", \\, dan \$), urutan tersebut yang digunakan, bukan escape Unicode yang sesuai (misalnya, \u000a).

Karakter non-ASCII

Untuk karakter non-ASCII yang tersisa, karakter Unicode aktual (misalnya, ) atau escape Unicode yang setara (misalnya, \u221e) akan digunakan. Pilihannya hanya bergantung pada yang membuat kode lebih mudah dibaca dan dipahami. Escape Unicode tidak disarankan untuk karakter yang dapat dicetak di lokasi mana pun dan sangat tidak disarankan di luar literal string dan komentar.

Contoh Diskusi
val unitAbbrev = "μs" Terbaik: sangat jelas meskipun tanpa komentar.
val unitAbbrev = "\u03bcs" // μs Buruk: tidak ada alasan untuk menggunakan escape dengan karakter yang dapat dicetak.
val unitAbbrev = "\u03bcs" Buruk: pembaca tidak tahu apa ini.
return "\ufeff" + content Baik: gunakan escape untuk karakter yang tidak dapat dicetak, dan beri komentar jika perlu.

Struktur

File .kt terdiri dari hal-hal berikut, secara urut:

  • Header hak cipta dan/atau lisensi (opsional)
  • Anotasi level file
  • Pernyataan paket
  • Pernyataan impor
  • Deklarasi level atas

Tepat satu baris kosong yang memisahkan setiap bagian ini.

Jika ada judul hak cipta atau lisensi dalam file, maka harus ditempatkan di bagian atas dalam komentar multi-baris.

/*
 * Copyright 2017 Google, Inc.
 *
 * ...
 */
 

Jangan gunakan komentar KDoc-style atau single-line-style.

/**
 * Copyright 2017 Google, Inc.
 *
 * ...
 */
// Copyright 2017 Google, Inc.
//
// ...

Anotasi level file

Anotasi dengan target penggunaan situs "file" ditempatkan di antara komentar judul dan deklarasi paket.

Pernyataan paket

Pernyataan paket tidak tunduk pada batas kolom dan tidak pernah digabungkan dalam baris.

Pernyataan impor

Pernyataan impor untuk class, fungsi, dan properti dikelompokkan menjadi satu dalam daftar tunggal dan diurutkan berdasarkan ASCII.

Impor karakter pengganti (jenis apa pun) tidak diizinkan.

Serupa dengan pernyataan paket, pernyataan impor tidak tunduk pada batas kolom dan tidak pernah digabungkan.

Deklarasi level atas

File .kt dapat mendeklarasikan satu atau beberapa jenis, fungsi, properti, atau alias jenis di level atas.

Konten file harus berfokus pada satu tema. Contohnya adalah satu jenis publik atau serangkaian fungsi ekstensi yang melakukan operasi yang sama di beberapa jenis penerima. Deklarasi yang tidak terkait harus dipisahkan ke file dan deklarasi publiknya sendiri dalam satu file harus diminimalkan.

Tidak ada batasan eksplisit yang ditempatkan pada nomor atau urutan konten file.

File sumber biasanya dibaca dari atas ke bawah yang berarti bahwa urutannya, secara umum, harus merefleksikan bahwa deklarasi yang lebih tinggi akan menginformasikan pemahaman tentang yang lebih jauh ke bawah. File lain dapat memilih untuk mengurutkan kontennya secara berbeda. Demikian pula, satu file dapat berisi 100 properti, 10 fungsi lain, dan class tunggal lain.

Yang penting adalah setiap file menggunakan beberapa urutan logis, yang dapat dijelaskan oleh pengelola jika diminta. Misalnya, fungsi baru tidak hanya ditambahkan secara rutin ke akhir file, karena akan menghasilkan pengurutan “kronologis menurut tanggal penambahan”, yang bukan merupakan pengurutan logis.

Pengurutan anggota class

Urutan anggota dalam class mengikuti aturan yang sama seperti deklarasi level atas.

Pemformatan

Kurung kurawal

Kurung kurawal tidak diperlukan untuk cabang when dan ekspresi if yang tidak memiliki lebih dari satu cabang else dan yang sesuai dalam satu baris.

if (string.isEmpty()) return

val result =
    if (string.isEmpty()) DEFAULT_VALUE else string

when (value) {
    0 -> return
    // …
}

Kurung kurawal biasanya diperlukan untuk pernyataan dan ekspresi if, for, cabang when, do, dan while apa pun, meskipun isinya kosong atau hanya memiliki satu pernyataan.

if (string.isEmpty())
    return  // WRONG!

if (string.isEmpty()) {
    return  // Okay
}

if (string.isEmpty()) return  // WRONG
else doLotsOfProcessingOn(string, otherParametersHere)

if (string.isEmpty()) {
    return  // Okay
} else {
    doLotsOfProcessingOn(string, otherParametersHere)
}

Blok yang tidak kosong

Kurung kurawal mengikuti gaya Kernighan dan Ritchie ("Kurung kurawal Mesir") untuk blok yang tidak kosong dan konstruksi seperti blok:

  • Tidak ada baris baru sebelum kurung kurawal buka.
  • Jeda baris setelah kurung kurawal buka.
  • Jeda baris sebelum kurung kurawal tutup.
  • Jeda baris setelah kurung kurawal tutup, hanya jika kurung kurawal tersebut mengakhiri pernyataan atau mengakhiri isi class yang diberi nama, fungsi, atau konstruktor. Misalnya, tidak ada jeda baris setelah kurung kurawal jika diikuti oleh else atau koma.
return Runnable {
    while (condition()) {
        foo()
    }
}

return object : MyClass() {
    override fun foo() {
        if (condition()) {
            try {
                something()
            } catch (e: ProblemException) {
                recover()
            }
        } else if (otherCondition()) {
            somethingElse()
        } else {
            lastThing()
        }
    }
}

Beberapa pengecualian untuk class enum ditampilkan di bawah ini.

Blok kosong

Blok kosong atau konstruksi seperti blok harus dalam gaya K&R.

try {
    doSomething()
} catch (e: Exception) {} // WRONG!
try {
    doSomething()
} catch (e: Exception) {
} // Okay

Ekspresi

Suatu if/else bersyarat yang digunakan sebagai ekspresi dapat menghilangkan tanda kurung kurawal hanya jika seluruh ekspresi sesuai dalam satu baris.

val value = if (string.isEmpty()) 0 else 1  // Okay
val value = if (string.isEmpty())  // WRONG!
    0
else
    1
val value = if (string.isEmpty()) { // Okay
    0
} else {
    1
}

Indentasi

Setiap kali blok baru atau konstruksi seperti blok terbuka, indentasi akan meningkat sebesar empat spasi. Saat blok berakhir, indentasi akan kembali ke level indentasi sebelumnya. Level indentasi berlaku untuk kode dan komentar di seluruh blok.

Satu pernyataan per baris

Setiap pernyataan diikuti dengan baris baru. Titik koma tidak digunakan.

Penggabungan baris

Kode memiliki batas kolom sebanyak 100 karakter. Kecuali sebagaimana disebutkan di bawah, setiap baris yang melebihi batas ini harus digabungkan dalam baris, seperti yang dijelaskan di bawah.

Pengecualian:

  • Baris yang tidak mematuhi batas kolom tidak dimungkinkan (misalnya, URL panjang di KDoc)
  • Pernyataan package dan import
  • Command line dalam komentar yang mungkin dipotong dan ditempel ke suatu shell

Tempat penjedaan baru

Petunjuk utama penggabungan baris adalah: lebih baik melakukan penjedaan baru pada level sintaksis yang lebih tinggi. Selain itu:

  • Jika baris dijeda pada operator atau nama fungsi infix, jeda akan muncul setelah operator atau nama fungsi infix.
  • Jika baris dijeda pada simbol "seperti operator" berikut, jeda akan muncul sebelum simbol:
    • Pemisah titik (., ?.).
    • Dua tanda titik dua dari referensi anggota (::).
  • Metode atau nama konstruktor tetap disertakan pada tanda kurung buka (() yang mengikutinya.
  • Tanda koma (,) tetap disertakan pada token yang mendahuluinya.
  • Panah lambda (->) tetap disertakan pada daftar argumen yang mendahuluinya.

Fungsi

Jika tanda tangan fungsi tidak sesuai di satu baris, pisahkan setiap deklarasi parameter ke barisnya masing-masing. Parameter yang ditentukan dalam format ini harus menggunakan indentasi tunggal (+4). Kurung tutup ()) dan jenis nilai ditempatkan pada barisnya sendiri tanpa indentasi tambahan.

fun <T> Iterable<T>.joinToString(
    separator: CharSequence = ", ",
    prefix: CharSequence = "",
    postfix: CharSequence = ""
): String {
    // …
}
Fungsi ekspresi

Jika hanya berisi satu ekspresi, fungsi dapat direpresentasikan sebagai fungsi ekspresi.

override fun toString(): String {
    return "Hey"
}
override fun toString(): String = "Hey"

Properti

Jika penginisialisasi properti tidak sesuai dalam satu baris, pisahkan setelah tanda sama dengan (=) dan gunakan indentasi.

private val defaultCharset: Charset? =
    EncodingRegistry.getInstance().getDefaultCharsetForPropertiesFiles(file)

Properti yang mendeklarasikan fungsi get dan/atau set harus menempatkan di setiap barisnya sendiri dengan indentasi normal (+4). Format menggunakan aturan yang sama dengan fungsi.

var directory: File? = null
    set(value) {
        // …
    }
Properti hanya baca dapat menggunakan sintaksis yang lebih pendek yang sesuai di satu baris.
val defaultExtension: String get() = "kt"

Spasi kosong

Vertikal

Satu baris kosong akan muncul:

  • Antara anggota class yang berurutan: properti, konstruktor, fungsi, class bertingkat, dsb.
    • Pengecualian: Baris kosong antara dua properti berturut-turut (tidak memiliki kode lain di antara keduanya) bersifat opsional. Baris kosong tersebut digunakan seperlunya untuk membuat pengelompokan properti yang logis dan properti atribusi dengan properti cadangannya, jika ada.
    • Pengecualian: Baris kosong antara konstanta enum dibahas di bagian bawah.
  • Antara pernyataan, seperlunya untuk mengatur kode ke dalam sub-bagian logis.
  • Secara opsional sebelum pernyataan pertama dalam suatu fungsi, sebelum anggota pertama class, atau setelah anggota terakhir class (baik yang disarankan maupun yang tidak).
  • Sebagaimana yang diminta oleh bagian lain dokumen ini (seperti bagian Struktur).

Beberapa baris kosong berturut-turut diizinkan, tetapi tidak disarankan dan tidak pernah diwajibkan.

Horizontal

Di luar yang diwajibkan oleh bahasa atau aturan gaya lainnya, dan terlepas dari literal, komentar, dan KDoc, satu ruang ASCII juga hanya muncul di tempat-tempat berikut:

  • Memisahkan kata yang hanya boleh digunakan oleh sistem, seperti if, for, atau catch dari tanda kurung (() yang mengikutinya di baris tersebut.
    // WRONG!
    for(i in 0..1) {
    }
    
    // Okay
    for (i in 0..1) {
    }
    
  • Memisahkan kata yang hanya boleh digunakan oleh sistem, seperti else atau catch, dari tanda kurung kurawal tutup (}) yang mendahuluinya di baris tersebut.
    // WRONG!
    }else {
    }
    
    // Okay
    } else {
    }
    
  • Sebelum kurung kurawal buka apa pun ({).
    // WRONG!
    if (list.isEmpty()){
    }
    
    // Okay
    if (list.isEmpty()) {
    }
    
  • Di kedua sisi operator biner apa pun.
    // WRONG!
    val two = 1+1
    
    // Okay
    val two = 1 + 1
    
    Hal ini juga berlaku untuk simbol “seperti operator” berikut:
    • panah dalam ekspresi lambda (->).
      // WRONG!
      ints.map { value->value.toString() }
      
      // Okay
      ints.map { value -> value.toString() }
      
    Tetapi bukan:
    • dua tanda titik dua (::) dari referensi anggota.
      // WRONG!
      val toString = Any :: toString
      
      // Okay
      val toString = Any::toString
      
    • pemisah titik (.).
      // WRONG
      it . toString()
      
      // Okay
      it.toString()
      
    • operator rentang (..).
      // WRONG
      for (i in 1 .. 4) {
        print(i)
      }
      
      // Okay
      for (i in 1..4) {
        print(i)
      }
      
  • Sebelum titik dua (:) hanya jika digunakan dalam deklarasi class untuk menentukan antarmuka atau class dasar, atau jika digunakan dalam klausa where untuk batasan umum.
    // WRONG!
    class Foo: Runnable
    
    // Okay
    class Foo : Runnable
    
    // WRONG
    fun <T: Comparable> max(a: T, b: T)
    
    // Okay
    fun <T : Comparable> max(a: T, b: T)
    
    // WRONG
    fun <T> max(a: T, b: T) where T: Comparable<T>
    
    // Okay
    fun <T> max(a: T, b: T) where T : Comparable<T>
    
  • Setelah tanda koma (,) atau titik dua (:).
    // WRONG!
    val oneAndTwo = listOf(1,2)
    
    // Okay
    val oneAndTwo = listOf(1, 2)
    
    // WRONG!
    class Foo :Runnable
    
    // Okay
    class Foo : Runnable
    
  • Di kedua sisi garis miring ganda (//) yang memulai komentar akhir baris. Di sini, beberapa spasi diperbolehkan, tetapi tidak wajib.
    // WRONG!
    var debugging = false//disabled by default
    
    // Okay
    var debugging = false // disabled by default
    

Aturan ini tidak pernah diartikan sebagai mewajibkan atau melarang spasi tambahan di awal atau akhir baris; hanya membahas ruang interior.

Konstruksi khusus

Class enum

Sebuah enum tanpa fungsi dan tanpa dokumentasi pada konstantanya dapat diformat sebagai satu baris.

enum class Answer { YES, NO, MAYBE }

Jika konstanta dalam enum ditempatkan di baris terpisah, baris kosong tidak diperlukan di antaranya kecuali dalam kasus di mana sebuah isi ditentukan.

enum class Answer {
    YES,
    NO,

    MAYBE {
        override fun toString() = """¯\_(ツ)_/¯"""
    }
}

Karena class enum adalah class, berlaku semua aturan lain untuk class pemformatan.

Anotasi

Anotasi anggota atau jenis ditempatkan pada baris terpisah tepat sebelum konstruksi beranotasi.

@Retention(SOURCE)
@Target(FUNCTION, PROPERTY_SETTER, FIELD)
annotation class Global

Anotasi tanpa argumen dapat ditempatkan pada satu baris.

@JvmField @Volatile
var disposable: Disposable? = null

Jika hanya ada satu anotasi tanpa argumen, anotasi tersebut dapat diletakkan pada baris yang sama dengan deklarasi.

@Volatile var disposable: Disposable? = null

@Test fun selectAll() {
    // …
}

Sintaksis @[...] hanya dapat digunakan dengan target situs penggunaan eksplisit, dan hanya untuk menggabungkan 2 atau lebih anotasi tanpa argumen pada satu baris.

@field:[JvmStatic Volatile]
var disposable: Disposable? = null

Jenis properti/nilai implisit

Jika isi fungsi ekspresi atau penginisialisasi properti berupa nilai skalar atau jenis nilai yang ditampilkan dapat dengan jelas disimpulkan dari isi tersebut, nilai tersebut dapat dihilangkan.

override fun toString(): String = "Hey"
// becomes
override fun toString() = "Hey"
private val ICON: Icon = IconLoader.getIcon("/icons/kotlin.png")
// becomes
private val ICON = IconLoader.getIcon("/icons/kotlin.png")

Saat menuliskan library, pertahankan deklarasi jenis eksplisit jika merupakan bagian dari API publik.

Penamaan

ID hanya menggunakan huruf dan angka ASCII, dan, dalam beberapa kasus yang disebutkan di bawah ini, menggunakan garis bawah. Jadi, setiap nama ID yang valid dicocokkan dengan ekspresi reguler \w+.

Awalan atau akhiran khusus, seperti yang ada dalam contoh name_, mName, s_name, dan kName, tidak digunakan kecuali dalam hal properti pendukung (lihat Properti pendukung).

Nama Paket

Nama paket semuanya huruf kecil, dengan kata berturut-turut yang digabung bersama-sama (tanpa garis bawah).

// Okay
package com.example.deepspace
// WRONG!
package com.example.deepSpace
// WRONG!
package com.example.deep_space

Nama jenis

Nama class ditulis dalam PascalCase dan biasanya berupa kata benda atau frasa nomina. Misalnya, Character atau ImmutableList. Nama antarmuka juga dapat berupa kata benda atau frasa nomina (misalnya, List), tetapi terkadang dapat berupa kata sifat atau frasa kata sifat (misalnya, Readable).

Class pengujian diberi nama dimulai dengan nama class yang diuji, dan diakhiri dengan Test. Misalnya, HashTest atau HashIntegrationTest.

Nama fungsi

Nama fungsi ditulis dalam camelCase dan biasanya berupa kata kerja atau frasa kata kerja. Misalnya, sendMessage atau stop.

Garis bawah diizinkan muncul dalam nama fungsi pengujian untuk memisahkan komponen logis nama tersebut.

@Test fun pop_emptyStack() {
    // …
}

Fungsi yang dianotasi dengan @Composable yang menampilkan Unit adalah PascalCased dan diberi nama dengan kata benda, seolah-olah kata tersebut adalah jenis.

@Composable
fun NameTag(name: String) {
    // …
}

Nama fungsi tidak boleh berisi spasi karena tidak didukung di setiap platform (terutama, ini tidak sepenuhnya didukung di Android).

// WRONG!
fun `test every possible case`() {}
// OK
fun testEveryPossibleCase() {}

Nama konstanta

Nama konstanta menggunakan UPPER_SNAKE_CASE: semua huruf besar, dengan kata-kata yang dipisahkan dengan garis bawah. Namun, sebenarnya apa yang dimaksud dengan konstanta?

Konstanta adalah properti val tanpa fungsi get kustom, yang kontennya tidak dapat diubah, dan yang fungsinya tidak memiliki efek samping yang dapat dideteksi. Yang termasuk konstanta adalah jenis immutable dan koleksi immutable dari jenis immutable serta skalar dan string jika ditandai sebagai const. Jika salah satu status observasi instance dapat berubah, itu bukan termasuk konstanta. Tindakan untuk tidak memutasikan objek belumlah cukup.

const val NUMBER = 5
val NAMES = listOf("Alice", "Bob")
val AGES = mapOf("Alice" to 35, "Bob" to 32)
val COMMA_JOINER = Joiner.on(',') // Joiner is immutable
val EMPTY_ARRAY = arrayOf()

Nama-nama tersebut biasanya berupa kata benda atau frasa nomina.

Nilai konstanta hanya dapat ditentukan dalam object atau sebagai deklarasi level atas. Nilai yang dinyatakan memenuhi persyaratan konstanta, tetapi didefinisikan di dalam class harus menggunakan nama non-konstanta.

Konstanta yang merupakan nilai skalar harus menggunakan pengubah const.

Nama non-konstanta

Nama non-konstanta ditulis dalam camelCase. Ini berlaku untuk properti instance, properti lokal, dan nama parameter.

val variable = "var"
val nonConstScalar = "non-const"
val mutableCollection: MutableSet = HashSet()
val mutableElements = listOf(mutableInstance)
val mutableValues = mapOf("Alice" to mutableInstance, "Bob" to mutableInstance2)
val logger = Logger.getLogger(MyClass::class.java.name)
val nonEmptyArray = arrayOf("these", "can", "change")

Nama-nama tersebut biasanya berupa kata benda atau frasa nomina.

Properti pendukung

Jika properti pendukung diperlukan, namanya harus sama persis dengan properti sebenarnya, tetapi diawali dengan garis bawah.

private var _table: Map? = null

val table: Map
    get() {
        if (_table == null) {
            _table = HashMap()
        }
        return _table ?: throw AssertionError()
    }

Nama variabel jenis

Setiap variabel jenis diberi nama dalam salah satu dari dua gaya:

  • Satu huruf kapital, dapat diikuti dengan satu angka (seperti E, T, X, T2)
  • Nama dalam bentuk yang digunakan untuk class, diikuti dengan huruf kapital T (seperti RequestT, FooBarT)

Camel case

Terkadang ada lebih dari satu cara yang wajar untuk mengonversi frasa bahasa Inggris ke dalam camel case, misalnya jika ada akronim atau konstruksi yang tidak biasa seperti “IPv6” atau “iOS”. Untuk meningkatkan prediktabilitas, gunakan skema berikut.

Dimulai dengan bentuk prosa nama:

  1. Konversi frasa tersebut menjadi ASCII biasa dan hapus apostrof. Misalnya, “Müllerl's algorithm” dapat menjadi “Muellers algorithm”.
  2. Pisahkan hasilnya ini menjadi kata-kata, yang terbagi dengan spasi dan tanda baca yang tersisa (biasanya tanda hubung). Rekomendasi: jika kata apa pun sudah muncul dengan camel-case konvensional dalam penggunaan umum, pisahkan ke dalam bagian-bagian penyusunnya (misalnya, “AdWords” menjadi “ad words”). Perhatikan bahwa kata seperti “iOS” tidak benar-benar dalam camel case; hal ini melanggar konvensi, sehingga rekomendasi ini tidak berlaku.
  3. Sekarang ubah menjadi huruf kecil semuanya (termasuk akronim), lalu lakukan salah satu langkah berikut:
    • Buat huruf besar pada karakter pertama di setiap kata untuk membuat pascal case.
    • Gunakan huruf besar untuk karakter pertama setiap kata kecuali yang pertama untuk menghasilkan camel case.
  4. Terakhir, gabungkan semua kata menjadi satu ID.

Perlu diperhatikan bahwa penggunaan huruf besar/kecil untuk kata-kata asli hampir sepenuhnya diabaikan.

Bentuk prosa Benar Salah
"Permintaan HTTP XML" XmlHttpRequest XMLHTTPRequest
"ID pelanggan baru" newCustomerId newCustomerID
"stopwatch internal" innerStopwatch innerStopWatch
"mendukung IPv6 di iOS" supportsIpv6OnIos supportsIPv6OnIOS
"pengimpor YouTube" YouTubeImporter YoutubeImporter*

(* Dapat diterima, tetapi tidak direkomendasikan.)

Dokumentasi

Pemformatan

Pemformatan dasar blok KDoc terlihat dalam contoh ini:

/**
 * Multiple lines of KDoc text are written here,
 * wrapped normally…
 */
fun method(arg: String) {
    // …
}

...atau dalam contoh satu baris ini:

/** An especially short bit of KDoc. */

Bentuk dasar selalu dapat diterima. Bentuk satu baris dapat digantikan jika keseluruhan blok KDoc (termasuk penanda komentar) dapat disesuaikan dalam satu baris. Perhatikan bahwa ini hanya berlaku jika tidak ada tag blok seperti @return.

Paragraf

Satu baris kosong, yaitu baris yang hanya berisi tanda bintang berurutan (*), muncul di antara paragraf dan sebelum grup tag blok, jika ada.

Tag blok

Setiap “tag blok” standar yang digunakan akan muncul dalam urutan @constructor, @receiver, @param, @property, @return, @throws, @see, dan tag ini tidak pernah muncul dengan deskripsi kosong. Jika tag blok tidak sesuai dalam satu baris, baris lanjutan diberi indentasi 4 spasi dari posisi @.

Fragmen ringkasan

Setiap blok KDoc dimulai dengan fragmen ringkasan singkat. Fragmen ini sangat penting: ini adalah satu-satunya bagian dari teks yang muncul dalam konteks tertentu seperti indeks class dan metode.

Ini adalah fragmen, yaitu frasa nomina atau frasa kata kerja, bukan kalimat lengkap. Fragmen ini tidak dimulai dengan "A `Foo` is a...", atau "This method returns...", juga tidak harus membentuk kalimat imperatif lengkap seperti "Save the record.". Namun, fragmen tersebut mengandung huruf kapital dan tanda baca seolah-olah merupakan kalimat lengkap.

Penggunaan

Setidaknya, KDoc ada untuk setiap jenis public, dan setiap anggota public atau protected dari jenis tersebut, dengan beberapa pengecualian yang tercantum di bawah.

Pengecualian: Fungsi yang dapat dipahami dengan jelas

KDoc bersifat opsional untuk fungsi “sederhana, jelas” seperti getFoo dan properti seperti foo, apabila satu-satunya yang paling dapat dikatakan adalah “Mengembalikan foo”.

Mengutip pengecualian ini demi membenarkan penghapusan informasi relevan yang mungkin perlu diketahui pembaca umum bukanlah tindakan yang tepat. Misalnya, untuk fungsi bernama getCanonicalName atau properti bernama canonicalName, jangan hapus dokumentasinya (dengan dasar pemikiran yang hanya akan menyebutkan /** Returns the canonical name. */) jika pembaca umum mungkin tidak memahami istilah "nama kanonis"!

Pengecualian: penggantian

KDoc tidak selalu ada pada metode yang menggantikan metode supertype.