Gaya kode di halaman ini adalah aturan ketat untuk mengkontribusikan kode Java ke Android Open Source Project (AOSP). Kontribusi ke platform Android yang tidak mematuhi aturan ini umumnya tidak akan diterima . Kami menyadari bahwa tidak semua kode yang ada mengikuti aturan ini, tetapi kami berharap semua kode baru mematuhinya. Lihat Pengkodean sehubungan dengan contoh terminologi untuk digunakan dan dihindari untuk ekosistem yang lebih inklusif.
Konsisten
Salah satu aturan paling sederhana adalah KONSISTEN. Jika Anda mengedit kode, luangkan beberapa menit untuk melihat kode di sekitarnya dan tentukan gayanya. Jika kode itu menggunakan spasi di sekitar klausa if
, Anda juga harus melakukannya. Jika komentar kode memiliki kotak kecil bintang di sekelilingnya, buat komentar Anda juga memiliki kotak kecil bintang di sekitarnya.
Inti dari memiliki pedoman gaya adalah untuk memiliki kosa kata pengkodean yang umum, sehingga pembaca dapat berkonsentrasi pada apa yang Anda katakan, bukan pada bagaimana Anda mengatakannya. Kami menyajikan aturan gaya global di sini agar Anda tahu kosakatanya, tetapi gaya lokal juga penting. Jika kode yang Anda tambahkan ke file terlihat sangat berbeda dari kode yang ada di sekitarnya, itu membuat pembaca keluar dari ritme saat mereka membacanya. Cobalah untuk menghindari ini.
kaidah bahasa jawa
Android mengikuti konvensi pengkodean Java standar dengan aturan tambahan yang dijelaskan di bawah.
Jangan abaikan pengecualian
Mungkin tergoda untuk menulis kode yang mengabaikan pengecualian, seperti:
void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { } }
Jangan lakukan ini. Meskipun Anda mungkin mengira kode Anda tidak akan pernah mengalami kondisi kesalahan ini atau tidak penting untuk menanganinya, mengabaikan jenis pengecualian ini akan membuat ranjau dalam kode Anda untuk dipicu oleh orang lain suatu hari nanti. Anda harus menangani setiap pengecualian dalam kode Anda dengan cara yang berprinsip; penanganan spesifiknya berbeda-beda tergantung kasusnya.
" Setiap kali seseorang memiliki klausa tangkapan kosong, mereka harus memiliki perasaan menyeramkan. Pasti ada saat-saat ketika itu sebenarnya hal yang benar untuk dilakukan, tetapi setidaknya Anda harus memikirkannya. Di Jawa Anda tidak bisa lepas dari perasaan menyeramkan itu. " —James Gosling
Alternatif yang dapat diterima (dalam urutan preferensi) adalah:
- Lempar pengecualian ke pemanggil metode Anda.
void setServerPort(String value) throws NumberFormatException { serverPort = Integer.parseInt(value); }
- Lempar pengecualian baru yang sesuai dengan tingkat abstraksi Anda.
void setServerPort(String value) throws ConfigurationException { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { throw new ConfigurationException("Port " + value + " is not valid."); } }
- Tangani kesalahan dengan baik dan gantikan nilai yang sesuai di blok
catch {}
./** Set port. If value is not a valid number, 80 is substituted. */ void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { serverPort = 80; // default port for server } }
- Tangkap pengecualian dan lempar instance baru
RuntimeException
. Ini berbahaya, jadi lakukan hanya jika Anda yakin jika kesalahan ini terjadi, hal yang tepat untuk dilakukan adalah crash./** Set port. If value is not a valid number, die. */ void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { throw new RuntimeException("port " + value " is invalid, ", e); } }
- Sebagai upaya terakhir, jika Anda yakin bahwa mengabaikan pengecualian itu tepat maka Anda dapat mengabaikannya, tetapi Anda juga harus memberi komentar alasannya dengan alasan yang bagus.
/** If value is not a valid number, original port number is used. */ void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { // Method is documented to just ignore invalid user input. // serverPort will just be unchanged. } }
Jangan menangkap pengecualian umum
Mungkin tergoda untuk malas saat menangkap pengecualian dan melakukan sesuatu seperti ini:
try { someComplicatedIOFunction(); // may throw IOException someComplicatedParsingFunction(); // may throw ParsingException someComplicatedSecurityFunction(); // may throw SecurityException // phew, made it all the way } catch (Exception e) { // I'll just catch all exceptions handleError(); // with one generic handler! }
Jangan lakukan ini. Di hampir semua kasus, tidak tepat untuk menangkap Exception
umum atau Throwable
(lebih disukai tidak Throwable
karena menyertakan pengecualian Error
). Ini berbahaya karena itu berarti pengecualian yang tidak pernah Anda duga (termasuk pengecualian runtime seperti ClassCastException
) terjebak dalam penanganan kesalahan tingkat aplikasi. Itu mengaburkan properti penanganan kegagalan kode Anda, artinya jika seseorang menambahkan jenis pengecualian baru dalam kode yang Anda panggil, kompiler tidak akan menunjukkan bahwa Anda perlu menangani kesalahan secara berbeda. Dalam kebanyakan kasus, Anda seharusnya tidak menangani berbagai jenis pengecualian dengan cara yang sama.
Pengecualian langka untuk aturan ini adalah kode pengujian dan kode tingkat atas tempat Anda ingin menangkap semua jenis kesalahan (untuk mencegahnya muncul di UI, atau agar tugas batch tetap berjalan). Dalam kasus ini, Anda dapat menangkap Exception
generik (atau Throwable
) dan menangani kesalahan dengan tepat. Pikirkan baik-baik sebelum melakukan ini, dan berikan komentar yang menjelaskan mengapa aman dalam konteks ini.
Alternatif untuk menangkap pengecualian umum:
- Tangkap setiap pengecualian secara terpisah sebagai bagian dari blok multitangkap, misalnya:
try { ... } catch (ClassNotFoundException | NoSuchMethodException e) { ... }
- Refactor kode Anda untuk memiliki penanganan kesalahan yang lebih halus, dengan beberapa blok percobaan. Pisahkan IO dari penguraian, dan tangani kesalahan secara terpisah di setiap kasus.
- Ulangi pengecualian. Seringkali Anda tidak perlu menangkap pengecualian pada level ini, biarkan saja metode membuangnya.
Ingatlah bahwa pengecualian adalah teman Anda! Saat kompiler mengeluh bahwa Anda tidak menangkap pengecualian, jangan cemberut. Senyum! Kompiler memudahkan Anda menangkap masalah runtime dalam kode Anda.
Jangan gunakan finalizer
Finalizer adalah cara untuk membuat potongan kode dieksekusi ketika sebuah objek dikumpulkan dari sampah. Meskipun finalizer berguna untuk pembersihan (khususnya sumber daya eksternal), tidak ada jaminan kapan finalizer akan dipanggil (atau bahkan akan dipanggil sama sekali).
Android tidak menggunakan finalizer. Dalam kebanyakan kasus, Anda dapat menggunakan penanganan pengecualian yang baik sebagai gantinya. Jika Anda benar-benar membutuhkan finalizer, tentukan metode close()
(atau sejenisnya) dan dokumentasikan dengan tepat kapan metode tersebut perlu dipanggil (lihat InputStream sebagai contoh). Dalam hal ini, pantas tetapi tidak diharuskan untuk mencetak pesan log singkat dari finalizer, selama tidak diharapkan membanjiri log.
Sepenuhnya memenuhi syarat impor
Saat Anda ingin menggunakan kelas Bar
dari paket foo
, ada dua cara yang memungkinkan untuk mengimpornya:
-
import foo.*;
Berpotensi mengurangi jumlah pernyataan impor.
-
import foo.Bar;
Memperjelas kelas apa yang digunakan dan kode lebih mudah dibaca oleh pengelola.
Gunakan import foo.Bar;
untuk mengimpor semua kode Android. Pengecualian eksplisit dibuat untuk pustaka standar Java ( java.util.*
, java.io.*
, dll.) dan kode pengujian unit ( junit.framework.*
).
Aturan perpustakaan Jawa
Ada konvensi untuk menggunakan pustaka dan alat Java Android. Dalam beberapa kasus, konvensi telah berubah dengan cara yang penting dan kode lama mungkin menggunakan pola atau pustaka yang tidak digunakan lagi. Saat bekerja dengan kode seperti itu, tidak apa-apa untuk melanjutkan gaya yang ada. Namun saat membuat komponen baru, jangan pernah menggunakan pustaka yang sudah tidak digunakan lagi.
Aturan gaya Java
Gunakan komentar standar Javadoc
Setiap file harus memiliki pernyataan hak cipta di bagian atas, diikuti oleh pernyataan paket dan impor (setiap blok dipisahkan oleh baris kosong), dan akhirnya deklarasi kelas atau antarmuka. Dalam komentar Javadoc, jelaskan apa yang dilakukan kelas atau antarmuka.
/* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.foo; import android.os.Blah; import android.view.Yada; import java.sql.ResultSet; import java.sql.SQLException; /** * Does X and Y and provides an abstraction for Z. */ public class Foo { ... }
Setiap kelas dan metode publik nontrivial yang Anda tulis harus berisi komentar Javadoc dengan setidaknya satu kalimat yang menjelaskan apa yang dilakukan kelas atau metode tersebut. Kalimat ini harus dimulai dengan kata kerja deskriptif orang ketiga.
Contoh
/** Returns the correctly rounded positive square root of a double value. */ static double sqrt(double a) { ... }
atau
/** * Constructs a new String by converting the specified array of * bytes using the platform's default character encoding. */ public String(byte[] bytes) { ... }
Anda tidak perlu menulis Javadoc untuk metode get and set yang sepele seperti setFoo()
jika semua yang dikatakan Javadoc Anda adalah "set Foo". Jika metode tersebut melakukan sesuatu yang lebih rumit (seperti memaksakan batasan atau memiliki efek samping yang penting), maka Anda harus mendokumentasikannya. Jika tidak jelas apa arti properti "Foo", Anda harus mendokumentasikannya.
Setiap metode yang Anda tulis, publik atau lainnya, akan mendapat manfaat dari Javadoc. Metode publik adalah bagian dari API dan karenanya memerlukan Javadoc. Android tidak menerapkan gaya khusus untuk menulis komentar Javadoc, tetapi Anda harus mengikuti petunjuk di Cara Menulis Komentar Dokumen untuk Alat Javadoc .
Tulis metode singkat
Jika memungkinkan, pertahankan metode tetap kecil dan fokus. Kami menyadari bahwa metode panjang terkadang sesuai, jadi tidak ada batasan keras yang diberikan pada panjang metode. Jika suatu metode melebihi 40 baris atau lebih, pikirkan apakah metode tersebut dapat dipecah tanpa merusak struktur program.
Tentukan bidang di tempat standar
Tentukan bidang baik di bagian atas file atau tepat sebelum metode yang menggunakannya.
Batasi ruang lingkup variabel
Pertahankan ruang lingkup variabel lokal seminimal mungkin. Ini meningkatkan keterbacaan dan pemeliharaan kode Anda dan mengurangi kemungkinan kesalahan. Deklarasikan setiap variabel di blok terdalam yang menyertakan semua penggunaan variabel.
Deklarasikan variabel lokal pada titik di mana mereka pertama kali digunakan. Hampir setiap deklarasi variabel lokal harus berisi penginisialisasi. Jika Anda belum memiliki informasi yang cukup untuk menginisialisasi variabel secara masuk akal, tunda deklarasi sampai Anda melakukannya.
Pengecualian adalah pernyataan try-catch. Jika sebuah variabel diinisialisasi dengan nilai kembalian dari sebuah metode yang melempar pengecualian yang dicentang, itu harus diinisialisasi di dalam blok try. Jika nilai harus digunakan di luar blok try, maka harus dideklarasikan sebelum blok try, yang belum dapat diinisialisasi secara wajar:
// Instantiate class cl, which represents some sort of Set Set s = null; try { s = (Set) cl.newInstance(); } catch(IllegalAccessException e) { throw new IllegalArgumentException(cl + " not accessible"); } catch(InstantiationException e) { throw new IllegalArgumentException(cl + " not instantiable"); } // Exercise the set s.addAll(Arrays.asList(args));
Namun, Anda bahkan dapat menghindari kasus ini dengan mengenkapsulasi blok try-catch dalam sebuah metode:
Set createSet(Class cl) { // Instantiate class cl, which represents some sort of Set try { return (Set) cl.newInstance(); } catch(IllegalAccessException e) { throw new IllegalArgumentException(cl + " not accessible"); } catch(InstantiationException e) { throw new IllegalArgumentException(cl + " not instantiable"); } } ... // Exercise the set Set s = createSet(cl); s.addAll(Arrays.asList(args));
Deklarasikan variabel loop dalam pernyataan for itu sendiri kecuali ada alasan kuat untuk melakukan sebaliknya:
for (int i = 0; i < n; i++) { doSomething(i); }
dan
for (Iterator i = c.iterator(); i.hasNext(); ) { doSomethingElse(i.next()); }
Memesan pernyataan impor
Urutan pernyataan impor adalah:
- impor Android
- Impor dari pihak ketiga (
com
,junit
,net
,org
) -
java
danjavax
Agar sama persis dengan pengaturan IDE, impor harus:
- Abjad dalam setiap pengelompokan, dengan huruf kapital sebelum huruf kecil (misalnya, Z sebelum a)
- Dipisahkan oleh baris kosong antara setiap pengelompokan utama (
android
,com
,junit
,net
,org
,java
,javax
)
Awalnya, tidak ada persyaratan gaya pada pengurutan, artinya IDE selalu mengubah pengurutan atau pengembang IDE harus menonaktifkan fitur manajemen impor otomatis dan memelihara impor secara manual. Ini dianggap buruk. Ketika gaya Java ditanya, gaya yang disukai sangat bervariasi dan turun ke Android yang hanya perlu "memilih urutan dan konsisten." Jadi kami memilih gaya, memperbarui panduan gaya, dan membuat IDE mematuhinya. Kami berharap saat pengguna IDE mengerjakan kode, impor di semua paket akan cocok dengan pola ini tanpa upaya rekayasa tambahan.
Kami memilih gaya ini sedemikian rupa sehingga:
- Impor yang ingin dilihat orang pada awalnya cenderung berada di atas (
android
). - Impor yang paling ingin dilihat orang cenderung berada di bawah (
java
). - Manusia dapat dengan mudah mengikuti gaya tersebut.
- IDE dapat mengikuti gaya.
Letakkan impor statis di atas semua impor lainnya yang diurutkan dengan cara yang sama seperti impor biasa.
Gunakan spasi untuk lekukan
Kami menggunakan empat (4) indentasi spasi untuk blok dan tidak pernah tab. Jika ragu, konsistenlah dengan kode di sekitarnya.
Kami menggunakan delapan (8) indentasi spasi untuk pembungkus baris, termasuk pemanggilan fungsi dan penugasan.
Direkomendasikan
Instrument i = someLongExpression(that, wouldNotFit, on, one, line);
Tidak direkomendasikan
Instrument i = someLongExpression(that, wouldNotFit, on, one, line);
Ikuti konvensi penamaan bidang
- Nama kolom non-publik dan non-statis dimulai dengan
m
. - Nama bidang statis dimulai dengan
s
. - Bidang lain dimulai dengan huruf kecil.
- Bidang akhir statis (konstanta, sangat tidak dapat diubah) adalah
ALL_CAPS_WITH_UNDERSCORES
.
Sebagai contoh:
public class MyClass { public static final int SOME_CONSTANT = 42; public int publicField; private static MyClass sSingleton; int mPackagePrivate; private int mPrivate; protected int mProtected; }
Gunakan gaya penjepit standar
Letakkan tanda kurung pada baris yang sama dengan kode sebelumnya, bukan pada barisnya sendiri:
class MyClass { int func() { if (something) { // ... } else if (somethingElse) { // ... } else { // ... } } }
Kami membutuhkan tanda kurung di sekitar pernyataan untuk kondisional. Pengecualian: Jika seluruh kondisional (kondisi dan tubuh) muat dalam satu baris, Anda dapat (namun tidak wajib) meletakkan semuanya dalam satu baris. Misalnya, ini dapat diterima:
if (condition) { body(); }
dan ini dapat diterima:
if (condition) body();
tetapi ini tidak dapat diterima:
if (condition) body(); // bad!
Batasi panjang garis
Panjang setiap baris teks dalam kode Anda harus maksimal 100 karakter. Meskipun banyak diskusi seputar aturan ini, keputusan tetap bahwa 100 karakter adalah maksimal dengan pengecualian berikut :
- Jika baris komentar berisi contoh perintah atau URL literal yang lebih panjang dari 100 karakter, baris tersebut mungkin lebih panjang dari 100 karakter untuk kemudahan potong dan tempel.
- Garis impor dapat melewati batas karena manusia jarang melihatnya (ini juga menyederhanakan penulisan alat).
Gunakan anotasi Java standar
Anotasi harus mendahului pengubah lain untuk elemen bahasa yang sama. Anotasi penanda sederhana (misalnya, @Override
) dapat dicantumkan pada baris yang sama dengan elemen bahasa. Jika ada beberapa anotasi, atau anotasi berparameter, cantumkan satu per baris dalam urutan abjad.
Praktik standar Android untuk tiga anotasi standar di Java adalah:
- Gunakan anotasi
@Deprecated
setiap kali penggunaan elemen beranotasi tidak disarankan. Jika Anda menggunakan anotasi@Deprecated
, Anda juga harus memiliki tag Javadoc@deprecated
dan harus menamai implementasi alternatif. Selain itu, ingatlah bahwa metode@Deprecated
masih berfungsi . Jika Anda melihat kode lama yang memiliki tag Javadoc@deprecated
, tambahkan anotasi@Deprecated
. - Gunakan anotasi
@Override
setiap kali metode menimpa deklarasi atau implementasi dari superclass. Misalnya, jika Anda menggunakan tag Javadoc@inheritdocs
, dan berasal dari kelas (bukan antarmuka), Anda juga harus memberi anotasi bahwa metode tersebut menimpa metode kelas induk. - Gunakan anotasi
@SuppressWarnings
hanya dalam keadaan yang tidak memungkinkan untuk menghilangkan peringatan. Jika peringatan lolos uji "tidak mungkin dihilangkan" ini, anotasi@SuppressWarnings
harus digunakan, untuk memastikan bahwa semua peringatan mencerminkan masalah sebenarnya dalam kode.Saat anotasi
@SuppressWarnings
diperlukan, anotasi harus diawali dengan komentarTODO
yang menjelaskan kondisi "tidak mungkin dihilangkan". Ini biasanya mengidentifikasi kelas yang menyinggung yang memiliki antarmuka yang canggung. Sebagai contoh:// TODO: The third-party class com.third.useful.Utility.rotate() needs generics @SuppressWarnings("generic-cast") List<String> blix = Utility.rotate(blax);
Saat anotasi
@SuppressWarnings
diperlukan, faktor ulang kode untuk mengisolasi elemen perangkat lunak tempat anotasi diterapkan.
Perlakukan akronim sebagai kata
Perlakukan akronim dan singkatan sebagai kata dalam penamaan variabel, metode, dan kelas agar nama lebih mudah dibaca:
Bagus | Buruk |
---|---|
XmlHttpRequest | Permintaan XMLHTTP |
getCustomerId | getCustomerID |
kelas HTML | HTML kelas |
Url string | URL string |
id panjang | identitas panjang |
Karena basis kode JDK dan Android tidak konsisten di sekitar akronim, hampir tidak mungkin untuk konsisten dengan kode di sekitarnya. Karena itu, selalu perlakukan akronim sebagai kata.
Gunakan komentar TODO
Gunakan komentar TODO
untuk kode yang bersifat sementara, solusi jangka pendek, atau cukup baik tetapi tidak sempurna. Komentar ini harus menyertakan string TODO
dengan huruf besar semua, diikuti dengan tanda titik dua:
// TODO: Remove this code after the UrlTable2 has been checked in.
dan
// TODO: Change this to use a flag instead of a constant.
Jika TODO
Anda berbentuk "Di masa mendatang, lakukan sesuatu", pastikan Anda menyertakan tanggal tertentu ("Perbaiki sebelum November 2005") atau acara tertentu ("Hapus kode ini setelah semua pencampur produksi memahami protokol V7." ).
Log hemat
Sementara logging diperlukan, itu memiliki dampak negatif pada kinerja dan kehilangan kegunaannya jika tidak disimpan secara wajar. Fasilitas penebangan menyediakan lima tingkat penebangan yang berbeda:
-
ERROR
: Gunakan ketika sesuatu yang fatal telah terjadi, yaitu, sesuatu akan memiliki konsekuensi yang terlihat oleh pengguna dan tidak dapat dipulihkan tanpa menghapus beberapa data, mencopot aplikasi, menghapus partisi data, atau mem-reflash seluruh perangkat (atau lebih buruk). Level ini selalu dicatat. Masalah yang membenarkan beberapa logging pada tingkatERROR
adalah kandidat yang baik untuk dilaporkan ke server pengumpul statistik. -
WARNING
: Gunakan ketika terjadi sesuatu yang serius dan tidak terduga, yaitu, sesuatu yang memiliki konsekuensi yang terlihat oleh pengguna tetapi kemungkinan besar dapat dipulihkan tanpa kehilangan data dengan melakukan beberapa tindakan eksplisit, mulai dari menunggu atau memulai ulang aplikasi hingga mengunduh ulang versi baru aplikasi atau me-reboot perangkat. Level ini selalu dicatat. Masalah yang membenarkan pembuatan log pada tingkatWARNING
juga dapat dipertimbangkan untuk dilaporkan ke server pengumpul statistik. -
INFORMATIVE
: Gunakan untuk mencatat bahwa sesuatu yang menarik terjadi, yaitu, ketika terdeteksi situasi yang kemungkinan memiliki dampak luas, meskipun belum tentu merupakan kesalahan. Kondisi seperti itu seharusnya hanya dicatat oleh modul yang percaya bahwa itu adalah yang paling otoritatif di domain itu (untuk menghindari pencatatan ganda oleh komponen yang tidak otoritatif). Level ini selalu dicatat. -
DEBUG
: Gunakan untuk mencatat lebih lanjut apa yang terjadi pada perangkat yang mungkin relevan untuk menyelidiki dan men-debug perilaku yang tidak diharapkan. Catat hanya apa yang diperlukan untuk mengumpulkan informasi yang cukup tentang apa yang terjadi dengan komponen Anda. Jika log debug Anda mendominasi log, maka Anda harus menggunakan log verbose.Level ini dicatat bahkan pada build rilis, dan harus dikelilingi oleh blok
if (LOCAL_LOG)
atauif LOCAL_LOGD)
, di manaLOCAL_LOG[D]
ditentukan di kelas atau subkomponen Anda, sehingga ada kemungkinan untuk menonaktifkan semua logging tersebut . Oleh karena itu, tidak boleh ada logika aktif dalam blokif (LOCAL_LOG)
. Semua bangunan string untuk log juga perlu ditempatkan di dalam blokif (LOCAL_LOG)
. Jangan refactor pemanggilan logging keluar menjadi pemanggilan metode jika itu akan menyebabkan pembangunan string dilakukan di luar blokif (LOCAL_LOG)
.Ada beberapa kode yang masih bertuliskan
if (localLOGV)
. Ini juga dianggap dapat diterima, meskipun namanya tidak standar. -
VERBOSE
: Gunakan untuk yang lainnya. Level ini hanya dicatat pada build debug dan harus dikelilingi oleh blokif (LOCAL_LOGV)
(atau yang setara) sehingga dapat dikompilasi secara default. Bangunan string apa pun dihapus dari versi rilis dan harus muncul di dalam blokif (LOCAL_LOGV)
.
Catatan
- Dalam modul tertentu, selain pada level
VERBOSE
, kesalahan hanya boleh dilaporkan satu kali jika memungkinkan. Dalam satu rantai pemanggilan fungsi dalam modul, hanya fungsi terdalam yang akan mengembalikan kesalahan, dan penelepon dalam modul yang sama hanya boleh menambahkan beberapa pencatatan jika itu secara signifikan membantu mengisolasi masalah. - Dalam rantai modul, selain di tingkat
VERBOSE
, ketika modul tingkat rendah mendeteksi data yang tidak valid yang berasal dari modul tingkat yang lebih tinggi, modul tingkat rendah seharusnya hanya mencatat situasi ini ke logDEBUG
, dan hanya jika pencatatan menyediakan informasi yang tidak tersedia untuk penelepon. Khususnya, tidak perlu mencatat situasi di mana pengecualian dilemparkan (pengecualian harus berisi semua informasi yang relevan), atau di mana satu-satunya informasi yang dicatat dimuat dalam kode kesalahan. Ini sangat penting dalam interaksi antara kerangka kerja dan aplikasi, dan kondisi yang disebabkan oleh aplikasi pihak ketiga yang ditangani dengan benar oleh kerangka kerja tidak boleh memicu pencatatan lebih tinggi dari tingkatDEBUG
. Satu-satunya situasi yang harus memicu logging pada levelINFORMATIVE
atau lebih tinggi adalah saat modul atau aplikasi mendeteksi kesalahan pada levelnya sendiri atau berasal dari level yang lebih rendah. - Ketika suatu kondisi yang biasanya membenarkan beberapa logging kemungkinan terjadi berkali-kali, itu bisa menjadi ide yang baik untuk menerapkan beberapa mekanisme pembatasan kecepatan untuk mencegah log meluap dengan banyak salinan duplikat dari informasi yang sama (atau sangat mirip).
- Kehilangan konektivitas jaringan dianggap umum dan diharapkan sepenuhnya, dan tidak boleh dicatat secara serampangan. Hilangnya konektivitas jaringan yang memiliki konsekuensi dalam aplikasi harus dicatat di tingkat
DEBUG
atauVERBOSE
(bergantung pada apakah konsekuensinya cukup serius dan tidak terduga untuk dicatat dalam versi rilis). - Memiliki sistem file lengkap pada sistem file yang dapat diakses oleh atau atas nama aplikasi pihak ketiga tidak boleh dicatat pada level yang lebih tinggi dari INFORMATIVE.
- Data tidak valid yang berasal dari sumber yang tidak tepercaya (termasuk file apa pun di penyimpanan bersama, atau data yang datang melalui koneksi jaringan) dianggap diharapkan dan tidak boleh memicu pencatatan apa pun pada tingkat yang lebih tinggi dari
DEBUG
ketika terdeteksi tidak valid (dan bahkan kemudian mencatat harus dibatasi semaksimal mungkin). - Saat digunakan pada objek
String
, operator+
secara implisit membuat instanceStringBuilder
dengan ukuran buffer default (16 karakter) dan kemungkinan objekString
sementara lainnya. Jadi secara eksplisit membuat objekStringBuilder
tidak lebih mahal daripada mengandalkan operator+
default (dan bisa jauh lebih efisien). Perlu diingat bahwa kode yang memanggilLog.v()
dikompilasi dan dieksekusi pada build rilis, termasuk membuat string, meskipun log tidak sedang dibaca. - Log apa pun yang dimaksudkan untuk dibaca oleh orang lain dan tersedia dalam versi rilis harus singkat tanpa samar, dan harus dapat dimengerti. Ini termasuk semua masuk ke tingkat
DEBUG
. - Jika memungkinkan, tetap masuk dalam satu baris. Panjang baris hingga 80 atau 100 karakter dapat diterima. Hindari panjang lebih dari 130 atau 160 karakter (termasuk panjang tag) jika memungkinkan.
- Jika laporan logging berhasil, jangan pernah menggunakannya pada level yang lebih tinggi dari
VERBOSE
. - Jika Anda menggunakan pembuatan log sementara untuk mendiagnosis masalah yang sulit direproduksi, pertahankan pada tingkat
DEBUG
atauVERBOSE
dan lampirkan dengan blok if yang memungkinkan untuk menonaktifkannya pada waktu kompilasi. - Berhati-hatilah dengan kebocoran keamanan melalui log. Hindari mencatat informasi pribadi. Secara khusus, hindari mencatat informasi tentang konten yang dilindungi. Ini sangat penting saat menulis kode framework karena tidak mudah untuk mengetahui sebelumnya apa yang akan dan tidak akan menjadi informasi pribadi atau konten yang dilindungi.
- Jangan pernah menggunakan
System.out.println()
(atauprintf()
untuk kode native).System.out
danSystem.err
dialihkan ke/dev/null
, sehingga pernyataan cetak Anda tidak memiliki efek yang terlihat. Namun, semua pembuatan string yang terjadi untuk panggilan ini tetap dijalankan. - Aturan utama logging adalah bahwa log Anda mungkin tidak perlu mendorong log lain keluar dari buffer, sama seperti orang lain mungkin tidak mendorong log Anda.
Aturan gaya Javatests
Ikuti konvensi penamaan metode pengujian dan gunakan garis bawah untuk memisahkan apa yang sedang diuji dari kasus tertentu yang sedang diuji. Gaya ini memudahkan untuk melihat kasus mana yang sedang diuji. Sebagai contoh:
testMethod_specificCase1 testMethod_specificCase2 void testIsDistinguishable_protanopia() { ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA) assertFalse(colorMatcher.isDistinguishable(Color.RED, Color.BLACK)) assertTrue(colorMatcher.isDistinguishable(Color.X, Color.Y)) }