Styly kódu na této stránce představují přísná pravidla pro přispívání kódem v jazyce Java do projektu Android Open Source Project (AOSP). Příspěvky do platformy Android, které tato pravidla nedodržují, nejsou obecně přijímány. Uznáváme, že ne všechen existující kód tato pravidla dodržuje, ale očekáváme, že veškerý nový kód bude v souladu s nimi. V části Coding with Respect najdete příklady terminologie, kterou je třeba používat a které se vyvarovat, aby byl ekosystém inkluzivnější.
- Buďte konzistentní
- Pravidla jazyka Java
- Neignorujte výjimky
- Nechytejte obecné výjimky
- Nepoužívejte finalizátory
- Fully qualify imports
- Pravidla knihoven Java
- Pravidla stylu jazyka Java
- Pište krátké metody
- Definujte pole na standardních místech
- Omezte rozsah proměnných
- Order import statements
- Use spaces for indentation
- Follow field naming conventions
- Use standard brace style
- Limit line length
- Používejte standardní anotace jazyka Java
- Treat acronyms as words
- Protokolujte střídmě
- Poznámky
- Pravidla stylu Javatests
Buďte konzistentní
Jedním z nejjednodušších pravidel je BÝT KONZISTENTNÍ. Pokud upravujete kód, věnujte několik minut tomu, abyste se podívali na okolní kód a určili jeho styl. Pokud tento kód používá mezery kolem klauzulí if
, měli byste je používat také. Pokud mají komentáře kódu kolem sebe malé rámečky s hvězdičkami, zařiďte, aby i vaše komentáře měly kolem sebe malé rámečky s hvězdičkami.
Smyslem zásad stylu je mít jednotný slovník kódování, aby se čtenáři mohli soustředit na to, co říkáte, a ne na to, jak to říkáte. Předkládáme zde globální pravidla stylu, abyste znali slovník, ale lokální styl je také důležitý. Pokud kód, který přidáte do souboru, vypadá drasticky odlišně od stávajícího kódu v okolí, vyvede to čtenáře při čtení z rytmu. Snažte se tomu vyhnout.
Pravidla jazyka Java
Systém Android dodržuje standardní konvence kódování jazyka Java s dalšími pravidly popsanými níže.
Neignorujte výjimky
Může být lákavé napsat kód, který ignoruje výjimku, např:
void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { } }
To nedělejte. I když si možná myslíte, že se váš kód s tímto chybovým stavem nikdy nesetká nebo že není důležité jej ošetřit, ignorování tohoto typu výjimky vytváří ve vašem kódu miny, které může někdy spustit někdo jiný. Každou výjimku ve svém kódu musíte zásadně ošetřit; konkrétní způsob ošetření se liší v závislosti na konkrétním případu.
„Kdykoli má někdo prázdnou klauzuli catch, měl by mít husí kůži. Určitě existují případy, kdy je to skutečně správné, ale musíte se nad tím alespoň zamyslet. V Javě se strašidelnému pocitu nevyhnete.“ – James Gosling
Přijatelné alternativy (podle pořadí preferencí) jsou:
- Vyhodit výjimku až volajícímu metody.
void setServerPort(String value) throws NumberFormatException { serverPort = Integer.parseInt(value); }
- Vyhodit novou výjimku odpovídající úrovni abstrakce.
void setServerPort(String value) throws ConfigurationException { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { throw new ConfigurationException("Port " + value + " is not valid."); } }
- Chybu elegantně zpracujte a v bloku
catch {}
nahraďte vhodnou hodnotou./** 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 } }
- Zachyťte výjimku a vyhoďte novou instanci
RuntimeException
. To je nebezpečné, takže to dělejte pouze v případě, že jste si jisti, že v případě výskytu této chyby je vhodné výjimku zrušit./** 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); } }
- V krajním případě, pokud jste si jisti, že ignorování výjimky je vhodné, pak ji můžete ignorovat, ale musíte také okomentovat proč s dobrým odůvodněním.
/** 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. }}
Nechytejte obecné výjimky
Může být lákavé být při chytání výjimek líný a udělat něco takového:
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! }
Nedělejte to. Téměř ve všech případech je nevhodné chytat generické Exception
nebo Throwable
(nejlépe ne Throwable
, protože obsahuje Error
výjimky). Je to nebezpečné, protože to znamená, že výjimky, které jste nikdy nečekali (včetně výjimek za běhu, jako je ClassCastException
), se zachytí při zpracování chyb na úrovni aplikace. Zastírá vlastnosti vašeho kódu týkající se zpracování chyb, což znamená, že pokud někdo přidá do kódu, který voláte, nový typ výjimky, překladač vás neupozorní, že je třeba chybu zpracovat jinak. Ve většině případů byste neměli různé typy výjimek zpracovávat stejným způsobem.
Vzácnou výjimkou z tohoto pravidla je testovací kód a kód nejvyšší úrovně, kde chcete zachytit všechny druhy chyb (aby se nezobrazovaly v uživatelském rozhraní nebo aby dávková úloha běžela dál). V těchto případech můžete zachytit obecný Exception
(nebo Throwable
) a chybu vhodně zpracovat. Než to však uděláte, dobře si to rozmyslete a do komentáře vložte vysvětlení, proč je to v tomto kontextu bezpečné.
Alternativy k zachytávání obecných výjimek:
- Zachytávejte každou výjimku zvlášť jako součást bloku s více pokusy, například:
try { ...} catch (ClassNotFoundException | NoSuchMethodException e) { ...}
- Přepracujte kód tak, aby měl jemnější ošetření chyb pomocí více bloků pokusů. Oddělte IO od parsování a ošetřujte chyby v každém případě zvlášť.
- Zahoďte výjimku. Mnohdy stejně nepotřebujete výjimku na této úrovni zachytit, prostě ji nechte metodu vyhodit.
Nezapomeňte, že výjimky jsou vaši přátelé! Když si překladač stěžuje, že nechytáte výjimku, nemračte se. Usmějte se! Překladač vám právě usnadnil zachycení problémů při běhu kódu.
Nepoužívejte finalizátory
Finalizátory jsou způsob, jak nechat vykonat část kódu, když je objekt vybírán do koše. Ačkoli finalizátory mohou být užitečné pro čištění (zejména externích zdrojů), neexistuje žádná záruka, kdy bude finalizátor zavolán (nebo dokonce že bude vůbec zavolán).
Systém Android finalizátory nepoužívá. Ve většině případů můžete místo toho použít dobré zpracování výjimek. If you absolutely need a finalizer, define a close()
method (or the like) and document exactly when that method needs to be called (see InputStream for an example). In this case, it’s appropriate but not required to print a short log message from the finalizer, as long as it’s not expected to flood the logs.
Fully qualify imports
When you want to use class Bar
from package foo
, there are two possible ways to import it:
-
import foo.*;
Potentially reduces the number of import statements.
-
import foo.Bar;
Makes it obvious what classes are used and the code is more readable for maintainers.
Use import foo.Bar;
for importing all Android code. An explicit exception is made for Java standard libraries (java.util.*
java.io.*
, etc.) and unit test code (junit.framework.*
).
Pravidla knihoven Java
Pro používání knihoven a nástrojů Java systému Android platí určité konvence. V některých případech se konvence významně změnily a starší kód může používat zastaralý vzor nebo knihovnu. Při práci s takovým kódem je v pořádku pokračovat ve stávajícím stylu. Při vytváření nových komponent však nikdy nepoužívejte zastaralé knihovny.
Pravidla stylu jazyka Java
Každý soubor by měl mít na začátku prohlášení o copyrightu, následovat by měly příkazy package a import (každý blok oddělený prázdným řádkem) a nakonec deklarace třídy nebo rozhraní. V komentářích Javadoc popište, co daná třída nebo rozhraní dělá.
/* * 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 { ...}
Každá třída a netriviální veřejná metoda, kterou napíšete, musí obsahovat komentář Javadoc s alespoň jednou větou popisující, co třída nebo metoda dělá. Tato věta by měla začínat třetí osobou popisného slovesa.
Příklady
/** Returns the correctly rounded positive square root of a double value. */static double sqrt(double a) { ...}
nebo
/** * Constructs a new String by converting the specified array of * bytes using the platform's default character encoding. */public String(byte bytes) { ...}
Pro triviální metody get a set, jako je setFoo()
, nemusíte psát Javadoc, pokud by váš Javadoc říkal pouze „nastaví Foo“. Pokud metoda dělá něco složitějšího (například vynucuje omezení nebo má důležitý vedlejší efekt), pak ji musíte zdokumentovat. Pokud není zřejmé, co vlastnost „Foo“ znamená, měli byste ji zdokumentovat.
Každé metodě, kterou napíšete, ať už veřejné nebo jiné, by Javadoc prospěl. Veřejné metody jsou součástí rozhraní API, a proto vyžadují Javadoc. Systém Android nevynucuje specifický styl psaní komentářů Javadoc, ale měli byste se řídit pokyny uvedenými v části Jak psát komentáře pro nástroj Javadoc.
Pište krátké metody
Pokud je to možné, udržujte metody malé a soustředěné. Uznáváme, že dlouhé metody jsou někdy vhodné, proto není délka metod pevně omezena. Pokud metoda přesáhne přibližně 40 řádků, zamyslete se nad tím, zda ji lze rozdělit, aniž by to poškodilo strukturu programu.
Definujte pole na standardních místech
Pole definujte buď na začátku souboru, nebo bezprostředně před metodami, které je používají.
Omezte rozsah proměnných
Omezte rozsah lokálních proměnných na minimum. Zvýšíte tím čitelnost a udržovatelnost kódu a snížíte pravděpodobnost výskytu chyb. Každou proměnnou deklarujte v nejvnitřnějším bloku, který uzavírá všechna použití proměnné.
Lokální proměnné deklarujte v místě jejich prvního použití. Téměř každá deklarace lokální proměnné by měla obsahovat inicializátor. Pokud ještě nemáte dostatek informací k rozumné inicializaci proměnné, odložte deklaraci, dokud ji nezískáte.
Výjimkou jsou příkazy try-catch. Pokud je proměnná inicializována návratovou hodnotou metody, která vyhodí kontrolovanou výjimku, musí být inicializována uvnitř bloku try. If the value must be used outside of the try block, then it must be declared before the try block, where it can’t yet be sensibly initialized:
// Instantiate class cl, which represents some sort of SetSet 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 sets.addAll(Arrays.asList(args));
However, you can even avoid this case by encapsulating the try-catch block in a method:
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 setSet s = createSet(cl);s.addAll(Arrays.asList(args));
Declare loop variables in the for statement itself unless there’s a compelling reason to do otherwise:
for (int i = 0; i < n; i++) { doSomething(i);}
and
for (Iterator i = c.iterator(); i.hasNext(); ) { doSomethingElse(i.next());}
Order import statements
The ordering of import statements is:
- Android imports
- Imports from third parties (
com
junit
net
org
) -
java
andjavax
To exactly match the IDE settings, the imports should be:
- Abecedně v rámci každého seskupení, s velkými písmeny před malými (například Z před a)
- Oddělené prázdným řádkem mezi každým hlavním seskupením (
android
com
junit
net
org
java
javax
).
Původně neexistoval žádný požadavek na styl řazení, což znamenalo, že vývojáři IDE buď neustále měnili řazení, nebo museli vypnout funkce automatické správy importů a udržovat je ručně. To bylo považováno za špatné. Když byl dotazován styl Java, preferované styly se velmi lišily a došlo k tomu, že systém Android potřebuje jednoduše „vybrat pořadí a být konzistentní“. Vybrali jsme tedy styl, aktualizovali průvodce styly a přinutili IDE, aby se jím řídily. Očekáváme, že jak budou uživatelé IDE pracovat na kódu, budou importy ve všech balíčcích odpovídat tomuto vzoru bez dalšího inženýrského úsilí.
We chose this style such that:
- The imports that people want to look at first tend to be at the top (
android
). - The imports that people want to look at least tend to be at the bottom (
java
). - Humans can easily follow the style.
- IDEs can follow the style.
Put static imports above all the other imports ordered the same way as regular imports.
Use spaces for indentation
We use four (4) space indents for blocks and never tabs. When in doubt, be consistent with the surrounding code.
We use eight (8) space indents for line wraps, including function calls and assignments.
Recommended
Instrument i = someLongExpression(that, wouldNotFit, on, one, line);
Not recommended
Instrument i = someLongExpression(that, wouldNotFit, on, one, line);
Follow field naming conventions
- Non-public, non-static field names start with
m
. - Static field names start with
s
. - Other fields start with a lower case letter.
- Public static final fields (constants) are
ALL_CAPS_WITH_UNDERSCORES
.
For example:
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;}
Use standard brace style
Put braces on the same line as the code before them, not on their own line:
class MyClass { int func() { if (something) { // ... } else if (somethingElse) { // ... } else { // ... } }}
We require braces around the statements for a conditional. Exception: If the entire conditional (the condition and the body) fit on one line, you may (but are not obligated to) put it all on one line. For example, this is acceptable:
if (condition) { body();}
and this is acceptable:
if (condition) body();
but this is not acceptable:
if (condition) body(); // bad!
Limit line length
Each line of text in your code should be at most 100 characters long. While much discussion has surrounded this rule, the decision remains that 100 characters is the maximum with the following exceptions:
- Pokud řádek komentáře obsahuje příklad příkazu nebo doslovnou adresu URL delší než 100 znaků, může být tento řádek delší než 100 znaků kvůli snadnému vystřižení a vložení.
- Importní řádky mohou překročit limit, protože je lidé vidí jen zřídka (to také zjednodušuje psaní nástrojů).
Používejte standardní anotace jazyka Java
Anotace by měly předcházet jiným modifikátorům pro stejný jazykový prvek. Jednoduché značkovací anotace (například @Override
) mohou být uvedeny na stejném řádku s jazykovým prvkem. Pokud je anotací více nebo jsou parametrizované, uvádějte je po jedné na řádek v abecedním pořadí.
Standardní postupy systému Android pro tři předdefinované anotace v jazyce Java jsou následující:
- Použijte anotaci
@Deprecated
vždy, když se nedoporučuje použití anotovaného prvku. Pokud použijete anotaci@Deprecated
, musíte mít také značku@deprecated
Javadoc a ta by měla uvádět alternativní implementaci. Kromě toho nezapomeňte, že metoda@Deprecated
má stále fungovat. Pokud vidíte starý kód, který má značku@deprecated
Javadoc, přidejte anotaci@Deprecated
. - Použijte anotaci
@Override
vždy, když metoda přepisuje deklaraci nebo implementaci z nadtřídy. Pokud například použijete značku@inheritdocs
Javadoc a odvozujete z třídy (nikoli z rozhraní), musíte také anotovat, že metoda přepisuje metodu nadřazené třídy. - Anotaci
@SuppressWarnings
používejte pouze za okolností, kdy není možné varování vyloučit. If a warning passes this „impossible to eliminate“ test, the@SuppressWarnings
annotation must be used, to ensure that all warnings reflect actual problems in the code.When a
@SuppressWarnings
annotation is necessary, it must be prefixed with aTODO
comment that explains the „impossible to eliminate“ condition. This normally identifies an offending class that has an awkward interface. Například:// TODO: The third-party class com.third.useful.Utility.rotate() needs generics@SuppressWarnings("generic-cast")List<String> blix = Utility.rotate(blax);
When a
@SuppressWarnings
annotation is required, refactor the code to isolate the software elements where the annotation applies.
Treat acronyms as words
Treat acronyms and abbreviations as words in naming variables, methods, and classes to make names more readable:
Good | Bad |
---|---|
XmlHttpRequest | XMLHTTPRequest |
getCustomerId | getCustomerID |
class Html | class HTML |
String url | String URL |
long id | long ID |
As both the JDK and the Android code bases are inconsistent around acronyms, it’s virtually impossible to be consistent with the surrounding code. Therefore, always treat acronyms as words.
Use TODO
comments for code that is temporary, a short-term solution, or good enough but not perfect. These comments should include the string TODO
in all caps, followed by a colon:
// TODO: Remove this code after the UrlTable2 has been checked in.
a
// TODO: Change this to use a flag instead of a constant.
Pokud je váš TODO
ve tvaru „V budoucnu něco udělejte“, ujistěte se, že jste uvedli buď konkrétní datum („Oprava do listopadu 2005“), nebo konkrétní událost („Odstraňte tento kód poté, co všechny produkční směšovače pochopí protokol V7.“).
Protokolujte střídmě
Protokolování je sice nezbytné, ale má negativní dopad na výkon a ztrácí svou užitečnost, pokud není přiměřeně stručné. Prostředky pro protokolování poskytují pět různých úrovní protokolování:
-
ERROR
: Použije se v případě, že se stalo něco fatálního, tj. něco, co bude mít pro uživatele viditelné následky a nebude to možné obnovit bez smazání některých dat, odinstalování aplikací, vymazání datových oddílů nebo přeflashování celého zařízení (nebo ještě hůře). Tato úroveň je vždy zaznamenána. Problémy, které ospravedlňují určité protokolování na úrovniERROR
, jsou vhodnými kandidáty na hlášení serveru shromažďujícímu statistiky. -
WARNING
: Použijte v případě, že se stalo něco závažného a neočekávaného, tj. něco, co bude mít pro uživatele viditelné následky, ale pravděpodobně to bude možné obnovit bez ztráty dat provedením nějaké explicitní akce, od čekání nebo restartování aplikace až po opětovné stažení nové verze aplikace nebo restartování zařízení. Tato úroveň je vždy zaznamenána. Problémy, které odůvodňují protokolování na úrovniWARNING
, mohou být také zváženy pro hlášení serveru pro shromažďování statistik. -
INFORMATIVE
: Používá se k zaznamenání, že se stalo něco zajímavého, tj. když je zjištěna situace, která může mít široký dopad, ačkoli nemusí nutně jít o chybu. Takový stav by měl zaznamenávat pouze modul, který je přesvědčen, že je v dané doméně nejautoritativnější (aby se zabránilo duplicitnímu zaznamenávání neautoritativními komponentami). Tato úroveň se loguje vždy. -
DEBUG
: Slouží k dalšímu zaznamenávání toho, co se v zařízení děje a co by mohlo být relevantní pro zkoumání a ladění neočekávaného chování. Zaznamenávejte pouze to, co je nutné k získání dostatečného množství informací o tom, co se s komponentou děje. Pokud v logu převažují logy ladění, měli byste použít verbose logování.Tato úroveň se loguje i v sestaveních verze a je nutné ji obklopit blokem
if (LOCAL_LOG)
neboif LOCAL_LOGD)
, kdeLOCAL_LOG
je definován ve vaší třídě nebo dílčí komponentě, takže existuje možnost vypnout veškeré takové logování. V blokuif (LOCAL_LOG)
proto nesmí být žádná aktivní logika. Veškeré sestavení řetězce pro logování musí být také umístěno uvnitř blokuif (LOCAL_LOG)
. Nepřeformulovávejte volání logování na volání metody, pokud to způsobí, že sestavování řetězce bude probíhat mimo blokif (LOCAL_LOG)
.V kódu je stále uvedeno
if (localLOGV)
. I to je považováno za přijatelné, i když název je nestandardní. -
VERBOSE
: Použijte pro vše ostatní. Tato úroveň se zaznamenává pouze při sestaveních pro ladění a měla by být obklopena blokemif (LOCAL_LOGV)
(nebo ekvivalentem), aby mohla být standardně zkompilována. Jakékoli sestavování řetězců je u sestavení pro vydání odstraněno a musí se objevit uvnitř blokuif (LOCAL_LOGV)
.
Poznámky
- V rámci daného modulu, kromě úrovně
VERBOSE
, by měla být chyba hlášena pokud možno pouze jednou. V rámci jednoho řetězce volání funkcí v rámci modulu by měla chybu vracet pouze nejvnitřnější funkce a volající ve stejném modulu by měli přidávat nějaké protokolování pouze tehdy, pokud to výrazně pomůže izolovat problém. - V řetězci modulů, jiném než na úrovni
VERBOSE
, pokud modul nižší úrovně zjistí neplatná data přicházející z modulu vyšší úrovně, měl by modul nižší úrovně tuto situaci logovat pouze doDEBUG
logu, a to pouze v případě, že logování poskytuje informace, které jinak volající nemá k dispozici. Konkrétně není třeba logovat situace, kdy je vyhozena výjimka (výjimka by měla obsahovat všechny relevantní informace) nebo kdy je jediná logovaná informace obsažena v chybovém kódu. To je důležité zejména při interakci mezi frameworkem a aplikacemi a stavy způsobené aplikacemi třetích stran, které jsou správně zpracovány frameworkem, by neměly vyvolat protokolování vyšší než na úrovniDEBUG
. Jediné situace, které by měly spustit protokolování na úrovniINFORMATIVE
nebo vyšší, jsou situace, kdy modul nebo aplikace zjistí chybu na své vlastní úrovni nebo pocházející z nižší úrovně. - Pokud je pravděpodobné, že stav, který by za normálních okolností ospravedlňoval určité protokolování, nastane mnohokrát, může být dobré implementovat nějaký mechanismus omezující rychlost, aby se zabránilo zahlcení protokolů mnoha duplicitními kopiemi stejných (nebo velmi podobných) informací.
- Ztráty síťového připojení jsou považovány za běžné a plně očekávané a neměly by být bezdůvodně zaznamenávány. Ztráta síťového připojení, která má následky v rámci aplikace, by měla být zaznamenána na úrovni
DEBUG
neboVERBOSE
(podle toho, zda jsou následky dostatečně závažné a neočekávané, aby byly zaznamenány v sestavení verze). - Mít plný souborový systém na souborovém systému, který je přístupný aplikacím třetích stran nebo jejich jménem, by nemělo být protokolováno na vyšší úrovni než INFORMATIVNÍ.
- Neplatná data pocházející z jakéhokoli nedůvěryhodného zdroje (včetně jakéhokoli souboru na sdíleném úložišti nebo dat přicházejících přes síťové připojení) jsou považována za očekávaná a neměla by vyvolat žádné protokolování na vyšší úrovni než
DEBUG
, pokud je zjištěno, že jsou neplatná (a i pak by mělo být protokolování co nejomezenější). - Při použití na objektech
String
operátor+
implicitně vytvoří instanciStringBuilder
s výchozí velikostí vyrovnávací paměti (16 znaků) a případně další dočasné objektyString
. Explicitní vytváření objektůStringBuilder
tedy není dražší než spoléhání na výchozí operátor+
(a může být mnohem efektivnější). Mějte na paměti, že kód, který voláLog.v()
, je zkompilován a proveden v sestaveních pro vydání, včetně sestavení řetězců, i když se protokoly nečtou. - Veškeré logy, které mají být čteny jinými lidmi a mají být k dispozici v sestaveních verze, by měly být stručné, aniž by byly kryptické, a měly by být srozumitelné. To zahrnuje veškeré logování až do úrovně
DEBUG
. - Pokud je to možné, udržujte logování na jednom řádku. Délka řádku do 80 nebo 100 znaků je přijatelná. Pokud je to možné, vyhněte se délkám delším než přibližně 130 nebo 160 znaků (včetně délky značky).
- Pokud protokolování hlásí úspěchy, nikdy jej nepoužívejte na vyšších úrovních než
VERBOSE
. - Pokud používáte dočasné protokolování k diagnostice obtížně reprodukovatelného problému, udržujte jej na úrovni
DEBUG
neboVERBOSE
a uzavřete jej bloky if, které umožňují jeho vypnutí při kompilaci. - Dejte si pozor na úniky zabezpečení prostřednictvím protokolu. Vyhněte se protokolování soukromých informací. Zejména se vyhněte logování informací o chráněném obsahu. To je důležité zejména při psaní kódu frameworku, protože není snadné předem vědět, co bude a co nebude soukromou informací nebo chráněným obsahem.
- Nikdy nepoužívejte
System.out.println()
(neboprintf()
pro nativní kód).System.out
aSystem.err
se přesměrují na/dev/null
, takže vaše tiskové příkazy nemají žádný viditelný efekt. Nicméně veškeré sestavování řetězců, ke kterému u těchto volání dochází, se stále provádí. - Zlatým pravidlem protokolování je, že vaše protokoly nesmí zbytečně vytlačovat jiné protokoly z vyrovnávací paměti, stejně jako ostatní nesmí vytlačovat ty vaše.
Pravidla stylu Javatests
Dodržujte konvence pro pojmenování testovacích metod a používejte podtržítko pro oddělení toho, co se testuje, od konkrétního testovaného případu. Tento styl usnadňuje přehled o tom, které případy jsou testovány. For example:
testMethod_specificCase1 testMethod_specificCase2void testIsDistinguishable_protanopia() { ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA) assertFalse(colorMatcher.isDistinguishable(Color.RED, Color.BLACK)) assertTrue(colorMatcher.isDistinguishable(Color.X, Color.Y))}