Katkıda Bulunanlar için AOSP Java Kodu Stili

Bu sayfadaki kod stilleri, Java kodunu Android Açık Kaynak Projesine (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 Saygılı Kodlama bölümüne bakın.

Tutarlı ol

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şluk kullanıyorsa, siz de yapmalısınız. Kod yorumlarının çevresinde küçük kutucuklar varsa, yorumlarınızın da çevresinde küçük kutucuklar olsun.

Stil yönergelerine sahip olmanın amacı, ortak bir kodlama sözlüğüne sahip olmaktır, böylece okuyucular nasıl söylediğiniz yerine ne söylediğinize konsantre olabilir. Kelime dağarcığını bilmeniz için burada global 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ı okuduklarında ritmin dışına çıkarır. Bundan kaçınmaya çalışın.

Java dili kuralları

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

İstisnaları göz ardı etmeyin

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

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

Bunu yapma. Kodunuzun bu hata koşuluyla hiçbir zaman karşılaşmayacağını veya bununla başa çıkmanın önemli olmadığını düşünüyor olsanız da, bu tür bir istisnayı göz ardı etmek, bir gün başka birinin tetiklemesi için kodunuzda 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 birisi boş bir yakalama maddesine sahip olsa, ürkütücü bir duyguya sahip olmalıdır. Gerçekten yapılacak doğru şey olduğu zamanlar vardır, ama en azından bunun hakkında düşünmeniz gerekir. Java'da ürpertici duygudan kaçamazsınız. " -James Gosling

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

  • İstisnayı yönteminizin 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ı dikkatli bir şekilde ele alın ve catch {} bloğunda 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
        }
      }
    
  • İstisnayı yakalayın ve RuntimeException yeni bir örneğini atın. Bu tehlikelidir, bu yüzden bunu yalnızca bu hatanın meydana gelmesi durumunda 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, onu görmezden gelebilirsiniz, ancak bunun 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 bunun gibi 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 tüm durumlarda, genel Exception veya Throwable yakalamak uygun değildir (tercihen Throwable değildir, çünkü Error istisnaları içerir). Tehlikelidir çünkü bu, hiç beklemediğiniz istisnaların ( ClassCastException gibi çalışma zamanı istisnaları dahil) uygulama düzeyinde hata işlemeye yakalanması anlamına gelir. Bu, kodunuzun hata işleme özelliklerini gizler, yani biri 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ı (bir kullanıcı arayüzünde görünmelerini önlemek veya bir toplu işin çalışmasını sağlamak için) yakalamak istediğiniz test kodu ve üst düzey koddur. Bu durumlarda, genel Exception (veya Throwable ) yakalayabilir ve hatayı uygun şekilde işleyebilirsiniz. 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:

  • Her istisnayı çoklu yakalama bloğunun bir parçası olarak ayrı ayrı yakalayın, örneğin:
    try {
        ...
    } catch (ClassNotFoundException | NoSuchMethodException e) {
        ...
    }
  • Birden çok deneme bloğuyla daha ayrıntılı hata işlemeye sahip olmak için kodunuzu yeniden düzenleyin. IO'yu ayrıştırmadan ayırın ve her durumda hataları ayrı ayrı ele alın.
  • İstisnayı yeniden atın. Çoğu zaman, yine de bu düzeyde istisnayı yakalamanız gerekmez, yöntemin onu 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 yürütülecek bir kod yığınına sahip olmanın bir yoludur. Sonlandırıcılar (özellikle dış kaynaklar) temizlik için kullanışlı olsa da, 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ıları 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 ne zaman çağrılması gerektiğini tam olarak belgeleyin (örnek için InputStream'e bakın). Bu durumda, günlükleri taşması beklenmediği sürece sonlandırıcıdan kısa bir günlük mesajı yazdırmak uygundur ancak gerekli değildir.

Tam nitelikli ithalat

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

  • import foo.*;

    İçe aktarma ifadelerinin 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 okunabilir olmasını sağlar.

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ı kullanma 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. Böyle bir kodla çalışırken, mevcut stile devam etmenizde bir sakınca yoktur. Ancak yeni bileşenler oluştururken, kullanımdan kaldırılmış kitaplıkları asla kullanmayın.

Java stili kuralları

Javadoc standart yorumlarını kullanın

Her dosyanın en üstünde bir telif hakkı bildirimi, 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 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 {
    ...
}

Yazdığınız her sınıf ve önemsiz 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) {
    ...
}

Tüm Javadoc'unuz "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ıtlama uygulamak gibi veya önemli bir yan etkisi varsa), bunu belgelemelisiniz. "Foo" özelliğinin ne anlama geldiği açık değilse, bunu belgelemelisiniz.

Yazdığınız her yöntem, genel veya başka türlü Javadoc'tan yararlanır. Genel yöntemler bir API'nin parçasıdır ve bu nedenle Javadoc gerektirir. Android, Javadoc yorumları yazmak için belirli bir stili zorunlu kılmaz, ancak Javadoc Aracı için Doküman 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 odaklı tutun. Uzun yöntemlerin bazen uygun olduğunu biliyoruz, bu nedenle yöntem uzunluğuna kesin bir sınır konmaz. Bir metot 40 satırı aşarsa, programın yapısına zarar vermeden bölünüp bölünemeyeceğini düşünün.

Standart yerlerde alanları tanımlayın

Alanları ya dosyanın üstünde ya da 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 ifadeleridir. 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, 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));

Ancak, try-catch bloğunu bir yönteme dahil ederek bu durumdan 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, for deyiminin 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 beyanlarını sipariş edin

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

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

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

  • Her gruplama içinde, büyük harfler küçük harflerden önce olacak şekilde alfabetik (ö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, siparişte herhangi bir stil gereksinimi yoktu, yani IDE'ler ya her zaman sıralamayı 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 Android'e basitçe "bir sipariş seçip tutarlı olması" gerekti. 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 içe aktarmaların ekstra mühendislik çabası olmadan bu modelle eşleşmesini bekliyoruz.

Bu stili şu şekilde seçtik:

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

Statik ithalatları, normal ithalatlarla aynı şekilde sipariş edilen 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 kullanıyoruz. Şüphe duyduğunuzda, çevreleyen kodla tutarlı olun.

İşlev çağrıları ve atamalar dahil olmak üzere satır sarma için sekiz (8) boşluk girintisi kullanırız.

Önerilen

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

Tavsiye edilmez

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

Alan adlandırma kurallarını takip edin

  • 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, derinden 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ın

Parantezleri kendi satırlarına değil, önlerindeki kodla aynı satıra koyun:

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

Koşullu ifadeler için parantezlere ihtiyacımız var. İstisna: Tüm koşul (koşul ve gövde) bir satıra sığıyorsa, 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!

Çizgi uzunluğunu sınırla

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

  • Bir yorum satırı, 100 karakterden uzun bir örnek komut veya hazır URL içeriyorsa, kesme ve yapıştırma kolaylığı için bu satır 100 karakterden uzun olabilir.
  • İçe aktarma satırları sınırı aşabilir çünkü insanlar bunları nadiren görür (bu ayrıca araç yazmayı da kolaylaştırır).

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şaretleyici açıklamaları (örneğin, @Override ), dil öğesiyle aynı satırda listelenebilir. Birden fazla açıklama veya parametreli açıklama varsa, bunları alfabetik sırayla her satırda bir tane olacak şekilde listeleyin.

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

  • Açıklamalı öğenin kullanılması önerilmediğinde @Deprecated 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 uygulamaya isim vermesi gerekir. Ayrıca, @Deprecated yönteminin 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 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 türetiyorsanız (bir arabirim değil), 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 notu gerekli olduğunda, "ortadan kaldırmak imkansız" koşulunu açıklayan bir TODO yorumu ile ö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ın

İsimleri daha okunaklı kılmak için değişkenleri, yöntemleri ve sınıfları adlandırırken kısaltmalara ve kısaltmalara kelimeler gibi davranın:

İyi Kötü
XmlHttpTalebi XMLHTTPTalebi
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ısaltmalara her zaman kelimeler gibi davranın.

YAPILACAKLAR yorumlarını kullanın

Geçici, kısa vadeli bir çözüm veya yeterince iyi ancak mükemmel olmayan kod için TODO yorumlarını kullanın. Bu yorumlar, tüm büyük harflerle TODO dizesini ve ardından iki nokta üst üste işareti 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 "Gelecek bir tarihte bir şeyler yapın" biçimindeyse, belirli bir tarih ("Kasım 2005'e kadar düzeltin") 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. ).

Dikkatli bir şekilde oturum açın

Günlüğe kaydetme gerekli olmakla birlikte, performans üzerinde olumsuz bir etkisi vardır ve makul şekilde kısa tutulmazsa kullanışlılığını kaybeder. Günlüğe kaydetme olanakları, beş farklı günlüğe kaydetme düzeyi sağlar:

  • ERROR : Ölümcül bir şey olduğunda kullanın, yani, bir şey kullanıcının görebileceği sonuçlara sahip olacak ve bazı veriler silinmeden, uygulamaları kaldırmadan, veri bölümlerini silmeden veya tüm cihazı yeniden başlatmadan (veya daha kötüsü) kurtarılamaz. Bu seviye her zaman günlüğe kaydedilir. ERROR düzeyinde bazı günlükleri haklı çıkaran sorunlar, istatistik toplama sunucusuna bildirilmek için iyi adaylardır.
  • WARNING : Ciddi ve beklenmedik bir şey olduğunda kullanın, yani kullanıcı tarafından görülebilen sonuçlara sahip olacak, ancak bir uygulamayı beklemekten veya yeniden başlatmaktan yeniden indirmeye kadar uzanan bir dizi açık eylem gerçekleştirerek veri kaybı olmadan kurtarılabilir olması muhtemel bir şey. bir uygulamanın yeni bir 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ı kılan sorunlar, istatistik toplama sunucusuna raporlama için de düşünülebilir.
  • INFORMATIVE : İlginç bir şey olduğunu, yani yaygın bir etkiye sahip olması muhtemel bir durum tespit edildiğinde, ancak mutlaka bir hata olmadığını belirtmek 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 olduğunu daha fazla not etmek için kullanın. Yalnızca bileşeninizde olup bitenler 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 kullanmalısınız.

    Bu seviye, sürüm sürümlerinde bile günlüğe kaydedilir ve bir if (LOCAL_LOG) veya if LOCAL_LOGD) bloğuyla çevrelenmesi gerekir; 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 olmamalıdır. 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üğe kaydetme çağrısını bir yöntem çağrısına yeniden düzenlemeyin.

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

  • VERBOSE : Diğer her şey için kullanın. Bu düzey 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

  • 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ı zincirinde, yalnızca en içteki işlev hatayı döndürmelidir ve aynı modüldeki arayanlar, sorunun yalıtılmasına önemli ölçüde yardımcı oluyorsa, yalnızca bir miktar günlük eklemelidir.
  • VERBOSE seviyesinden başka bir modül zincirinde, daha düşük seviyeli bir modül daha yüksek seviyeli bir modülden gelen geçersiz veriyi tespit ettiğinde, alt seviye modül bu durumu yalnızca DEBUG günlüğüne kaydetmeli ve yalnızca loglama aşağıdakileri sağlıyorsa: arayan kişi için başka şekilde mevcut olmayan bilgiler. Özellikle, bir istisnanın oluşturulduğu (istisna tüm ilgili bilgileri içermelidir) veya günlüğe kaydedilen tek bilginin bir hata kodunda bulunduğu durumları günlüğe kaydetmeye gerek yoktur. Bu, çerçeve ve uygulamalar arasındaki etkileşimde özellikle önemlidir ve çerçeve tarafından düzgün bir şekilde işlenen üçüncü taraf uygulamaların neden olduğu koşullar, DEBUG seviyesinden daha yüksek bir günlüğe kaydetmeyi 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 meydana gelmesi muhtemel olduğunda, günlüklerin aynı (veya çok benzer) bilgilerin birçok yinelenen kopyasıyla 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 nedensiz bir şekilde günlüğe 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 derlemesinde günlüğe 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'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ı üzerinden gelen veriler dahil) beklenen olarak kabul edilir ve geçersiz olduğu tespit edildiğinde (ve hatta o zaman günlüğe kaydetme) DEBUG daha yüksek bir düzeyde günlük kaydını tetiklememelidir. mümkün olduğunca sınırlı olmalıdır).
  • + operatörü, String nesnelerinde kullanıldığında, varsayılan arabellek boyutu (16 karakter) ve potansiyel olarak diğer geçici String nesneleri ile örtük olarak bir StringBuilder örneği oluşturur. Bu nedenle, açıkça StringBuilder nesneleri oluşturmak, varsayılan + operatörüne güvenmekten daha pahalı değildir (ve çok daha verimli olabilir). Log.v() 'yi çağıran kodun, günlükler okunmasa bile, dizelerin oluşturulması da dahil olmak üzere, sürüm derlemelerinde derlendiğini ve yürütüldüğünü unutmayın.
  • Başkaları tarafından okunması ve sürüm yapılarında bulunması gereken herhangi bir günlük kaydı, şifreli olmadan özlü olmalı ve anlaşılabilir olmalıdır. Bu, DEBUG düzeyine kadar olan tüm oturum açma işlemlerini 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 olan uzunluklardan kaçının.
  • Günlüğe kaydetme raporları başarılıysa, bunu asla VERBOSE daha yüksek seviyelerde kullanmayın.
  • Yeniden üretilmesi 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ırakılmasına izin veren if bloklarıyla kapatın.
  • Günlükten 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. Bu, özel bilgilerin veya korunan içeriğin ne olup olmayacağını önceden bilmek kolay olmadığından, çerçeve kodu yazarken özellikle önemlidir.
  • Asla System.out.println() (veya yerel kod için printf() ) kullanmayın. System.out ve System.err , /dev/null dizinine yönlendirilir, böylece print 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ı, günlüklerinizin diğer günlükleri arabellekten gereksiz yere itmemesidir, tıpkı diğerlerinin sizinkileri dışarı itmemesi gibi.

Javatest stil kuralları

Test yöntemi adlandırma kurallarını takip edin 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))
}