Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

Gaya Kode Java AOSP untuk Kontributor

Gaya kode di halaman ini adalah aturan ketat untuk mengkontribusikan kode Java ke Android Open Source Project (AOSP). Kontribusi untuk platform Android yang tidak mematuhi aturan ini umumnya tidak diterima. Kami menyadari bahwa tidak semua kode yang ada mengikuti aturan ini, tetapi kami berharap semua kode baru mematuhinya. Lihat Coding dengan Menghormati untuk contoh terminologi untuk menggunakan dan menghindari untuk ekosistem yang lebih inklusif.

Konsisten

Salah satu aturan paling sederhana adalah BE KONSISTEN. Jika Anda mengedit kode, luangkan beberapa menit untuk melihat kode di sekitarnya dan menentukan gayanya. Jika kode yang menggunakan ruang di sekitar if klausa, Anda harus juga. Jika komentar kode memiliki kotak-kotak kecil bintang di sekelilingnya, buatlah komentar Anda juga memiliki kotak-kotak kecil bintang di sekelilingnya.

Inti dari memiliki pedoman gaya adalah untuk memiliki kosakata 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 kosa kata, tetapi gaya lokal juga penting. Jika kode yang Anda tambahkan ke file terlihat sangat berbeda dari kode yang ada di sekitarnya, pembaca akan kehilangan ritme saat mereka membacanya. Cobalah untuk menghindari ini.

aturan bahasa jawa

Android mengikuti konvensi pengkodean Java standar dengan aturan tambahan yang dijelaskan di bawah ini.

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 berpikir kode Anda tidak akan pernah mengalami kondisi kesalahan ini atau bahwa tidak penting untuk menanganinya, mengabaikan jenis pengecualian ini 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 khusus bervariasi tergantung pada kasusnya.

"Kapan saja seseorang memiliki klausa menangkap kosong mereka harus memiliki perasaan menyeramkan. Ada pasti saat-saat itu sebenarnya adalah hal yang benar untuk dilakukan, tapi setidaknya Anda harus berpikir tentang hal itu. Di Jawa Anda tidak bisa lepas dari perasaan menyeramkan. "- James Gosling

Alternatif yang dapat diterima (dalam urutan preferensi) adalah:

  • Lemparkan 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.");
        }
      }
    
  • Menangani kesalahan anggun dan mengganti nilai yang sesuai dalam catch {} blok.
      /** 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
        }
      }
    
  • Menangkap pengecualian dan melemparkan contoh baru dari 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 berkomentar mengapa 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 menjadi malas ketika 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. Dalam hampir semua kasus, itu tidak pantas untuk menangkap generik Exception atau Throwable (sebaiknya tidak Throwable karena termasuk Error pengecualian). Ini berbahaya karena itu berarti bahwa pengecualian Anda tidak pernah diharapkan (termasuk pengecualian runtime seperti ClassCastException ) terjebak dalam aplikasi-tingkat kesalahan penanganan. Ini mengaburkan properti penanganan kegagalan kode Anda, artinya jika seseorang menambahkan tipe pengecualian baru dalam kode yang Anda panggil, kompiler tidak akan menunjukkan bahwa Anda perlu menangani kesalahan secara berbeda. Dalam kebanyakan kasus, Anda tidak boleh menangani berbagai jenis pengecualian dengan cara yang sama.

Pengecualian yang jarang terjadi untuk aturan ini adalah kode pengujian dan kode tingkat atas tempat Anda ingin menangkap semua jenis kesalahan (untuk mencegahnya muncul di UI, atau untuk membuat pekerjaan batch tetap berjalan). Dalam kasus ini, Anda dapat menangkap generik Exception (atau Throwable ) dan menangani kesalahan tepat. Pikirkan baik-baik sebelum melakukan ini, dan berikan komentar yang menjelaskan mengapa itu aman dalam konteks ini.

Alternatif untuk menangkap pengecualian umum:

  • Menangkap setiap pengecualian secara terpisah sebagai bagian dari blok multi-catch, misalnya:
    try {
        ...
    } catch (ClassNotFoundException | NoSuchMethodException e) {
        ...
    }
  • Memfaktorkan ulang kode Anda agar memiliki penanganan kesalahan yang lebih halus, dengan beberapa blok percobaan. Pisahkan IO dari penguraian, dan tangani kesalahan secara terpisah di setiap kasus.
  • Ulangi pengecualian. Sering kali Anda tidak perlu menangkap pengecualian pada level ini, biarkan saja metode membuangnya.

Ingatlah bahwa pengecualian adalah teman Anda! Ketika kompiler mengeluh bahwa Anda tidak menangkap pengecualian, jangan cemberut. Senyum! Kompiler hanya memudahkan Anda untuk menangkap masalah runtime dalam kode Anda.

Jangan gunakan finalizer

Finalizers adalah cara untuk mengeksekusi sepotong kode ketika suatu objek adalah sampah yang dikumpulkan. Meskipun finalizer dapat 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, mendefinisikan close() metode (atau sejenisnya) dan dokumen kapan tepatnya bahwa metode kebutuhan untuk dipanggil (lihat InputStream untuk contoh). Dalam hal ini, itu tepat tetapi tidak diharuskan untuk mencetak pesan log singkat dari finalizer, selama itu tidak diharapkan untuk membanjiri log.

Impor yang memenuhi syarat sepenuhnya

Bila Anda ingin menggunakan kelas Bar dari paket foo , ada dua cara yang mungkin 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 Java perpustakaan standar ( java.util.* , java.io.* , dll) dan kode unit test ( junit.framework.* ).

Aturan perpustakaan Java

Ada konvensi untuk menggunakan perpustakaan dan alat Java Android. Dalam beberapa kasus, konvensi telah berubah dengan cara yang penting dan kode yang lebih lama mungkin menggunakan pola atau pustaka yang tidak digunakan lagi. Saat bekerja dengan kode seperti itu, boleh saja melanjutkan gaya yang ada. Namun, saat membuat komponen baru, jangan pernah menggunakan pustaka yang 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 2022 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 umum trivial yang Anda tulis harus berisi komentar javadoc dengan setidaknya satu kalimat yang menggambarkan apa kelas atau metode tidak. 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 mendapatkan dan set metode sepele seperti setFoo() jika semua Javadoc Anda akan katakan adalah "set Foo". Jika metode melakukan sesuatu yang lebih kompleks (seperti memberlakukan 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 menegakkan gaya tertentu untuk menulis komentar javadoc, tapi Anda harus mengikuti petunjuk di Cara Menulis Doc Komentar untuk Alat Javadoc .

Tulis metode singkat

Jika memungkinkan, pertahankan metode tetap kecil dan fokus. Kami menyadari bahwa metode panjang terkadang tepat, jadi tidak ada batasan keras yang ditempatkan 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 cakupan variabel

Pertahankan cakupan variabel lokal seminimal mungkin. Ini meningkatkan keterbacaan dan pemeliharaan kode Anda dan mengurangi kemungkinan kesalahan. Deklarasikan setiap variabel di blok terdalam yang mencakup semua penggunaan variabel.

Deklarasikan variabel lokal pada titik di mana mereka pertama kali digunakan. Hampir setiap deklarasi variabel lokal harus berisi inisialisasi. Jika Anda belum memiliki informasi yang cukup untuk menginisialisasi variabel dengan bijaksana, tunda deklarasi sampai Anda melakukannya.

Pengecualiannya adalah pernyataan try-catch. Jika sebuah variabel diinisialisasi dengan nilai kembalian dari metode yang melempar pengecualian yang dicentang, itu harus diinisialisasi di dalam blok coba. Jika nilai harus digunakan di luar blok try, maka nilai tersebut harus dideklarasikan sebelum blok try, di mana nilai tersebut belum dapat diinisialisasi dengan 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 mengenkapsulasi blok try-catch dalam suatu 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());
}

Pesan impor pernyataan

Urutan pernyataan impor adalah:

  1. Impor Android
  2. Impor dari pihak ketiga ( com , junit , net , org )
  3. java dan javax

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 kelompok utama ( android , com , junit , net , org , java , javax )

Awalnya, tidak ada persyaratan gaya pada pemesanan, artinya IDE selalu mengubah pemesanan atau pengembang IDE harus menonaktifkan fitur manajemen impor otomatis dan mempertahankan impor secara manual. Ini dianggap buruk. Ketika gaya Java ditanya, gaya yang disukai sangat bervariasi dan Android hanya perlu "memilih pemesanan dan konsisten." Jadi kami memilih gaya, memperbarui panduan gaya, dan membuat IDE mematuhinya. Kami berharap bahwa saat pengguna IDE mengerjakan kode, impor di semua paket akan cocok dengan pola ini tanpa upaya rekayasa ekstra.

Kami memilih gaya ini sedemikian rupa sehingga:

  • Impor yang orang ingin melihat pada awalnya cenderung di atas ( android ).
  • Impor yang orang ingin melihat setidaknya cenderung di bagian bawah ( java ).
  • Manusia dapat dengan mudah mengikuti gaya tersebut.
  • IDE dapat mengikuti gaya.

Letakkan impor statis di atas semua impor lain yang dipesan 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 penetapan.

Direkomendasikan

Instrument i =
        someLongExpression(that, wouldNotFit, on, one, line);

Tidak direkomendasikan

Instrument i =
    someLongExpression(that, wouldNotFit, on, one, line);

Ikuti konvensi penamaan bidang

  • Non-publik, nama field non-statis mulai dengan m .
  • Nama field statis mulai dengan s .
  • Bidang lain dimulai dengan huruf kecil.
  • Bidang akhir public static (konstanta) yang 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 penyangga standar

Letakkan kurung kurawal pada baris yang sama dengan kode sebelumnya, bukan pada barisnya sendiri:

class MyClass {
    int func() {
        if (something) {
            // ...
        } else if (somethingElse) {
            // ...
        } else {
            // ...
        }
    }
}

Kami membutuhkan kurung kurawal di sekitar pernyataan untuk kondisional. Pengecualian: Jika seluruh conditional (kondisi dan badan) muat dalam satu baris, Anda boleh (tetapi 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

Setiap baris teks dalam kode Anda harus memiliki panjang maksimal 100 karakter. Sementara banyak diskusi telah dikelilingi aturan ini, keputusan tetap bahwa 100 karakter adalah maksimum 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 memudahkan pemotongan dan tempel.
  • Jalur impor dapat melampaui batas karena manusia jarang melihatnya (ini juga menyederhanakan penulisan alat).

Gunakan anotasi Java standar

Anotasi harus mendahului pengubah lain untuk elemen bahasa yang sama. Penjelasan penanda sederhana (misalnya, @Override ) dapat terdaftar pada baris yang sama dengan elemen bahasa. Jika ada beberapa anotasi, atau anotasi berparameter, buat daftarnya satu per baris dalam urutan abjad.

Praktik standar Android untuk tiga anotasi standar di Java adalah:

  • Gunakan @Deprecated penjelasan setiap kali penggunaan elemen dijelaskan tidak disarankan. Jika Anda menggunakan @Deprecated penjelasan, Anda juga harus memiliki @deprecated tag Javadoc dan harus nama sebuah implementasi alternatif. Selain itu, ingat bahwa @Deprecated metode masih seharusnya bekerja. Jika Anda melihat kode lama yang memiliki @deprecated tag Javadoc, tambahkan @Deprecated penjelasan.
  • Gunakan @Override penjelasan setiap kali metode menimpa deklarasi atau pelaksanaan dari superclass. Misalnya, jika Anda menggunakan @inheritdocs tag Javadoc, dan berasal dari kelas (bukan sebuah antarmuka), Anda harus juga keterangan bahwa metode menimpa metode kelas orangtua.
  • Gunakan @SuppressWarnings penjelasan hanya dalam keadaan di mana tidak mungkin untuk menghilangkan peringatan. Jika peringatan melewati ini "tidak mungkin untuk menghilangkan" tes, yang @SuppressWarnings penjelasan harus digunakan, untuk memastikan bahwa semua peringatan mencerminkan masalah yang sebenarnya dalam kode.

    Ketika @SuppressWarnings penjelasan diperlukan, harus diawali dengan TODO komentar yang menjelaskan "tidak mungkin untuk menghilangkan" kondisi. 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);
    

    Ketika @SuppressWarnings penjelasan diperlukan, refactor kode untuk mengisolasi elemen perangkat lunak di mana anotasi berlaku.

Perlakukan akronim sebagai kata-kata

Perlakukan akronim dan singkatan sebagai kata dalam penamaan variabel, metode, dan kelas untuk membuat nama lebih mudah dibaca:

Bagus Buruk
Permintaan XmlHttp Permintaan XMLHTTP
dapatkanIdPelanggan dapatkanIDPelanggan
kelas HTML kelas HTML
Url string URL string
id panjang ID panjang

Karena basis kode JDK dan Android tidak konsisten di sekitar akronim, hampir tidak mungkin untuk konsisten dengan kode di sekitarnya. Oleh karena itu, selalu perlakukan akronim sebagai kata-kata.

Gunakan komentar TODO

Gunakan TODO komentar untuk kode yang bersifat sementara, solusi jangka pendek, atau cukup baik tetapi tidak sempurna. Komentar-komentar ini harus mencakup string TODO di semua topi, diikuti oleh 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 Anda TODO adalah dari bentuk "Pada masa mendatang melakukan sesuatu" pastikan bahwa Anda baik termasuk tanggal tertentu ( "Fix pada bulan November 2005") atau peristiwa tertentu ( "Hapus kode ini setelah semua mixer produksi memahami protokol V7." ).

Log hemat

Meskipun logging diperlukan, ini berdampak negatif pada kinerja dan kehilangan kegunaannya jika tidak disimpan dengan cukup singkat. Fasilitas logging menyediakan lima tingkat logging yang berbeda:

  • ERROR : Gunakan ketika sesuatu yang fatal telah terjadi, yaitu, sesuatu yang akan memiliki konsekuensi dilihat pengguna dan tidak akan dapat dipulihkan tanpa menghapus beberapa data, menghapus aplikasi, menghapus partisi data, atau reflashing seluruh perangkat (atau lebih buruk). Level ini selalu dicatat. Isu-isu yang membenarkan beberapa penebangan di ERROR tingkat adalah kandidat yang baik untuk dilaporkan ke server statistik pengumpulan.
  • WARNING : Gunakan ketika sesuatu yang serius dan tak terduga terjadi, yaitu, sesuatu yang akan memiliki konsekuensi dilihat pengguna tetapi kemungkinan untuk dapat dipulihkan tanpa kehilangan data dengan melakukan beberapa tindakan yang eksplisit, mulai dari menunggu atau restart aplikasi semua cara untuk re-download versi baru aplikasi atau me-reboot perangkat. Level ini selalu dicatat. Isu-isu yang membenarkan logging di WARNING tingkat mungkin juga dipertimbangkan untuk melaporkan ke server statistik pengumpulan.
  • INFORMATIVE : Gunakan untuk dicatat bahwa sesuatu yang menarik terjadi, yaitu ketika situasi terdeteksi yang cenderung memiliki dampak luas, meskipun belum tentu kesalahan. Kondisi seperti itu hanya boleh dicatat oleh modul yang percaya bahwa itu adalah yang paling otoritatif di domain itu (untuk menghindari duplikasi logging oleh komponen non-otoritatif). Level ini selalu dicatat.
  • DEBUG : Gunakan untuk catatan lebih lanjut apa yang terjadi pada perangkat yang bisa relevan untuk menyelidiki dan debug perilaku tak terduga. 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 verbose logging.

    Tingkat ini login bahkan di rilis membangun, dan diperlukan untuk dikelilingi oleh if (LOCAL_LOG) atau if LOCAL_LOGD) blok, di mana LOCAL_LOG[D] didefinisikan di kelas Anda atau subkomponen, sehingga ada kemungkinan untuk menonaktifkan semua penebangan tersebut . Oleh karena itu, tidak boleh ada logika aktif dalam if (LOCAL_LOG) blok. Semua bangunan string untuk log juga perlu ditempatkan di dalam if (LOCAL_LOG) blok. Jangan refactor panggilan logging keluar menjadi panggilan metode jika itu akan menyebabkan string membangun untuk mengambil tempat di luar if (LOCAL_LOG) blok.

    Ada beberapa kode yang masih mengatakan if (localLOGV) . Ini dianggap dapat diterima juga, meskipun namanya tidak standar.

  • VERBOSE : Gunakan untuk segala sesuatu yang lain. Tingkat ini hanya login debug membangun dan harus dikelilingi oleh if (LOCAL_LOGV) blok (atau setara) sehingga dapat dikompilasi oleh default. Setiap bangunan string dilucuti dari rilis membangun dan kebutuhan untuk tampil dalam if (LOCAL_LOGV) blok.

Catatan

  • Dalam modul yang diberikan, selain di VERBOSE tingkat, kesalahan hanya harus dilaporkan sekali jika memungkinkan. Dalam satu rantai panggilan fungsi dalam sebuah modul, hanya fungsi terdalam yang akan mengembalikan kesalahan, dan pemanggil dalam modul yang sama hanya boleh menambahkan beberapa logging jika itu secara signifikan membantu mengisolasi masalah.
  • Dalam rantai modul, selain di VERBOSE tingkat, ketika modul-tingkat yang lebih rendah mendeteksi data yang tidak valid yang berasal dari modul-tingkat yang lebih tinggi, modul-tingkat yang lebih rendah seharusnya hanya log situasi ini dengan DEBUG log, dan hanya jika penebangan menyediakan informasi yang tidak tersedia bagi pemanggil. Secara khusus, tidak perlu mencatat situasi di mana pengecualian dilemparkan (pengecualian harus berisi semua informasi yang relevan), atau di mana satu-satunya informasi yang dicatat terkandung dalam kode kesalahan. Hal ini terutama penting dalam interaksi antara kerangka dan aplikasi, dan kondisi yang disebabkan oleh aplikasi pihak ketiga yang ditangani oleh kerangka kerja tidak harus memicu penebangan lebih tinggi dari DEBUG tingkat. Satu-satunya situasi yang harus memicu penebangan di INFORMATIVE tingkat atau lebih tinggi adalah ketika modul atau aplikasi mendeteksi kesalahan pada tingkat sendiri atau berasal dari tingkat yang lebih rendah.
  • Ketika kondisi yang biasanya membenarkan beberapa logging kemungkinan terjadi berkali-kali, itu bisa menjadi ide yang baik untuk menerapkan beberapa mekanisme pembatasan tingkat untuk mencegah meluapnya log dengan banyak salinan duplikat dari informasi yang sama (atau sangat mirip).
  • Hilangnya konektivitas jaringan dianggap umum dan diharapkan sepenuhnya, dan tidak boleh dicatat secara serampangan. Sebuah kehilangan konektivitas jaringan yang memiliki konsekuensi dalam aplikasi harus login di DEBUG atau VERBOSE tingkat (tergantung pada apakah konsekuensi yang cukup serius dan cukup tak terduga untuk login dalam rilis membangun).
  • Memiliki sistem file lengkap pada sistem file yang dapat diakses atau atas nama aplikasi pihak ketiga tidak boleh dicatat pada tingkat yang lebih tinggi dari INFORMATIVE.
  • Data yang tidak valid yang berasal dari sumber yang tidak dipercaya (termasuk file pada penyimpanan bersama, atau data yang datang melalui koneksi jaringan) dianggap diharapkan dan tidak harus memicu penebangan setiap pada tingkat yang lebih tinggi dari DEBUG ketika itu terdeteksi tidak valid (dan bahkan kemudian penebangan harus seminimal mungkin).
  • Ketika digunakan pada String objek, + Operator implisit menciptakan StringBuilder misalnya dengan ukuran buffer default (16 karakter) dan sementara berpotensi lainnya String objek. Jadi secara eksplisit menciptakan StringBuilder objek tidak lebih mahal daripada mengandalkan default + operator (dan dapat menjadi jauh lebih efisien). Perlu diingat bahwa kode yang memanggil Log.v() dikompilasi dan dijalankan pada rilis membangun, termasuk membangun string, bahkan jika log tidak menjadi membaca.
  • Setiap logging yang dimaksudkan untuk dibaca oleh orang lain dan tersedia dalam rilis build harus singkat tanpa samar, dan harus dapat dimengerti. Ini mencakup semua penebangan hingga DEBUG tingkat.
  • Jika memungkinkan, tetap masuk dalam satu baris. Panjang baris hingga 80 atau 100 karakter dapat diterima. Hindari panjang yang lebih panjang dari sekitar 130 atau 160 karakter (termasuk panjang tag) jika memungkinkan.
  • Jika penebangan laporan keberhasilan, tidak pernah menggunakannya pada tingkat yang lebih tinggi dari VERBOSE .
  • Jika Anda menggunakan logging sementara untuk mendiagnosis masalah yang sulit untuk mereproduksi, tetap di DEBUG atau VERBOSE tingkat dan melampirkan dengan jika blok yang memungkinkan untuk menonaktifkan itu pada waktu kompilasi.
  • Hati-hati dengan kebocoran keamanan melalui log. Hindari mencatat informasi pribadi. Secara khusus, hindari mencatat informasi tentang konten yang dilindungi. Ini sangat penting ketika menulis kode kerangka kerja karena tidak mudah untuk mengetahui sebelumnya apa yang akan dan tidak akan menjadi informasi pribadi atau konten yang dilindungi.
  • Tidak pernah menggunakan System.out.println() (atau printf() untuk kode asli). System.out dan System.err mendapatkan diarahkan ke /dev/null , sehingga laporan cetak Anda tidak memiliki efek yang terlihat. Namun, semua pembuatan string yang terjadi untuk panggilan ini masih akan dieksekusi.
  • Aturan utama logging adalah bahwa log Anda mungkin tidak perlu mendorong log lain keluar dari buffer, sama seperti yang 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))
}