Google is committed to advancing racial equity for Black communities. See how.
Bu sayfa, Cloud Translation API ile çevrilmiştir.
Switch to English

Katkıda Bulunanlar için AOSP Java Kod Stili

Bu sayfadaki kod stilleri, Java kodunun Android Açık Kaynak Projesi'ne (AOSP) katkıda bulunmak için katı kurallardır. Bu kurallara uymayan Android platformuna yapılan katkılar genellikle kabul edilmez . Mevcut tüm kodların bu kurallara uymadığını biliyoruz, ancak tüm yeni kodların uyumlu olmasını bekliyoruz.

Tutarlı olun

En basit kurallardan biri TUTARLI OLMAK. Kodu düzenliyorsanız, çevreleyen koda bakmak ve stilini belirlemek için birkaç dakikanızı ayırın. Bu kod if cümlelerinin etrafında boşluklar kullanıyorsa, siz de yapmalısınız. Kod yorumlarının etrafında küçük yıldız kutuları varsa, yorumlarınızın da çevresinde küçük yıldız kutuları olmasını sağlayın.

Stil kurallarına sahip olmanın amacı, ortak bir kodlama kelime dağarcığına sahip olmaktır, böylece okuyucular, nasıl söylediğinize değil, söylediklerinize konsantre olabilirler. Kelime bilgisini bilmeniz için küresel stil kurallarını burada sunuyoruz, ancak yerel stil de önemlidir. Bir dosyaya eklediğiniz kod, çevresindeki mevcut koddan büyük ölçüde farklı görünüyorsa, okuyucuları okuduklarında ritmin dışına çıkarır. Bundan kaçınmaya çalışın.

Java dil kuralları

Android, aşağıda açıklanan ek kurallarla birlikte standart Java kodlama kurallarını izler.

İstisnaları görmezden gelmeyin

Aşağıdakiler gibi bir istisnayı yok sayan bir kod yazmak cazip gelebilir:

  void setServerPort(String value) {
      try {
          serverPort = Integer.parseInt(value);
      } catch (NumberFormatException e) { }
  }

Bunu yapma. Kodunuzun bu hata koşuluyla asla karşılaşmayacağını veya bununla başa çıkmanın önemli olmadığını düşünseniz de, bu tür bir istisnayı göz ardı etmek, kodunuzda başka birinin bir gün tetiklemesi için mayınlar oluşturur. Kodunuzdaki her istisnayı ilkeli bir şekilde ele almalısınız; özel kullanım duruma göre değişir.

"Ne zaman biri boş bir yakalama cümlesine sahip olursa, tüyler ürpertici bir duyguya kapılır. Yapılması gereken doğru şeyin kesinlikle olduğu zamanlar vardır, ama en azından bunu düşünmeniz gerekir. Java'da ürpertici duygudan kaçamazsınız. "- James Gosling

Kabul edilebilir alternatifler (tercih sırasına göre):

  • İstisnayı, yönteminizi arayana kadar atın.
      void setServerPort(String value) throws NumberFormatException {
          serverPort = Integer.parseInt(value);
      }
    
  • Soyutlama seviyenize uygun yeni bir istisna oluşturun.
      void setServerPort(String value) throws ConfigurationException {
        try {
            serverPort = Integer.parseInt(value);
        } catch (NumberFormatException e) {
            throw new ConfigurationException("Port " + value + " is not valid.");
        }
      }
    
  • Hatayı incelikle işleyin ve catch {} bloğundaki uygun bir değeri değiştirin.
      /** 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
        }
      }
    
  • Özel durumu yakalayın ve yeni bir RuntimeException örneği oluşturun. Bu tehlikelidir, bu yüzden sadece bu hata meydana gelirse yapılacak uygun şeyin çökme olduğundan eminseniz yapın.
      /** 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);
        }
      }
    
  • Son çare olarak, istisnayı görmezden gelmenin uygun olduğundan eminseniz, bunu görmezden gelebilirsiniz, ancak aynı zamanda nedenini iyi bir sebeple yorumlamalısınız.
    /** 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.
        }
    }
    

Genel istisnaları yakalamayın

İstisnaları yakalayıp buna benzer bir şey yaparken tembellik yapmak cazip gelebilir:

  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!
  }

Bunu yapma. Hemen hemen tüm durumlarda, genel Exception veya Throwable ( Error istisnaları içerdiğinden tercihen Throwable değil) yakalamak uygun değildir. Tehlikelidir çünkü asla beklemediğiniz istisnaların ( ClassCastException gibi çalışma zamanı istisnaları dahil) uygulama düzeyinde hata işlemeye ClassCastException anlamına gelir. Kodunuzun hata işleme özelliklerini gizler, yani birisi aradığınız koda yeni bir istisna türü eklerse, derleyici hatayı farklı şekilde ele almanız gerektiğine işaret etmez. Çoğu durumda, farklı istisna türlerini aynı şekilde ele almamalısınız.

Bu kuralın nadir istisnası, her türlü hatayı yakalamak istediğiniz test kodu ve üst düzey koddur (bunların bir kullanıcı arayüzünde görünmesini engellemek veya bir toplu işi çalışır durumda tutmak için). Bu durumlarda, genel Exception (veya Throwable ) yakalayabilir ve hatayı uygun şekilde ele alabilirsiniz. Yine de bunu yapmadan önce dikkatlice düşünün ve bu bağlamda neden güvenli olduğunu açıklayan yorumlar ekleyin.

Genel istisnaları yakalamaya alternatifler:

  • Çoklu yakalama bloğunun parçası olarak her istisnayı ayrı ayrı yakalayın, örneğin:
    try {
        ...
    } catch (ClassNotFoundException | NoSuchMethodException e) {
        ...
    }
  • Birden çok deneme bloğu ile daha ayrıntılı hata işleme için kodunuzu yeniden düzenleyin. GÇ'yi ayrıştırmadan ayırın ve her durumda hataları ayrı ayrı ele alın.
  • İstisnayı yeniden atın. Çoğu zaman, bu seviyede istisnayı yakalamanıza gerek yoktur, sadece yöntemin atmasına izin verin.

İstisnaların arkadaşınız olduğunu unutmayın! Derleyici bir istisna yakalamadığınızdan şikayet ettiğinde kaşlarını çatmayın. Gülümsemek! Derleyici, kodunuzdaki çalışma zamanı sorunlarını yakalamanızı kolaylaştırdı.

Sonlandırıcıları kullanmayın

Sonlandırıcılar, bir nesne çöp toplandığında bir kod parçasının yürütülmesini sağlamanın bir yoludur. Sonlandırıcılar temizlik için kullanışlı olabilirken (özellikle dış kaynaklar için), bir sonlandırıcının ne zaman çağrılacağına (veya hatta çağrılacağına) dair hiçbir garanti yoktur.

Android, sonlandırıcı kullanmaz. Çoğu durumda, bunun yerine iyi bir istisna işlemeyi kullanabilirsiniz. Kesinlikle bir sonlandırıcıya ihtiyacınız varsa, bir close() yöntemi (veya benzerini) tanımlayın ve tam olarak bu yöntemin ne zaman çağrılması gerektiğini belgeleyin (bir örnek için InputStream'e bakın). Bu durumda, günlükleri doldurması beklenmediği sürece, sonlandırıcıdan kısa bir günlük mesajı yazdırmak uygundur, ancak gerekli değildir.

İçe aktarımları tam olarak uygun hale getirin

foo paketinden sınıf Bar kullanmak istediğinizde, onu içe aktarmanın iki olası yolu vardır:

  • import foo.*;

    İthalat bildirimlerinin sayısını potansiyel olarak azaltır.

  • import foo.Bar;

    Hangi sınıfların kullanıldığını ve kodun bakımcılar için daha okunaklı olduğunu açıkça gösterir.

import foo.Bar; kullanın import foo.Bar; tüm Android kodunu içe aktarmak için. Java standart kitaplıkları ( java.util.* , java.io.* , vb.) Ve birim test kodu ( junit.framework.* ) İçin açık bir istisna yapılmıştır.

Java kitaplık kuralları

Android'in Java kitaplıklarını ve araçlarını kullanmak için kurallar vardır. Bazı durumlarda, kural önemli şekillerde değişmiştir ve eski kod, kullanımdan kaldırılmış bir kalıp veya kitaplık kullanabilir. Böyle bir kodla çalışırken, mevcut stile devam etmek sorun değil. Ancak yeni bileşenler oluştururken asla kullanımdan kaldırılmış kitaplıkları kullanmayın.

Java stil kuralları

Javadoc standart yorumlarını kullanın

Her dosyanın üstte bir telif hakkı beyanı, ardından paket ve içe aktarma ifadeleri (her blok boş bir satırla ayrılmış) ve son olarak sınıf veya arayüz bildirimi olmalıdır. Javadoc yorumlarında, sınıfın veya arayüzün ne yaptığını açıklayın.

/*
 * Copyright 2020 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 {
    ...
}

Her sınıf ve en az bir cümle sınıf veya yöntem ne yaptığını açıklayan bir Javadoc yorumunu içermelidir yazmanızı nontrivial kamu yöntemi. Bu cümle üçüncü şahıs tanımlayıcı bir fiil ile başlamalıdır.

Örnekler

/** Returns the correctly rounded positive square root of a double value. */

static double sqrt(double a) {
    ...
}

veya

/**
 * Constructs a new String by converting the specified array of
 * bytes using the platform's default character encoding.
 */
public String(byte[] bytes) {
    ...
}

setFoo() "sets Foo" ise, önemsiz get ve setFoo() gibi yöntemler için Javadoc yazmanıza gerek yoktur. Yöntem daha karmaşık bir şey yaparsa (bir kısıtlama uygulamak gibi veya önemli bir yan etkiye sahipse), o zaman onu belgelemelisiniz. "Foo" özelliğinin ne anlama geldiği açık değilse, bunu belgelemelisiniz.

Herkese açık veya başka bir şekilde yazdığınız her yöntem Javadoc'tan yararlanacaktır. Genel yöntemler bir API'nin parçasıdır ve bu nedenle Javadoc gerektirir. Android, Javadoc yorumları yazmak için belirli bir stil uygulamaz, ancak Javadoc Aracı için Belge Yorumları Nasıl Yazılır bölümündeki talimatları izlemelisiniz.

Kısa yöntemler yazın

Mümkün olduğunda, yöntemleri küçük ve odaklanmış tutun. Uzun yöntemlerin bazen uygun olduğunu biliyoruz, bu nedenle yöntem uzunluğuna kesin bir sınır getirilmemiştir. Bir yöntem 40 veya daha fazla satırı aşarsa, programın yapısına zarar vermeden parçalanıp bölünemeyeceğini düşünün.

Standart yerlerde alanları tanımlayın

Alanları dosyanın en üstünde veya onları kullanan yöntemlerden hemen önce tanımlayın.

Değişken kapsamını sınırla

Yerel değişkenlerin kapsamını minimumda tutun. Bu, kodunuzun okunabilirliğini ve sürdürülebilirliğini artırır ve hata olasılığını azaltır. Değişkenin tüm kullanımlarını kapsayan en içteki bloktaki her bir değişkeni bildirin.

Yerel değişkenleri ilk kullanıldıkları noktada bildirin. Neredeyse her yerel değişken bildirimi bir başlatıcı içermelidir. Henüz bir değişkeni makul bir şekilde başlatmak için yeterli bilgiye sahip değilseniz, beyanı yapana kadar erteleyin.

Bunun istisnası, dene-yakala ifadeleridir. Bir değişken, kontrol edilen bir istisna atan bir yöntemin dönüş değeriyle başlatılırsa, bir try bloğu içinde başlatılmalıdır. Değer, try bloğunun dışında kullanılması gerekiyorsa, henüz mantıklı bir şekilde başlatılamadığı try bloğundan önce bildirilmelidir:

// 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));

Bununla birlikte, try-catch bloğunu bir yöntemde kapsülleyerek bu durumu önleyebilirsiniz:

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));

Aksini yapmak için zorlayıcı bir neden olmadıkça, for ifadesinin kendisinde döngü değişkenlerini bildirin:

for (int i = 0; i < n; i++) {
    doSomething(i);
}

ve

for (Iterator i = c.iterator(); i.hasNext(); ) {
    doSomethingElse(i.next());
}

İthalat ekstrelerini sipariş et

İthalat beyannamelerinin sıralaması şu şekildedir:

  1. Android içe aktarmalar
  2. Üçüncü şahıslardan ithalat ( com , junit , net , org )
  3. java ve javax

IDE ayarlarıyla tam olarak eşleşmek için içe aktarmalar şu şekilde olmalıdır:

  • Her grupta alfabetik olarak, küçük harflerden önce büyük harfler (örneğin, a'dan önce Z)
  • Her ana gruplama arasında boş bir satırla ayrılmış ( android , com , junit , net , org , java , javax )

Başlangıçta, siparişte herhangi bir stil gerekliliği yoktu, yani IDE'ler ya her zaman sıralamayı değiştiriyorlardı ya da IDE geliştiricilerinin otomatik içe aktarma yönetimi özelliklerini devre dışı bırakması ve içe aktarmaları manuel olarak sürdürmesi gerekiyordu. Bu kötü kabul edildi. Java tarzı sorulduğunda, tercih edilen stiller çılgınca çeşitlilik gösterdi ve Android'in sadece "bir sipariş seçip tutarlı olması" gerektiğine indi. Bu yüzden bir stil seçtik, stil kılavuzunu güncelledik ve IDE'lerin buna uymasını sağladık. IDE kullanıcıları kod üzerinde çalışırken, tüm paketlerdeki ithalatların ekstra mühendislik çabası olmadan bu modele uymasını bekliyoruz.

Bu stili şu şekilde seçtik:

  • İnsanların ilk bakmak istediği içe android en üstte ( android ) olma eğilimindedir.
  • İnsanların en azından bakmak istediği ithalatlar en altta ( java ) olma eğilimindedir.
  • İnsanlar tarzı rahatlıkla takip edebilir.
  • IDE'ler stili takip edebilir.

Statik ithalatı diğer tüm ithalatların üzerine koyun, normal ithalatlarla aynı şekilde sipariş verin.

Girinti için boşluk kullanın

Bloklar için dört (4) boşluk girintisi kullanıyoruz ve hiçbir zaman sekme kullanmıyoruz. Şüpheniz olduğunda, çevreleyen kodla tutarlı olun.

İşlev çağrıları ve atamalar dahil satır kaydırmaları için sekiz (8) boşluk girintisi kullanıyoruz.

Önerilen

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

Tavsiye edilmez

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

Alan adlandırma kurallarına uyun

  • Genel olmayan, statik olmayan alan adları m ile başlar.
  • Statik alan adları s ile başlar.
  • Diğer alanlar küçük harfle başlar.
  • Genel statik son alanlar (sabitler) ALL_CAPS_WITH_UNDERSCORES .

Örneğin:

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;
}

Standart küme ayracı stilini kullanın

Kaşlı ayraçları kendi satırlarına değil, önlerindeki kodla aynı satıra koyun:

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

Bir koşul için ifadelerin etrafında parantez kullanılması gerekir. İstisna: Tüm koşul (durum ve vücut) tek bir satıra uyuyorsa, hepsini tek bir satıra koyabilirsiniz (ancak mecbur değilsiniz). Örneğin, bu kabul edilebilir:

if (condition) {
    body();
}

ve bu kabul edilebilir:

if (condition) body();

ancak bu kabul edilemez:

if (condition)
    body();  // bad!

Satır uzunluğunu sınırla

Kodunuzdaki her metin satırı en fazla 100 karakter uzunluğunda olmalıdır. Bu kuralı pek çok tartışma çevrelemiş olsa da, aşağıdaki istisnalar dışında en fazla 100 karakter olduğuna dair karar kalır:

  • Bir yorum satırı örnek bir komut veya 100 karakterden uzun bir değişmez URL içeriyorsa, bu satır kesme ve yapıştırma kolaylığı için 100 karakterden uzun olabilir.
  • İnsanlar nadiren gördükleri için içe aktarma satırları sınırı aşabilir (bu aynı zamanda araç yazmayı da basitleştirir).

Standart Java notlarını kullanın

Ek açıklamalar, aynı dil öğesi için diğer değiştiricilerden önce gelmelidir. Basit işaretçi açıklamaları (örneğin, @Override ) dil öğesiyle aynı satırda listelenebilir. Birden çok ek açıklama veya parametreli açıklama varsa, bunları alfabetik sırayla satır başına bir liste halinde listeleyin.

Java'da önceden tanımlanmış üç ek açıklama için Android standart uygulamaları şunlardır:

  • Ek açıklamalı öğenin kullanılması önerilmediğinde @Deprecated açıklamasını kullanın. @Deprecated açıklamasını kullanırsanız, bir @deprecated Javadoc etiketine de sahip olmalısınız ve alternatif bir uygulamayı adlandırmalıdır. Ek olarak, @Deprecated yöntemin hala çalışması gerektiğini unutmayın. @deprecated Javadoc etiketine sahip eski bir kod görürseniz, @Deprecated ek açıklamasını ekleyin.
  • Bir yöntem, bir üst @Override bildirimi veya uygulamayı geçersiz kıldığında @Override açıklamasını kullanın. Örneğin, @inheritdocs Javadoc etiketini kullanırsanız ve bir sınıftan (bir arabirim değil) @inheritdocs , yöntemin üst sınıfın yöntemini geçersiz kıldığını da açıklamanız gerekir.
  • @SuppressWarnings ek açıklamasını yalnızca bir uyarıyı ortadan kaldırmanın imkansız olduğu durumlarda kullanın. Bir uyarı bu "imkansız ortadan kaldırmak için" testini geçerse, @SuppressWarnings açıklama bütün uyarılar kodunda gerçek sorunları yansıtmasını sağlamak için, kullanılmalıdır.

    @SuppressWarnings ek açıklaması gerekli olduğunda, "ortadan kaldırılması imkansız" koşulunu açıklayan bir TODO açıklamasıyla önek olarak eklenmelidir. Bu normalde garip bir arayüze sahip bir rahatsız edici sınıfı tanımlar. Örneğin:

    // TODO: The third-party class com.third.useful.Utility.rotate() needs generics
    @SuppressWarnings("generic-cast")
    List<String> blix = Utility.rotate(blax);
    

    @SuppressWarnings ek açıklaması gerektiğinde, açıklamanın geçerli olduğu yazılım öğelerini izole etmek için kodu yeniden düzenleyin.

Kısaltmaları kelime olarak ele alın

Adları daha okunaklı hale getirmek için değişkenleri, yöntemleri ve sınıfları adlandırırken kısaltmaları ve kısaltmaları sözcükler olarak ele alın:

İyi Kötü
XmlHttpRequest XMLHTTPRequest
getCustomerId getCustomerID
sınıf Html sınıf HTML
Dize url'si Dize URL'si
uzun kimlik uzun kimlik

Kısaltmalar konusunda hem JDK hem de Android kod tabanları tutarsız olduğundan, çevreleyen kodla tutarlı olmak neredeyse imkansızdır. Bu nedenle, kısaltmaları her zaman kelime olarak değerlendirin.

YAPILACAK açıklamaları kullanın

Geçici, kısa vadeli çözüm veya yeterince iyi ancak mükemmel olmayan kodlar için TODO açıklamaları kullanın. Bu açıklamalar, tüm büyük harflerle TODO dizesini ve ardından iki nokta üst üste TODO içermelidir:

// TODO: Remove this code after the UrlTable2 has been checked in.

ve

// TODO: Change this to use a flag instead of a constant.

TODO "Gelecekte bir şeyler yapın" biçimindeyse, belirli bir tarih ("Kasım 2005'e kadar düzeltme") veya belirli bir olay ("Tüm üretim karıştırıcıları protokol V7'yi anladıktan sonra bu kodu kaldırın") eklediğinizden emin olun. ).

Tutarlı bir şekilde oturum açın

Günlüğe kaydetme gerekli olsa da, performans üzerinde olumsuz bir etkiye sahiptir ve makul bir şekilde kısa tutulmazsa kullanışlılığını kaybeder. Günlük kaydı tesisleri beş farklı düzeyde günlük kaydı sağlar:

  • ERROR : ERROR şey olduğunda kullanın, yani bir şeyin kullanıcı tarafından görülebilen sonuçları olacaktır ve bazı verileri silmeden, uygulamaları kaldırmadan, veri bölümlerini silmeden veya tüm cihazı yeniden başlatmadan (veya daha kötüsü) kurtarılamayacaktır. Bu seviye her zaman kaydedilir. ERROR düzeyinde bir miktar günlük kaydını haklı çıkaran sorunlar, bir istatistik toplama sunucusuna rapor edilmek için iyi adaylardır.
  • WARNING : Ciddi ve beklenmedik bir şey olduğunda, yani kullanıcı tarafından görülebilecek sonuçları olan ancak bir uygulamayı beklemekten veya yeniden başlatmadan yeniden indirmeye kadar bazı açık eylemler gerçekleştirerek veri kaybı olmadan kurtarılabilecek bir şey olduğunda kullanın. bir uygulamanın yeni bir sürümü veya cihazı yeniden başlatma. Bu seviye her zaman kaydedilir. WARNING düzeyinde günlüğe kaydetmeyi haklı çıkaran sorunlar, bir istatistik toplama sunucusuna raporlama için de düşünülebilir.
  • INFORMATIVE : İlginç bir şeyin gerçekleştiğini, yani yaygın bir etkiye sahip olması muhtemel, ancak bir hata olması gerekmeyen bir durum tespit edildiğinde not etmek için kullanın. Bu tür bir koşul, yalnızca bu etki alanındaki en yetkili olduğuna inanan bir modül tarafından günlüğe kaydedilmelidir (yetkili olmayan bileşenlerin yinelenen günlük kaydını önlemek için). Bu seviye her zaman kaydedilir.
  • DEBUG : Beklenmedik davranışları araştırmak ve hatalarını ayıklamak için ilgili olabilecek cihazda neler olduğunu daha fazla not etmek için kullanın. Yalnızca bileşeninizle ilgili yeterli bilgi toplamak için gerekenleri kaydedin. Hata ayıklama günlükleriniz günlüğe hakimse, ayrıntılı günlüğü kullanmalısınız.

    Bu seviye, sürüm yapılarında bile günlüğe kaydedilir ve bir if (LOCAL_LOG) veya if LOCAL_LOGD) bloğu ile LOCAL_LOG[D] ; burada LOCAL_LOG[D] , sınıfınızda veya alt bileşeninizde tanımlanır, böylece tüm bu tür günlükleri devre dışı bırakma olasılığı vardır . Bu nedenle, bir if (LOCAL_LOG) bloğunda aktif mantık if (LOCAL_LOG) . Günlük için tüm dize oluşturmanın da if (LOCAL_LOG) bloğunun içine yerleştirilmesi gerekir. Dize oluşturmanın if (LOCAL_LOG) bloğunun dışında gerçekleşmesine neden olacaksa, günlük çağrısını bir yöntem çağrısında yeniden düzenlemeyin.

    Hala if (localLOGV) yazan bir kod var. Adı standart olmasa da, bu da kabul edilebilir olarak kabul edilir.

  • VERBOSE : Diğer her şey için kullanın. Bu seviye yalnızca hata ayıklama yapılarında günlüğe kaydedilir ve varsayılan olarak derlenebilmesi için bir if (LOCAL_LOGV) bloğu (veya eşdeğeri) ile çevrelenmelidir. Herhangi bir dizge oluşturma, sürüm yapılarından çıkarılır ve if (LOCAL_LOGV) bloğunun içinde görünmesi gerekir.

Notlar

  • VERBOSE düzeyi dışında belirli bir modül içinde, bir hata mümkünse yalnızca bir kez rapor edilmelidir. Bir modül içindeki tek bir işlev çağrıları zinciri içinde, yalnızca en içteki işlev hatayı döndürmelidir ve aynı modüldeki arayanlar, yalnızca sorunu izole etmeye önemli ölçüde yardımcı oluyorsa bazı günlükler eklemelidir.
  • VERBOSE seviyesi dışındaki bir modül zincirinde, daha düşük seviyeli bir modül, daha yüksek seviyeli bir modülden gelen geçersiz verileri tespit ettiğinde, daha düşük seviyeli modül, bu durumu yalnızca DEBUG günlüğüne kaydetmelidir ve yalnızca günlük kaydı sağlarsa Arayan için başka türlü mevcut olmayan bilgiler. Spesifik olarak, bir istisnanın atıldığı (istisna ilgili tüm bilgileri içermelidir) veya günlüğe kaydedilen tek bilginin bir hata kodunda bulunduğu durumları günlüğe kaydetmeye gerek yoktur. Bu, özellikle çerçeve ile uygulamalar arasındaki etkileşimde önemlidir ve çerçeve tarafından uygun şekilde işlenen üçüncü taraf uygulamaların neden olduğu koşullar, DEBUG düzeyinden daha yüksek günlük kaydını tetiklememelidir. INFORMATIVE düzeyinde veya daha yüksek düzeyde günlük kaydını tetiklemesi gereken tek durum, bir modül veya uygulamanın kendi düzeyinde veya daha düşük bir düzeyden gelen bir hata algılamasıdır.
  • Normalde bazı günlüğe kaydetmeyi haklı çıkaran bir koşulun birçok kez ortaya çıkması muhtemel olduğunda, aynı (veya çok benzer) bilginin birçok yinelenen kopyasıyla günlüklerin taşmasını önlemek için bazı hız sınırlama mekanizmaları uygulamak iyi bir fikir olabilir.
  • Ağ bağlantısı kayıpları yaygın olarak kabul edilir ve tamamen beklenir ve karşılıksız olarak kaydedilmemelidir. Bir uygulama içinde sonuçları olan bir ağ bağlantısı kaybı, DEBUG veya VERBOSE düzeyinde günlüğe kaydedilmelidir (sonuçların bir sürüm yapısında günlüğe kaydedilecek kadar ciddi ve beklenmedik olmasına bağlı olarak).
  • Üçüncü taraf uygulamalar tarafından veya onlar adına erişilebilen bir dosya sisteminde tam bir dosya sistemine sahip olmak, BİLGİLENDİRİCİ'den daha yüksek bir düzeyde günlüğe kaydedilmemelidir.
  • Güvenilmeyen herhangi bir kaynaktan gelen geçersiz veriler (paylaşılan depolama alanındaki herhangi bir dosya veya bir ağ bağlantısı yoluyla gelen veriler dahil) beklenen kabul edilir ve geçersiz olduğu tespit edildiğinde (ve daha sonra bile günlüğe kaydetme) DEBUG daha yüksek bir düzeyde herhangi bir günlük kaydını tetiklememelidir. mümkün olduğunca sınırlı olmalıdır).
  • String nesnelerinde kullanıldığında, + operatörü, varsayılan arabellek boyutu (16 karakter) ve potansiyel olarak diğer geçici String nesneleriyle bir StringBuilder örneğini örtük olarak oluşturur. Bu nedenle, StringBuilder nesnelerini açıkça oluşturmak, varsayılan + operatörüne güvenmekten daha pahalı değildir (ve çok daha verimli olabilir). Log.v() çağıran kodun, Log.v() bile dizelerin oluşturulması da dahil olmak üzere sürüm yapılarında derlendiğini ve yürütüldüğünü unutmayın.
  • Başkaları tarafından okunması ve sürüm yapılarında mevcut olması amaçlanan herhangi bir günlük kaydı, şifreli olmadan kısa ve anlaşılır olmalıdır. Bu, DEBUG düzeyine kadar tüm günlük kaydını içerir.
  • Mümkün olduğunda, tek bir satırda oturum açmaya devam edin. 80 veya 100 karaktere kadar satır uzunlukları kabul edilebilir. Mümkünse yaklaşık 130 veya 160 karakterden (etiketin uzunluğu dahil) daha uzun uzunluklardan kaçının.
  • Günlüğe kaydetme başarılı olursa, onu asla VERBOSE daha yüksek seviyelerde kullanmayın.
  • Yeniden oluşturulması zor olan bir sorunu teşhis etmek için geçici günlük kaydı kullanıyorsanız, bunu DEBUG veya VERBOSE düzeyinde tutun ve derleme zamanında devre dışı bırakmaya izin veren if blokları ile VERBOSE .
  • Günlükteki güvenlik sızıntılarına dikkat edin. Özel bilgileri kaydetmekten kaçının. Özellikle, korumalı içerik hakkındaki bilgileri günlüğe kaydetmekten kaçının. Bu, özellikle çerçeve kodu yazarken önemlidir, çünkü neyin özel bilgilerin veya korumalı içeriğin olup olmayacağını önceden bilmek kolay değildir.
  • Asla System.out.println() (veya yerel kod için printf() ) kullanmayın. System.out ve System.err /dev/null System.err yeniden yönlendirilir, böylece yazdırma ifadelerinizin görünür bir etkisi olmaz. Bununla birlikte, bu çağrılar için gerçekleşen tüm dizgi oluşturma hala yürütülür.
  • Günlük tutmanın altın kuralı, günlüklerinizin diğer günlükleri gereksiz yere arabellekten dışarı itemeyeceğidir, tıpkı diğerleri sizin günlüğünüzü dışarı atmayabilir.

Javatests stil kuralları

Test yöntemi adlandırma kurallarını izleyin ve test edileni, test edilen özel durumdan ayırmak için bir alt çizgi kullanın. Bu stil, hangi vakaların test edildiğini görmeyi kolaylaştırır. Örneğin:

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))
}