Gaya kode di halaman ini adalah aturan ketat untuk menyumbangkan kode Java ke Proyek Open Source Android (AOSP). Kontribusi untuk platform Android yang tidak mematuhi aturan ini umumnya tidak diterima. Rab menyadari bahwa tidak semua kode yang ada mengikuti aturan ini, tapi kita mengharapkan semua kode baru agar patuh. Lihat Coding dengan hormat contoh terminologi yang dapat digunakan dan dihindari untuk ekosistem yang lebih inklusif.
Tetaplah konsisten
Salah satu aturan paling sederhana adalah BERKONSISTEN. Jika Anda mengedit kode, lakukan beberapa
menit untuk melihat kode di sekitarnya dan menentukan gayanya. Jika hal tersebut
kode menggunakan spasi di sekitar klausa if
, Anda juga harus melakukannya. Jika kode
komentar memiliki kotak-kotak bintang kecil di sekelilingnya, buat komentar Anda
kotak-kotak kecil bintang
di sekelilingnya.
Inti dari memiliki pedoman gaya adalah memiliki kosakata umum tentang {i>coding<i}, sehingga pembaca dapat berkonsentrasi pada apa yang Anda katakan, bukan pada bagaimana Anda mengucapkannya. Kami menyajikan aturan gaya global di sini sehingga Anda tahu kosakata, tetapi gaya lokal juga penting. Jika kode yang Anda tambahkan ke file terlihat sangat berbeda dari kode yang ada di sekitarnya, membuat pembaca tidak selaras ketika mereka membacanya. Coba hindari hal ini.
Aturan bahasa Java
Android mengikuti konvensi coding Java standar dengan aturan tambahan yang dijelaskan di bawah.
Jangan abaikan pengecualian
Anda mungkin ingin menulis kode yang mengabaikan pengecualian, seperti:
void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { } }
Jangan lakukan ini. Meskipun Anda mungkin berpikir kode Anda tidak akan pernah mengalami ini kondisi {i>error <i}atau bahwa tidak penting untuk menanganinya, mengabaikan jenis membuat ranjau di kode Anda untuk orang lain agar dipicu suatu hari nanti. Anda harus menangani setiap pengecualian dalam kode dengan dengan prinsip; penanganan spesifik akan berbeda-beda tergantung pada kasusnya.
"Kapan pun seseorang memiliki klausa tangkapan kosong, pelanggan. Pasti ada kalanya informasi tersebut yang harus dilakukan, tapi setidaknya Anda harus memikirkannya. Di Java, Anda tidak bisa terbebas dari perasaan menakutkan itu." — Jefri Gosling
Alternatif yang dapat diterima (dalam urutan preferensi) adalah:
- Tampilkan pengecualian ke pemanggil metode Anda.
void setServerPort(String value) throws NumberFormatException { serverPort = Integer.parseInt(value); }
-
Tampilkan 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 error dengan baik dan ganti 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 tampilkan instance
RuntimeException
baru. Ini berbahaya, jadi lakukan hanya jika Anda yakin bahwa terjadi {i>error<i}, maka hal yang sesuai untuk dilakukan adalah {i>crash<i}./** 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 merupakan
sesuai maka Anda boleh mengabaikannya, namun Anda juga harus memberi komentar mengapa dengan
Anda memiliki alasan yang kuat.
/** 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. } }
Tidak menangkap pengecualian umum
Anda mungkin ingin malas 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. Hampir semua kasus, tidaklah
pantas untuk menangkap
Exception
atau Throwable
(sebaiknya bukan Throwable
karena menyertakan
pengecualian Error
). Ini berbahaya karena itu
berarti bahwa pengecualian
yang tidak pernah Anda duga (termasuk pengecualian runtime seperti ClassCastException
)
terlibat dalam penanganan
kesalahan tingkat aplikasi. {i>Metadata<i} mengaburkan kegagalan
menangani properti kode Anda, artinya jika seseorang menambahkan jenis
dalam kode yang Anda panggil, compiler tidak akan menunjukkan
bahwa Anda perlu menangani
{i>error<i} secara berbeda. Dalam kebanyakan kasus, Anda
seharusnya tidak menangani
berbagai jenis pengecualian dengan cara yang sama.
Pengecualian yang jarang terjadi untuk aturan ini adalah kode pengujian dan kode tingkat atas dengan
Anda ingin menemukan berbagai jenis {i>error<i} (untuk mencegahnya muncul
di UI, atau untuk membuat tugas batch tetap berjalan). Dalam kasus ini, Anda mungkin mendapati
Exception
(atau Throwable
) generik dan menangani error dengan tepat.
Namun, pikirkan baik-baik sebelum melakukan ini, dan beri komentar
menjelaskan mengapa kampanye ini aman dalam konteks ini.
Alternatif untuk menangkap pengecualian umum:
-
Tangkap setiap pengecualian secara terpisah sebagai bagian dari blok multi-tangkapan, misalnya:
try { ... } catch (ClassNotFoundException | NoSuchMethodException e) { ... }
- Faktorkan ulang kode Anda agar penanganan errornya lebih mendetail, dengan beberapa blok percobaan. Memisahkan IO dari penguraian, dan menangani error secara terpisah dalam setiap kasus.
- Tampilkan ulang pengecualian. Sering kali Anda tidak perlu menangkap pengecualian pada level ini, biarkan saja metode itu yang membuangnya.
Ingatlah bahwa Anda hanya perlu pengecualian! Ketika kompiler mengeluh bahwa Anda jangan cemberut, jangan cemberut. Senyum! Kompilatornya baru saja berhasil memudahkan Anda menangkap masalah runtime dalam kode.
Jangan gunakan finaler
Finalizer adalah cara untuk mengeksekusi sepotong kode ketika suatu objek pembersihan sampah memori. Sementara finaler dapat berguna untuk pembersihan (terutama sumber daya eksternal), tidak ada jaminan mengenai kapan finaler akan dipanggil (atau bahkan akan dipanggil sama sekali).
Android tidak menggunakan finaler. Dalam kebanyakan kasus, Anda dapat menggunakan
penanganan pengecualian yang baik. Jika Anda benar-benar
membutuhkan finaler,
tentukan metode close()
(atau yang serupa) dan dokumentasikan tepat ketika metode tersebut
metode perlu dipanggil (lihat
InputStream sebagai contoh). Dalam kasus ini,
sudah sesuai tetapi tidak diperlukan untuk
mencetak pesan log singkat dari
finaler, selama tidak membanjiri log.
Impor yang memenuhi syarat sepenuhnya
Bila Anda ingin menggunakan class Bar
dari paket foo
, ada dua
cara yang mungkin untuk mengimpornya:
import foo.*;
Berpotensi mengurangi jumlah pernyataan impor.
import foo.Bar;
Memperjelas class yang digunakan dan kodenya lebih dapat dibaca oleh pengelola.
Gunakan import foo.Bar;
untuk mengimpor semua kode Android. Channel
pengecualian eksplisit dibuat untuk library standar Java (java.util.*
,
java.io.*
, dll.) dan kode pengujian unit (junit.framework.*
).
Aturan library Java
Ada konvensi untuk menggunakan library dan alat Java Android. Di beberapa dalam beberapa kasus, konvensi telah berubah dengan cara penting dan kode lama mungkin menggunakan pola atau pustaka yang sudah tidak digunakan lagi. Saat bekerja dengan kode seperti itu, Anda dapat melanjutkan gaya yang sudah ada. Saat membuat komponen baru namun, jangan pernah menggunakan library yang tidak digunakan lagi.
Aturan gaya Java
Menggunakan komentar standar Javadoc
Setiap file harus memiliki pernyataan hak cipta di bagian atas, diikuti dengan pernyataan paket dan impor (setiap blok dipisahkan oleh baris kosong), dan terakhir deklarasi class atau antarmuka. Pada komentar Javadoc, untuk mendeskripsikan fungsi class atau antarmuka.
/* * Copyright yyyy 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 class dan metode publik nontrivial yang Anda tulis harus berisi komentar Javadoc dengan setidaknya satu kalimat yang menjelaskan apa yang atau metode lain. Kalimat ini harus dimulai dengan orang ketiga deskriptif.
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 dan set trivial seperti
setFoo()
jika semua Javadoc Anda adalah "sets Foo". Jika
metode ini melakukan sesuatu yang lebih kompleks (seperti menerapkan batasan
atau memiliki efek samping yang penting), maka Anda harus mendokumentasikannya. Jika tidak
sudah jelas apa yang
dimaksud dengan properti "Foo" berarti, Anda harus
mendokumentasikannya.
Setiap metode yang Anda tulis, publik atau lainnya, akan mendapat manfaat dari Javadoc. Metode publik adalah bagian dari API sehingga memerlukan Javadoc. Android tidak memberlakukan gaya khusus untuk menulis Javadoc tetapi Anda harus mengikuti petunjuk di Cara Menulis Komentar Dokumen untuk Alat Javadoc.
Menulis metode singkat
Jika memungkinkan, usahakan agar metode tetap kecil dan fokus. Kami paham bahwa lama terkadang sesuai, sehingga tidak ada batasan pasti yang ditempatkan pada metode paruh. Jika suatu metode melebihi 40 baris atau lebih, pikirkan apakah metode itu dapat diselesaikan tanpa merusak struktur program.
Menentukan kolom di tempat standar
Tentukan kolom di bagian atas file atau tepat sebelum metode yang menggunakannya.
Batasi cakupan variabel
Minimalkan cakupan variabel lokal. Ini meningkatkan keterbacaan dan pengelolaan kode Anda dan mengurangi kemungkinan terjadinya error. Deklarasikan setiap variabel di bagian terdalam yang mencakup semua penggunaan variabel.
Deklarasikan variabel lokal pada titik tempat variabel tersebut pertama kali digunakan. Hampir setiap deklarasi variabel lokal harus berisi penginisialisasi. Jika Anda belum memiliki informasi yang cukup untuk melakukan inisialisasi variabel dengan bijak, tunda pernyataan sampai Anda melakukannya.
Pengecualiannya adalah pernyataan try-catch. Jika variabel diinisialisasi dengan nilai hasil dari metode yang menampilkan pengecualian yang dicentang, maka harus diinisialisasi di dalam blok try. Jika nilai harus digunakan di luar coba, maka harus dideklarasikan sebelum blok try, di mana ia belum dapat diinisialisasi secara bijaksana:
// 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 melakukan enkapsulasi {i>try-catch<i} memblokir dalam 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));
Mendeklarasikan variabel loop dalam pernyataan for itu sendiri kecuali ada alasan kuat untuk melakukan yang sebaliknya:
for (int i = 0; i < n; i++) { doSomething(i); }
dan
for (Iterator i = c.iterator(); i.hasNext(); ) { doSomethingElse(i.next()); }
Pernyataan impor pesanan
Urutan pernyataan impor adalah:
- Impor Android
-
Impor dari pihak ketiga (
com
,junit
,net
,org
) -
java
danjavax
Agar sama persis dengan setelan IDE, impornya harus berupa:
- Menurut abjad dalam setiap grup, dengan huruf kapital sebelum huruf kecil huruf besar/kecil (misalnya, Z sebelum a)
-
Dipisahkan oleh garis kosong di antara setiap pengelompokan utama
(
android
,com
,junit
,net
,org
,java
,javax
)
Awalnya, tidak ada persyaratan gaya pada pengurutan, yang berarti IDE selalu mengubah urutan atau pengembang IDE harus nonaktifkan fitur pengelolaan impor otomatis dan mengelolanya secara manual impor. Hal ini dianggap buruk. Ketika gaya Java diminta, gaya yang disukai sangat bervariasi dan bergantung pada Android yang perlu hanya "memilih pesanan dan konsisten". Jadi kita memilih gaya, memperbarui panduan gaya, dan membuat IDE mematuhinya. Kami berharap bahwa sebagai Pengguna IDE mengerjakan kode, impor dalam semua paket akan cocok dengan tanpa upaya teknis tambahan.
Kita memilih gaya ini sedemikian rupa sehingga:
-
Impor yang ingin dilihat orang pertama kali cenderung
(
android
). -
Impor yang ingin dilihat orang setidaknya cenderung berada di bagian bawah
(
java
). - Manusia dapat dengan mudah mengikuti gaya.
- IDE dapat mengikuti gaya.
Tempatkan impor statis di atas semua impor lainnya diurutkan dengan cara yang sama seperti impor reguler.
Menggunakan spasi untuk indentasi
Kami menggunakan empat (4) indentasi spasi untuk blok dan tidak pernah tab. Jika ragu, konsisten dengan kode di sekitarnya.
Kami menggunakan delapan (8) indentasi spasi untuk {i>line wrap<i}, termasuk panggilan fungsi dan tugas.
Direkomendasikan
Instrument i = someLongExpression(that, wouldNotFit, on, one, line);
Tidak direkomendasikan
Instrument i = someLongExpression(that, wouldNotFit, on, one, line);
Ikuti konvensi penamaan {i>field<i}
-
Nama kolom non-publik dan non-statis dimulai dengan
m
. -
Nama kolom statis dimulai dengan
s
. - Kolom lain dimulai dengan huruf kecil.
-
Kolom akhir statis (konstanta, sangat tidak dapat diubah) adalah
ALL_CAPS_WITH_UNDERSCORES
.
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 kurung kurawal standar
Letakkan tanda kurung kurawal pada baris yang sama dengan kode di depannya, bukan di barisnya sendiri:
class MyClass { int func() { if (something) { // ... } else if (somethingElse) { // ... } else { // ... } } }
Kita memerlukan tanda kurung kurawal di sekitar pernyataan untuk kondisional. Pengecualian: Jika seluruh kondisional (kondisi dan {i>body<i}) muat dalam satu baris, Anda dapat (tetapi tidak berkewajiban) menyatukan semuanya dalam satu baris. Misalnya, dapat diterima:
if (condition) { body(); }
dan ini dapat diterima:
if (condition) body();
tetapi hal ini tidak dapat diterima:
if (condition) body(); // bad!
Batasi panjang baris
Setiap baris teks dalam kode Anda maksimal harus 100 karakter. Meskipun banyak diskusi telah mengelilingi aturan ini, keputusannya tetap bahwa 100 karakter adalah jumlah maksimum dengan pengecualian:
- Jika baris komentar berisi contoh perintah atau URL literal yang lebih panjang dari 100 karakter, baris tersebut bisa lebih dari 100 karakter untuk kemudahan memotong dan menempel.
- Baris impor dapat melampaui batas karena manusia jarang melihatnya (ini juga menyederhanakan penulisan alat).
Menggunakan anotasi Java standar
Anotasi harus mendahului pengubah lain untuk bahasa yang sama
. Anotasi penanda sederhana (misalnya, @Override
) dapat dicantumkan di
baris yang sama dengan elemen bahasa. Jika ada beberapa anotasi,
atau anotasi berparameter, cantumkan satu per baris
sesuai abjad.
Praktik standar Android untuk tiga anotasi yang telah ditentukan sebelumnya dalam Java adalah:
-
Menggunakan anotasi
@Deprecated
ketika penggunaan elemen yang dianotasi tidak disarankan. Jika Anda menggunakan anotasi@Deprecated
, Anda juga harus memiliki@deprecated
Tag Javadoc dan harus menamai implementasi alternatif. Selain itu, ingat bahwa metode@Deprecated
masih seharusnya berfungsi. Jika Anda melihat kode lama yang memiliki tag Javadoc@deprecated
, tambahkan metode anotasi@Deprecated
. -
Gunakan anotasi
@Override
setiap kali metode mengganti deklarasi atau implementasi dari superclass. Misalnya, jika Anda menggunakan tag Javadoc@inheritdocs
, dan berasal dari class (bukan antarmuka), Anda juga harus memberi anotasi bahwa metode tersebut mengganti metode class induk. -
Menggunakan anotasi
@SuppressWarnings
hanya dalam keadaan di mana tidak mungkin untuk menghilangkan peringatan. Jika peringatan dianggap "tidak mungkin untuk menghilangkan" anotasi@SuppressWarnings
harus digunakan, untuk memastikan bahwa semua peringatan mencerminkan masalah sebenarnya dalam pada kode sumber.Saat diperlukan, anotasi
@SuppressWarnings
harus diawali dengan komentarTODO
yang menjelaskan "tidak mungkin untuk menghilangkan" . Hal ini biasanya mengidentifikasi kelas yang mengganggu yang memiliki antarmuka canggung. 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, faktorkan ulang kode untuk mengisolasi elemen software tempat anotasi berlaku.
Perlakukan akronim sebagai kata
Perlakukan akronim dan singkatan sebagai kata dalam penamaan variabel, metode, dan class untuk membuat nama lebih mudah dibaca:
Bagus | Buruk |
---|---|
{i>XmlHttpRequest<i} | Permintaan |
getCustomerId | getCustomerID |
HTML kelas | HTML kelas |
URL string | URL String |
long id | ID panjang |
Karena JDK dan code base Android tidak konsisten akronim ini, hampir tidak mungkin untuk konsisten dengan kode di sekitarnya. Oleh karena itu, selalu anggap akronim sebagai kata.
Menggunakan 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
di semua
huruf besar, diikuti dengan 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" memastikan
bahwa Anda menyertakan tanggal tertentu ("Perbaiki paling lambat November 2005") atau
peristiwa tertentu ("Hapus kode ini setelah semua mixer produksi
memahami protokol V7.").
Catat dengan hemat
Meskipun logging diperlukan, hal ini berdampak negatif pada kinerja dan kehilangan kegunaannya jika tidak dijaga secara wajar singkat. Fasilitas pencatatan log menyediakan lima tingkat pencatatan yang berbeda:
-
ERROR
: Gunakan saat terjadi sesuatu yang fatal, yaitu sesuatu akan memiliki konsekuensi yang terlihat oleh pengguna dan tidak akan dapat dipulihkan tanpa menghapus beberapa data, menghapus instalan aplikasi, menghapus partisi data, atau menginstal ulang seluruh perangkat (atau lebih buruk). Level ini selalu dicatat. Masalah yang terkait dengan pencatatan log di LevelERROR
adalah kandidat yang baik untuk dilaporkan ke server pengumpulan statistik. -
WARNING
: Gunakan saat terjadi sesuatu yang serius dan tidak terduga terjadi, yaitu, sesuatu yang akan memiliki konsekuensi yang terlihat oleh pengguna tetapi dapat dipulihkan tanpa kehilangan data dengan melakukan beberapa tindakan eksplisit, mulai dari menunggu atau memulai ulang aplikasi untuk mengunduh ulang versi baru dari aplikasi atau me-{i>reboot<i} perangkat seluler. Level ini selalu dicatat. Masalah yang membenarkan pencatatan di tingkatWARNING
juga dapat dipertimbangkan untuk pelaporan ke server pengumpulan statistik. -
INFORMATIVE
: Gunakan untuk mencatat bahwa sesuatu yang menarik terjadi, yaitu ketika sebuah situasi yang kemungkinan besar terdeteksi memiliki dampak yang luas, meskipun bukan merupakan kesalahan. Sungguh kondisi ini seharusnya hanya dicatat oleh modul yang yakin paling otoritatif di domain tersebut (untuk menghindari duplikasi log oleh komponen non-otoritatif). Level ini selalu dicatat. -
DEBUG
: Gunakan untuk mencatat lebih lanjut apa yang terjadi di perangkat yang mungkin relevan untuk diselidiki dan melakukan debug perilaku model. Catat hanya yang diperlukan untuk mengumpulkan cukup informasi tentang apa yang terjadi dengan komponen Anda. Jika debug Anda log mendominasi log, maka Anda harus menggunakan {i>verbose<i} pembuatan log.Level ini dicatat bahkan pada build rilis, dan diperlukan untuk dikelilingi oleh blok
if (LOCAL_LOG)
atauif LOCAL_LOGD)
, tempatLOCAL_LOG[D]
ditentukan di class atau subkomponen, jadi ada kemungkinan untuk menonaktifkan semua logging tersebut. Oleh karena itu, tidak boleh ada logika yang aktif dalam blokif (LOCAL_LOG)
. Semua pembuatan {i>string<i} untuk log juga harus ditempatkan di dalam Blokif (LOCAL_LOG)
. Jangan faktorkan ulang panggilan logging ke dalam panggilan metode jika akan menyebabkan pembuatan string terjadi di luar Blokif (LOCAL_LOG)
.Ada beberapa kode yang masih bertuliskan
if (localLOGV)
. Ini dianggap sebagai dapat diterima, meskipun namanya tidak standar. -
VERBOSE
: Digunakan untuk lainnya. Level ini hanya yang dicatat pada build debug dan harus dikelilingi olehif (LOCAL_LOGV)
blok (atau yang setara) sehingga dapat dikompilasi secara {i>default<i}. Setiap bangunan {i>string<i} dilepas dari build rilis dan harus muncul di dalam Blokif (LOCAL_LOGV)
.
Catatan
-
Dalam modul tertentu, selain pada level
VERBOSE
, error sebaiknya hanya dilaporkan satu kali jika memungkinkan. Dalam satu rantai panggilan fungsi dalam modul, hanya fungsi terdalam yang harus mengembalikan kesalahan, dan pemanggil dalam modul yang sama hanya boleh menambahkan beberapa pencatatan {i>logging<i} jika hal itu secara signifikan membantu mengisolasi masalah. -
Dalam rantai modul, selain di level
VERBOSE
, saat modul level lebih rendah mendeteksi data tidak valid yang berasal dari modul tingkat rendah, seharusnya hanya mencatat situasi iniDEBUG
log, dan hanya jika pencatatan log memberikan informasi yang tidak jika tidak tersedia untuk pemanggil. Secara khusus, tidak perlu situasi log tempat pengecualian ditampilkan (pengecualian harus berisi semua informasi yang relevan), atau jika satu-satunya informasi yang dicatat terdapat dalam kode {i>error<i}. Hal ini terutama penting dalam interaksi antara kerangka kerja dan aplikasi, dan kondisi yang disebabkan oleh aplikasi pihak ketiga yang ditangani oleh kerangka kerja seharusnya tidak memicu pencatatan log lebih tinggi dari TingkatDEBUG
. Satu-satunya situasi yang seharusnya memicu logging pada LevelINFORMATIVE
atau lebih tinggi adalah saat modul atau aplikasi mendeteksi kesalahan pada tingkatnya sendiri atau berasal dari tingkat yang lebih rendah. - Ketika kondisi yang biasanya membenarkan beberapa pencatatan kemungkinan terjadi berkali-kali, menjadi ide yang baik untuk menerapkan beberapa mekanisme pembatasan kapasitas untuk mencegah kelebihan beban pada log salinan duplikat dari informasi yang sama (atau sangat mirip).
-
Kehilangan konektivitas jaringan dianggap
umum dan terjadi sepenuhnya
diharapkan, dan tidak boleh
dicatat secara serampangan. Hilangnya jaringan
konektivitas yang memiliki konsekuensi dalam aplikasi harus dicatat dalam
tingkat
DEBUG
atauVERBOSE
(bergantung pada apakah konsekuensinya cukup serius dan tidak terduga sehingga tidak dapat dicatat dalam rilis build). - Memiliki sistem file lengkap pada sistem file yang dapat diakses oleh atau di nama aplikasi pihak ketiga tidak seharusnya dicatat di tingkat lebih tinggi daripada INFORMATIF.
-
Data yang tidak valid berasal dari sumber yang tidak tepercaya (termasuk file apa pun di
penyimpanan bersama, atau data
yang masuk melalui jaringan
tambahan) dianggap sudah diperkirakan dan seharusnya tidak memicu
mencatat log pada tingkat yang lebih tinggi
dari
DEBUG
ketika terdeteksi tidak valid (dan log harus dibatasi sebatas mungkin). -
Saat digunakan pada objek
String
, operator+
secara implisit membuat instanceStringBuilder
dengan ukuran buffer (16 karakter) dan kemungkinanString
sementara lainnya objek terstruktur dalam jumlah besar. Jadi, membuat objekStringBuilder
secara eksplisit tidak lebih lebih mahal daripada mengandalkan operator+
{i>default<i} (dan bisa sangat lebih efisien). Perlu diingat bahwa kode yang memanggilLog.v()
dikompilasi dan dieksekusi pada build rilis, termasuk membangun {i>string<i}, bahkan jika log tidak dibaca. -
Setiap {i>logging<i} yang dimaksudkan untuk
dibaca oleh orang lain dan untuk
yang tersedia dalam build rilis
harus singkat tanpa samar,
dan harus dapat dipahami. Hal ini termasuk semua logging
hingga tingkat
DEBUG
. - Jika memungkinkan, tetap lakukan logging pada satu baris. Panjang baris hingga 80 atau 100 karakter adalah masih dapat diterima. Hindari panjang yang lebih dari 130 atau 160 karakter (termasuk panjang tag) jika memungkinkan.
-
Jika pencatatan log berhasil, jangan pernah menggunakannya pada tingkat yang lebih tinggi
dari
VERBOSE
. -
Jika Anda menggunakan {i>logging<i} sementara
untuk mendiagnosis masalah yang sulit
mereproduksi, mempertahankannya di level
DEBUG
atauVERBOSE
, dan tambahkan blok if yang memungkinkan penonaktifan waktu kompilasi. - Hati-hati dengan kebocoran keamanan melalui log. Menghindari logging pribadi tidak akurat atau tidak sesuai. Secara khusus, hindari pencatatan log tentang konten yang dilindungi. Hal ini sangat penting ketika menulis kode kerangka kerja karena tidak mudah untuk mengetahui terlebih dahulu apa yang akan dan tidak akan berupa informasi pribadi atau konten yang dilindungi.
-
Jangan pernah gunakan
System.out.println()
(atauprintf()
untuk kode native).System.out
danSystem.err
mendapatkan dialihkan ke/dev/null
, sehingga pernyataan cetak Anda tidak memiliki efek yang terlihat. Namun, semua bangunan {i>string<i} yang terjadi untuk panggilan ini masih dijalankan. - Aturan emas pencatatan adalah log Anda mungkin tidak mendorong log lain keluar dari buffer, sama seperti yang mungkin dan bukan deployment Anda.
Aturan gaya Javatest
Ikuti konvensi penamaan metode pengujian dan gunakan garis bawah untuk memisahkan apa yang sedang diuji dari kasus tertentu yang sedang diuji. Gaya ini membuat lebih mudah untuk melihat kasus mana yang sedang diuji. 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)) }