Katkıda bulunanlar için AOSP Java kod stili

Bu sayfadaki kod stilleri, Java kodunu 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. Daha kapsayıcı bir ekosistem için kullanılacak ve kaçınılacak terminoloji örnekleri için Kodlama'ya bakın.

Tutarlı olun

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

Stil yönergelerine sahip olmanın amacı, ortak bir kodlama sözlüğüne sahip olmaktır, böylece okuyucular, nasıl söylediğinizden çok ne söylediğinize konsantre olabilir. Sözlüğü bilmeniz için burada genel stil kurallarını sunuyoruz, ancak yerel stil de önemlidir. Bir dosyaya eklediğiniz kod, etrafındaki mevcut koddan büyük ölçüde farklı görünüyorsa, okuyucular onu okuduklarında ritimlerini bozarlar. Bundan kaçınmaya çalışın.

Java dil kuralları

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

İstisnaları göz ardı etmeyin

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 durumuyla 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 bir gün başka birinin tetiklemesi için mayınlar oluşturur. Kodunuzdaki her istisnayı ilkeli bir şekilde ele almalısınız; özel işlem duruma göre değişir.

" Ne zaman birisi boş bir yakalama yan tümcesine sahip olsa, ürkütücü bir duyguya sahip olmalıdır. Bunun gerçekten yapılacak doğru şey olduğu zamanlar kesinlikle vardır, ama en azından bunun hakkında düşünmeniz gerekir. Java'da ürkütücü 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 atın.
      void setServerPort(String value) throws ConfigurationException {
        try {
            serverPort = Integer.parseInt(value);
        } catch (NumberFormatException e) {
            throw new ConfigurationException("Port " + value + " is not valid.");
        }
      }
    
  • Hatayı nazikçe ele alın ve catch {} bloğunda uygun bir değerle 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
        }
      }
    
  • İstisnayı yakalayın ve yeni bir RuntimeException örneği atın. Bu tehlikelidir, bu yüzden bunu yalnızca bu hata oluşursa yapılacak uygun şeyin çökmek 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, görmezden gelebilirsiniz, ancak nedenini de iyi bir nedenle açıklamanız gerekir.
    /** 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ı yakalama

İstisnaları yakalarken tembel olmak ve şöyle bir şey 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 her durumda, genel Exception veya Throwable yakalamak uygun değildir ( Error istisnaları içerdiğinden tercihen Throwable ). Bu tehlikelidir, çünkü hiç beklemediğiniz istisnaların ( ClassCastException gibi çalışma zamanı istisnaları dahil) uygulama düzeyinde hata işlemede yakalanması 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ğini belirtmez. Ç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 (bir kullanıcı arabiriminde görünmelerini önlemek veya bir toplu işi çalışır durumda tutmak için) test kodu ve üst düzey koddur. Bu durumlarda, genel Exception (veya Throwable ) yakalayabilir ve hatayı uygun şekilde işleyebilirsiniz. Yine de bunu yapmadan önce dikkatlice düşünün ve bu bağlamda neden güvenli olduğunu açıklayan yorumlar yazın.

Genel istisnaları yakalamanın alternatifleri:

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

İstisnaların dostunuz 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ı kullanmayın

Sonlandırıcılar, bir nesne çöp toplandığında bir yığın kod yürütmenin bir yoludur. Sonlandırıcılar temizlik için kullanışlı olsa da (özellikle harici kaynaklar için), bir sonlandırıcının ne zaman çağrılacağına (hatta çağrılacağına) dair hiçbir garanti yoktur.

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

Tam nitelikli ithalatlar

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

  • import foo.*;

    Potansiyel olarak içe aktarma ifadelerinin sayısını azaltır.

  • import foo.Bar;

    Hangi sınıfların kullanıldığını açıkça gösterir ve kod bakımcılar için daha okunaklıdır.

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.* ) için açık bir istisna yapılmıştır.

Java kitaplığı kuralları

Android'in Java kitaplıklarını ve araçlarını kullanmak için kurallar vardır. Bazı durumlarda, sözleşme önemli şekillerde değişmiştir ve eski kod, kullanımdan kaldırılmış bir kalıp veya kitaplık kullanabilir. Bu tür bir kodla çalışırken, mevcut stile devam etmekte sorun yoktur. Bununla birlikte, 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 en üstünde bir telif hakkı bildirimi, ardından package ve import ifadeleri (her blok bir boş satırla ayrılmış) ve son olarak sınıf veya arayüz bildirimi bulunmalıdır. Javadoc yorumlarında, sınıfın veya arabirimin ne yaptığını açıklayın.

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

Yazdığınız her sınıf ve önemsiz olmayan genel yöntem, sınıfın veya yöntemin ne yaptığını açıklayan en az bir cümle içeren bir Javadoc yorumu içermelidir. Bu cümle üçüncü şahıs tanımlayıcı 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) {
    ...
}

Javadoc'unuzun tüm söyleyeceği "sets Foo" ise, setFoo() gibi önemsiz get ve set yöntemleri için Javadoc yazmanıza gerek yoktur. Yöntem daha karmaşık bir şey yapıyorsa (bir kısıtlamayı zorlamak veya önemli bir yan etkisi varsa), o zaman bunu belgelemeniz gerekir. "Foo" özelliğinin ne anlama geldiği açık değilse, bunu belgelemelisiniz.

Genel veya başka türlü yazdığınız her yöntem Javadoc'tan faydalanacaktı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

Uygulanabilir olduğunda, yöntemleri küçük ve odaklı tutun. Uzun yöntemlerin bazen uygun olduğunun farkındayız, bu nedenle yöntem uzunluğuna kesin bir sınır getirilmez. Bir metot 40 satırı aşarsa, programın yapısına zarar vermeden parçalara ayrılıp ayrılamayacağını düşünün.

Alanları standart yerlerde 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. Her değişkeni, değişkenin tüm kullanımlarını kapsayan en içteki blokta 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 mantıklı bir şekilde başlatmak için yeterli bilgiye sahip değilseniz, bunu yapana kadar bildirimi erteleyin.

Bunun istisnası, try-catch deyimleridir. Bir değişken, kontrol edilen bir istisna oluşturan bir yöntemin dönüş değeriyle başlatılırsa, bir try bloğu içinde başlatılmalıdır. Değerin try bloğunun dışında kullanılması gerekiyorsa, try bloğundan önce bildirilmelidir, burada henüz mantıklı bir şekilde başlatılamaz:

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

Ancak, try-catch bloğunu bir yöntemde kapsülleyerek bu durumdan bile kaçınabilirsiniz:

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 döngü değişkenlerini for ifadesinin kendisinde bildirin:

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

ve

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

Sipariş ithalat beyanları

İçe aktarma beyanlarının sıralaması şu şekildedir:

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

IDE ayarlarıyla tam olarak eşleşmesi için içe aktarmalar şöyle olmalıdır:

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

Başlangıçta sıralamada herhangi bir stil gereksinimi yoktu, yani IDE'ler ya sıralamayı her zaman değiştiriyordu 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 stili sorulduğunda, tercih edilen stiller çılgınca değişiyordu ve sıra Android'e geldi ve basitçe "bir sıralama seçip tutarlı olmaya" ihtiyaç duydu. 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, ekstra mühendislik çabası olmadan tüm paketlerdeki içe aktarmaların bu modelle eşleşmesini bekliyoruz.

Bu stili şu şekilde seçtik:

  • İnsanların ilk önce bakmak istedikleri ithalat, en üstte ( android ) olma eğilimindedir.
  • İnsanların en azından bakmak istedikleri ithalatlar en altta ( java ) olma eğilimindedir.
  • İnsanlar stili kolayca takip edebilir.
  • IDE'ler stili takip edebilir.

Statik ithalatı, normal ithalatla aynı şekilde sıralanan diğer tüm ithalatların üzerine koyun.

Girinti için boşluk kullanın

Bloklar için dört (4) boşluk girintisi kullanıyoruz ve asla sekmeler kullanmıyoruz. Şüpheye düştüğünüzde, çevreleyen kodla tutarlı olun.

İşlev çağrıları ve atamalar dahil olmak üzere 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

  • Herkese açık olmayan, statik olmayan alan adları m ile başlar.
  • Statik alan adları s ile başlar.
  • Diğer alanlar küçük harfle başlar.
  • Statik son alanlar (sabitler, son derece değişmez) 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 ayraç stilini kullan

Parantezleri kendilerinden önceki kodla aynı satıra koyun, kendi satırına değil:

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

Bir koşullu için ifadelerin etrafında ayraçlara ihtiyacımız var. İstisna: Tüm koşullu (koşul ve gövde) bir satıra sığarsa, hepsini bir satıra koyabilirsiniz (ancak zorunlu değilsiniz). Örneğin, bu kabul edilebilir:

if (condition) {
    body();
}

ve bu kabul edilebilir:

if (condition) body();

ama bu kabul edilemez:

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

Hat uzunluğunu sınırla

Kodunuzdaki her metin satırı en fazla 100 karakter uzunluğunda olmalıdır. Bu kuralın etrafında çok fazla tartışma yapılmış olsa da, aşağıdaki istisnalar dışında 100 karakterin maksimum olduğu kararı devam etmektedir:

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

Standart Java ek açıklamalarını kullanın

Ek açıklamalar, aynı dil öğesi için diğer değiştiricilerden önce gelmelidir. Basit işaret ek 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 her satırda bir 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 ek açıklamasını kullanın. @Deprecated ek açıklamasını kullanırsanız, ayrıca bir @deprecated Javadoc etiketine sahip olmanız ve bunun alternatif bir uygulamayı adlandırması gerekir. Ek olarak, bir @Deprecated yönteminin hala çalışması gerektiğini unutmayın. @deprecated Javadoc etiketine sahip eski bir kod görürseniz, @Deprecated ekleyin.
  • Bir yöntem, bir üst sınıftan bildirimi veya uygulamayı geçersiz kıldığında, @Override ek açıklamasını kullanın. Örneğin, @inheritdocs Javadoc etiketini kullanıyorsanız ve bir sınıftan (arayüzden değil) türetiyorsanız, 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 "ortadan kaldırılması imkansız" testini geçerse, tüm uyarıların koddaki gerçek sorunları yansıtmasını sağlamak için @SuppressWarnings notu kullanılmalıdır.

    Bir @SuppressWarnings ek açıklaması gerekli olduğunda, "ortadan kaldırılması imkansız" koşulunu açıklayan bir TODO yorumun önüne eklenmelidir. Bu normalde garip bir arayüze sahip rahatsız edici bir 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);
    

    Bir @SuppressWarnings ek açıklaması gerektiğinde, ek 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

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

İyi Kötü
XmlHttp İsteği XMLHTTPİstek
getCustomerId getCustomerID
sınıf Html sınıf HTML'si
Dize URL'si Dize URL'si
uzun kimlik uzun kimlik

Hem JDK hem de Android kod tabanları kısaltmalar konusunda tutarsız olduğundan, çevreleyen kodla tutarlı olmak neredeyse imkansızdır. Bu nedenle, kısaltmaları her zaman sözcük olarak ele alın.

TODO yorumlarını kullanın

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

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

ve

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

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

İdareli bir şekilde oturum açın

Günlüğe kaydetme gerekli olmakla birlikte, performans üzerinde olumsuz bir etkiye sahiptir ve makul ölçüde kısa tutulmadığı takdirde kullanışlılığını kaybeder. Kayıt olanakları, beş farklı kayıt düzeyi sağlar:

  • ERROR : Ölümcül bir şey olduğunda, yani bir şeyin kullanıcı tarafından görülebilen sonuçları olduğunda ve bazı verileri silmeden, uygulamaları kaldırmadan, veri bölümlerini silmeden veya tüm cihazı yeniden yüklemeden (veya daha kötüsü) kurtarılamaz olduğunda kullanın. Bu seviye her zaman günlüğe kaydedilir. ERROR düzeyinde bazı günlük kaydı yapılması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ülebilen sonuçları olacak ancak bir uygulamayı beklemek veya yeniden başlatmaktan yeniden indirmeye kadar değişen bazı açık eylemler gerçekleştirerek veri kaybı olmadan kurtarılabilecek bir şey olduğunda kullanın. bir uygulamanın yeni sürümü veya cihazın yeniden başlatılması. Bu seviye her zaman günlüğe 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 olduğunu, yani bir hata olması gerekmese de geniş çapta etki yaratması muhtemel bir durum algılandığında olduğunu not etmek için kullanın. Böyle bir koşul, yalnızca o etki alanındaki en yetkili olduğuna inanan bir modül tarafından günlüğe kaydedilmelidir (yetkili olmayan bileşenler tarafından yinelenen günlüğe kaydetmeyi önlemek için). Bu seviye her zaman günlüğe kaydedilir.
  • DEBUG : Beklenmeyen davranışları araştırmak ve hata ayıklamak için ilgili olabilecek cihazda neler olup bittiğini daha fazla not etmek için kullanın. Yalnızca bileşeninizde neler olup bittiği hakkında yeterli bilgi toplamak için gerekenleri günlüğe kaydedin. Hata ayıklama günlükleriniz günlüğe hakimse, ayrıntılı günlük kaydı kullanmalısınız.

    Bu seviye, yayın yapılarında bile günlüğe kaydedilir ve sınıfınızda veya alt bileşeninizde LOCAL_LOG[D] 'nin tanımlandığı bir if (LOCAL_LOG) veya if LOCAL_LOGD) bloğu ile çevrelenmesi gerekir, böylece tüm bu günlükleri devre dışı bırakma olasılığı vardır. . Bu nedenle, bir if (LOCAL_LOG) bloğunda aktif bir mantık olmamalıdır. Günlük için oluşturulan tüm dizilerin de 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ına yeniden düzenlemeyin.

    Hala if (localLOGV) yazan bazı kodlar var. Adı standart olmamasına rağmen 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 oturum açar ve varsayılan olarak derlenebilmesi için bir if (LOCAL_LOGV) bloğu (veya eşdeğeri) ile çevrelenmelidir. Herhangi bir dize yapısı, yayın yapılarından çıkarılır ve if (LOCAL_LOGV) bloğunun içinde görünmesi gerekir.

notlar

  • Belirli bir modül içinde, VERBOSE düzeyi dışında, bir hata mümkünse yalnızca bir kez bildirilmelidir. Bir modül içindeki tek bir işlev çağrıları zincirinde, yalnızca en içteki işlev hatayı döndürmeli ve aynı modüldeki arayanlar, yalnızca sorunun yalıtılmasına önemli ölçüde yardımcı oluyorsa bir miktar günlük kaydı eklemelidir.
  • VERBOSE düzeyi dışında bir modüller zincirinde, alt düzey bir modül üst düzey bir modülden gelen geçersiz verileri algıladığında, alt düzey modül bu durumu yalnızca DEBUG günlüğüne kaydetmeli ve yalnızca günlük kaydı şunları sağlıyorsa Arayan için başka şekilde mevcut olmayan bilgiler. Spesifik olarak, bir istisnanın atıldığı (istisnanın ilgili tüm bilgileri içermesi gerekir) veya günlüğe kaydedilen tek bilginin bir hata kodunda yer aldığı durumları günlüğe kaydetmeye gerek yoktur. Bu, çerçeve ve uygulamalar arasındaki etkileşimde özellikle önemlidir ve çerçeve tarafından uygun şekilde işlenen üçüncü taraf uygulamalarının neden olduğu koşullar, DEBUG düzeyinden daha yüksek günlük kaydı tetiklememelidir. INFORMATIVE düzeyinde veya daha yüksek düzeyde günlük kaydını tetiklemesi gereken tek durum, bir modülün 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ı çıkaracak bir koşulun birçok kez ortaya çıkması muhtemel olduğunda, aynı (veya çok benzer) bilgilerin birçok yinelenen kopyasıyla günlüklerin taşmasını önlemek için bazı hız sınırlayıcı mekanizmalar uygulamak iyi bir fikir olabilir.
  • Ağ bağlantısındaki kayıplar yaygın kabul edilir ve tamamen beklenir ve karşılıksız olarak günlüğe kaydedilmemelidir. Bir uygulama içinde sonuçları olan bir ağ bağlantısı kaybı, DEBUG veya VERBOSE seviyesinde günlüğe kaydedilmelidir (sonuçların bir sürüm derlemesinde kaydedilecek kadar ciddi ve beklenmedik olup olmadığına bağlı olarak).
  • Üçüncü taraf uygulamalar tarafından veya adına erişilebilen bir dosya sisteminde tam bir dosya sistemine sahip olmak, BİLGİLENDİRME seviyesinden daha yüksek bir seviyede günlüğe kaydedilmemelidir.
  • Güvenilmeyen herhangi bir kaynaktan (paylaşılan depolamadaki herhangi bir dosya veya bir ağ bağlantısı üzerinden gelen veriler dahil) gelen geçersiz veriler beklenen olarak kabul edilir ve geçersiz olduğu tespit edildiğinde (ve hatta daha sonra günlük kaydı yapıldığında) DEBUG daha yüksek bir seviyede 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ü dolaylı olarak varsayılan arabellek boyutuna (16 karakter) ve potansiyel olarak diğer geçici String nesnelerine sahip bir StringBuilder örneği oluşturur. Bu nedenle, açıkça StringBuilder nesneleri oluşturmak, varsayılan + işlecine güvenmekten daha pahalı değildir (ve çok daha verimli olabilir). Günlükler okunmuyor olsa bile, Log.v() 'yi çağıran kodun, dizelerin oluşturulması da dahil olmak üzere yayın yapılarında derlendiğini ve yürütüldüğünü unutmayın.
  • Diğer kişiler tarafından okunması ve sürüm yapılarında bulunması 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ükleri 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 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 çevreleyin.
  • Günlük aracılığıyla güvenlik sızıntılarına karşı dikkatli olun. Özel bilgileri günlüğe kaydetmekten kaçının. Özellikle, korunan içerikle ilgili bilgileri günlüğe kaydetmekten kaçının. Neyin özel bilgi veya korumalı içerik olup olmayacağını önceden bilmek kolay olmadığından, bu özellikle çerçeve kodu yazarken önemlidir.
  • Asla System.out.println() (veya yerel kod için printf() ) kullanmayın. System.out ve System.err , /dev/null konumuna yönlendirilir, böylece yazdırma ifadelerinizin görünür bir etkisi olmaz. Ancak, bu çağrılar için gerçekleşen tüm dizi oluşturma işlemi yine de yürütülür.
  • Günlüğe kaydetmenin altın kuralı, diğerlerinin sizinkini dışarı atmayacağı gibi, sizin günlüklerinizin de diğer günlükleri gereksiz yere arabellekten çıkarmamasıdır.

Java testleri stil kuralları

Test yöntemi adlandırma kurallarını izleyin ve test edileni test edilen belirli durumdan ayırmak için bir alt çizgi kullanın. Bu tarz, 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))
}