Die Code-Stile auf dieser Seite sind strenge Regeln für das Bereitstellen von Java-Code zum Android Open Source Project (AOSP): Beiträge zur Android-Plattform die diese Regeln nicht einhalten, werden in der Regel nicht akzeptiert. Mi. dass nicht der gesamte vorhandene Code diese Regeln einhält, aber wir erwarten, dass neuen Code konform sein. Siehe Coding mit Respekt finden Sie Beispiele für Terminologie, die Sie für ein inklusiveres Ökosystem verwenden und vermeiden sollten.
<ph type="x-smartling-placeholder">Beständig sein
Eine der einfachsten Regeln lautet: SEIN. Wenn Sie Code bearbeiten,
Minuten, um sich den umgebenden Code anzusehen und seinen Stil zu bestimmen. Wenn das
im Code Leerzeichen um die if
-Klauseln herum gesetzt werden. Das sollten Sie auch tun. Wenn der Code
Die Kommentare sind mit kleinen Sternen gekennzeichnet.
auch kleine Kisten mit Sternen um sie herum.
Der Sinn von Stilrichtlinien ist es, ein gemeinsames Vokabular sodass sich die Leser auf das konzentrieren können, was Sie sagen, wie Sie es sagen. Wir präsentieren hier globale Styleregeln, aber auch der lokale Stil ist wichtig. Wenn der Code, den Sie einer Datei erheblich anders aussieht als der vorhandene Code, der sie umgeben, bringt es die Leser aus dem Rhythmus. Versuchen Sie, vermeiden Sie dies.
Java-Sprachregeln
Android folgt den standardmäßigen Java-Codierungskonventionen mit den zusätzlichen Regeln beschrieben.
Ausnahmen nicht ignorieren
Es kann verlockend sein, Code zu schreiben, der eine Ausnahme ignoriert. Beispiel:
void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { } }
Tun Sie das nicht. Auch wenn Sie vielleicht denken, dass dieser Fehler Fehlerzustand oder einen unwichtigen Umgang damit ist. erstellt eine Ausnahme Minen in Ihrem Code, damit jemand auslösen können. Sie müssen jede Ausnahme in Ihrem Code in einem prinzipiell erfolgen, Die genaue Vorgehensweise variiert je nach Fall.
„Jedes Mal, wenn jemand eine leere Catch-Klausel hat, sollte er eine unheimliche Gefühlslage. Es gibt definitiv Fälle, in denen die URL was zu tun ist, aber zumindest müssen Sie darüber nachdenken. In Java können Sie dem unheimlichen Gefühl zu entfliehen.“ – Jan Gosling
Zulässige Alternativen (in der Reihenfolge ihrer Präferenz) sind:
- Übergeben Sie die Ausnahme an den Aufrufer Ihrer Methode.
void setServerPort(String value) throws NumberFormatException { serverPort = Integer.parseInt(value); }
-
Legen Sie eine neue Ausnahme ab, die Ihrer Abstraktionsebene entspricht.
void setServerPort(String value) throws ConfigurationException { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { throw new ConfigurationException("Port " + value + " is not valid."); } }
-
Behandeln Sie den Fehler ordnungsgemäß und ersetzen Sie den Fehler durch einen entsprechenden Wert in der
catch {}
Block./** 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 } }
-
Ausnahme abfangen und eine neue Instanz von
RuntimeException
auslösen. Das ist gefährlich. Tun Sie es also nur, wenn Sie sich sicher sind, dass tritt ein Absturz auf./** 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); } }
<ph type="x-smartling-placeholder"> -
Wenn Sie sich sicher sind, dass das Ignorieren der Ausnahme
dann ignorieren, sollten Sie aber auch angeben, warum
ist ein guter Grund.
/** 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. } }
Allgemeine Ausnahmen nicht erfassen
Es kann verlockend sein, faul zu sein, etwa so:
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! }
Tun Sie das nicht. In fast allen Fällen ist es unangemessen,
Exception
oder Throwable
(vorzugsweise nicht Throwable
)
weil sie die
Error
Ausnahmen). Es ist gefährlich, weil Ausnahmen
nie erwartet (einschließlich Laufzeitausnahmen wie ClassCastException
)
Fehlerbehandlung
auf App-Ebene. Es verdeckt den Fehler –
die Eigenschaften Ihres Codes verarbeiten, d. h., wenn jemand eine neue
Ausnahme in dem Code, den Sie aufrufen, weist der Compiler nicht darauf hin,
anders behandelt werden müssen. In den meisten Fällen
verschiedene Arten von Ausnahmen nicht auf dieselbe Weise verarbeiten.
Die seltene Ausnahme von dieser Regel sind Testcode und Code auf oberster Ebene,
sollten Sie alle Arten von Fehlern abfangen, damit diese nicht
in einer UI oder zum Aufrechterhalten eines Batchjobs). In diesen Fällen können Sie
generische Exception
(oder Throwable
) und behebe den Fehler entsprechend.
Vorher solltest du allerdings gut überlegen, ob du Kommentare hinterlassen möchtest,
und erklärt, warum es
in diesem Kontext sicher ist.
Alternativen zum Erkennen allgemeiner Ausnahmen:
-
Jede Ausnahme wird separat als Teil eines Blocks mit mehreren Catch erfasst. Beispiel:
try { ... } catch (ClassNotFoundException | NoSuchMethodException e) { ... }
- Refaktorieren Sie Ihren Code für eine genauere Fehlerbehandlung mit mehrere Versuche. E/A vom Parsing aufteilen und Fehler beheben in jedem Fall separat.
- Ausnahme noch einmal auslösen In vielen Fällen müssen Sie den auf dieser Ebene eine Ausnahme machen, lassen Sie sie von der Methode auslösen.
Denk daran, dass Ausnahmen deine Freunde sind! Wenn sich der Compiler darüber beschwert, keine Ausnahme abfangen, schau nicht schaukeln. Bitte lächeln! Der Compiler hat es gerade geschafft und einfacher ist es, Laufzeitprobleme im Code zu erkennen.
Keine Finalisierer verwenden
Finalisierer sind eine Möglichkeit, einen Codeblock auszuführen, wenn ein Objekt für die automatische Speicherbereinigung. Finalisierer können bei der Bereinigung praktisch sein, (insbesondere bei externen Ressourcen) gibt es keine Garantien dafür, wird ein Finalizer aufgerufen (oder sogar überhaupt).
Android verwendet keine Finalisierer. In den meisten Fällen können Sie
eine gute Ausnahmebehandlung. Wenn Sie unbedingt einen Finalizer benötigen,
eine close()
-Methode (oder Ähnliches) definieren und genau dokumentieren,
aufgerufen werden muss (siehe
InputStream. In diesem Fall
ist es angemessen, aber nicht erforderlich, eine kurze Protokollnachricht aus dem
Finalizer verwenden, solange
die Logs nicht überflutet werden.
Importe vollständig qualifizieren
Wenn Sie die Klasse Bar
aus dem Paket foo
verwenden möchten, gibt es zwei
Möglichkeiten für den Import:
import foo.*;
Die Anzahl der Importanweisungen wird möglicherweise reduziert.
import foo.Bar;
Macht deutlich, welche Klassen verwendet werden, und der Code ist eher für Administratoren lesbar sein.
Verwende import foo.Bar;
, um den gesamten Android-Code zu importieren. Eine
eine explizite Ausnahme für Java-Standardbibliotheken (java.util.*
,
java.io.*
usw.) und den Einheitentestcode (junit.framework.*
) enthalten.
Regeln für die Java-Bibliothek
Es gibt Konventionen für die Verwendung der Java-Bibliotheken und -Tools von Android. In In einigen Fällen hat sich die Konvention in wichtigen Bereichen geändert. wird möglicherweise ein verworfenes Muster oder eine verworfene Bibliothek verwendet. Wenn Sie mit solchem Code arbeiten, können Sie den vorhandenen Stil weiterhin verwenden. Beim Erstellen neuer Komponenten verworfene Bibliotheken verwenden Sie jedoch nie.
Java-Stilregeln
Javadoc-Standardkommentare verwenden
Am Anfang jeder Datei sollte eine Erklärung zum Urheberrecht stehen, gefolgt von Paket- und Importanweisungen (jeder Block sind durch eine Leerzeile getrennt) und und schließlich die Deklaration der Klasse oder des Interface. In den Javadoc-Kommentaren beschreiben, was die Klasse oder die Schnittstelle tut.
/* * Copyright yyyy 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 { ... }<ph type="x-smartling-placeholder">
Jede Klasse und nicht triviale öffentliche Methode, die Sie schreiben, muss Folgendes enthalten: Ein Javadoc-Kommentar mit mindestens einem Satz, der beschreibt, was die Klasse oder die Methode tut. Dieser Satz sollte mit einer dritten Person beginnen. beschreibendes Verb.
Beispiele
/** Returns the correctly rounded positive square root of a double value. */ static double sqrt(double a) { ... }
oder
/** * Constructs a new String by converting the specified array of * bytes using the platform's default character encoding. */ public String(byte[] bytes) { ... }
Für einfache get- und Set-Methoden wie
setFoo()
, wenn alle Ihre Javadoc-Informationen „Sets Foo“ lauten. Wenn
Die Methode führt einen komplexeren Vorgang aus, z. B. das Erzwingen einer Einschränkung.
oder einen wichtigen Nebeneffekt hat), müssen Sie dies dokumentieren. Falls nicht,
offensichtlich, was die Eigenschaft „Foo“ sollten Sie es dokumentieren.
Jede Methode, die Sie schreiben, ob öffentlich oder anderweitig, würde von Javadoc profitieren. Öffentliche Methoden sind Teil eines APIs und erfordern daher Javadoc. Android-Geräte erzwingt keinen bestimmten Stil zum Schreiben von Javadoc. Kommentare. Sie sollten jedoch der Anleitung unter Dokumentkommentare für das Javadoc-Tool schreiben folgen.
Kurze Methoden schreiben
Wenn möglich, sollten die Methoden klein und präzise sein. Wir erkennen, dass die lange sind manchmal angemessen, sodass die Methoden Länge. Wenn eine Methode mehr als 40 Zeilen umfasst, überlegen Sie, ohne die Struktur des Programms zu beeinträchtigen.
Felder an standardmäßigen Stellen definieren
Definieren Sie Felder entweder am Anfang der Datei oder unmittelbar vor dem die sie verwenden.
Variablenumfang einschränken
Begrenzen Sie den Umfang lokaler Variablen auf ein Minimum. Dieses erhöht die Lesbarkeit und Verwaltbarkeit Ihres Codes und reduziert die Fehlerwahrscheinlichkeit. Geben Sie jede Variable im innersten -Block, der alle Verwendungen der Variable einschließt.
Deklarieren Sie lokale Variablen an dem Punkt, an dem sie zum ersten Mal verwendet werden. Fast jede lokale Variablendeklaration sollte einen Initialisierer enthalten. Wenn Sie noch nicht genügend Informationen haben, um eine Variable zu initialisieren verschieben Sie die Erklärung, bis Sie es selbst tun.
Die Ausnahme sind Try-Catch-Anweisungen. Wenn eine Variable mit Rückgabewert einer Methode, die eine geprüfte Ausnahme auslöst, in einem „try“-Block initialisiert. Wenn der Wert außerhalb des versuchen, muss er vor dem "try"-Block deklariert werden. noch nicht vernünftig initialisiert werden kann:
// 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));
Sie können dies jedoch sogar vermeiden, indem Sie den -Block in einer Methode:
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));
Schleifenvariablen in der for-Anweisung selbst angeben, es sei denn, gibt es einen überzeugenden Grund, etwas anderes zu tun:
for (int i = 0; i < n; i++) { doSomething(i); }
und
for (Iterator i = c.iterator(); i.hasNext(); ) { doSomethingElse(i.next()); }
Importanweisungen für Bestellungen
Die Reihenfolge der Importanweisungen lautet wie folgt:
- Android-Importe
-
Importe von Drittanbietern (
com
,junit
,net
,org
) -
java
undjavax
Damit die Importe genau mit den IDE-Einstellungen übereinstimmen, sollten sie so aussehen:
- Alphabetisch innerhalb jeder Gruppe, mit Großbuchstaben vor dem Kleinbuchstaben Groß-/Kleinschreibung (z. B. Z vor A)
-
Durch eine Leerzeile zwischen den einzelnen größeren Gruppen getrennt
(
android
,com
,junit
,net
,org
,java
javax
)
Ursprünglich gab es keine Stilanforderung für die Bestellung, d. h. IDEs. entweder ständig die Reihenfolge änderten oder dass IDE-Entwickler die Verwaltungsfunktionen für den automatischen Import deaktivieren und die Importe. Dies wurde als schlecht eingestuft. Als der Java-Stil gefragt wurde, bevorzugte Stile variierten, und Android musste einfach „eine Reihenfolge auswählen und einheitlich sein“. Also haben wir einen Stil, aktualisiert den Styleguide und sorgte dafür, dass die IDEs diesem folgen. Wir erwarten, dass IDE-Nutzer arbeiten am Code, Importe in allen Paketen werden hierüber übereinstimmen ohne zusätzlichen technischen Aufwand.
Wir haben diesen Stil so gewählt:
-
Die Importe, die sich die Nutzer zuerst ansehen möchten, befinden sich
(
android
) -
Die Importe, die man sich zumindest ansehen möchte, befinden sich meist unten
(
java
) - Menschen können dem Stil leicht folgen.
- IDEs können dem Stil folgen.
Platzieren Sie statische Importe vor allen anderen Importen, die genauso sortiert sind wie für regelmäßige Importe.
Leerzeichen für Einrückung verwenden
Wir verwenden vier (4) Leerzeicheneinzüge für Blöcke und niemals Tabulatoren. Im Zweifelsfall mit dem umgebenden Code übereinstimmen.
Wir verwenden acht (8) Leerzeicheneinzüge für Zeilenumbrüche, einschließlich Funktionsaufrufe. und Aufgaben.
Empfohlen
Instrument i = someLongExpression(that, wouldNotFit, on, one, line);
Nicht empfohlen
Instrument i = someLongExpression(that, wouldNotFit, on, one, line);
Namenskonventionen für Felder einhalten
-
Nicht öffentliche, nicht statische Feldnamen beginnen mit
m
. -
Statische Feldnamen beginnen mit
s
. - Andere Felder beginnen mit einem Kleinbuchstaben.
-
Statische letzte Felder (Konstanten, stark unveränderlich) sind
ALL_CAPS_WITH_UNDERSCORES
.
Beispiel:
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; }
Standard-geschweifte Klammer verwenden
Setzen Sie geschweifte Klammern in dieselbe Zeile wie der Code davor und nicht in eine eigene Zeile:
class MyClass { int func() { if (something) { // ... } else if (somethingElse) { // ... } else { // ... } } }
Für eine Bedingung müssen die Anweisungen in geschweifte Klammern gesetzt werden. Ausnahme: Wenn die gesamte Bedingung (die Bedingung und der Körper) auf eine Zeile passt, können (sind aber nicht verpflichtet) alles in einer Zeile zu schreiben. Zum Beispiel ist akzeptabel:
if (condition) { body(); }
Das ist akzeptabel:
if (condition) body();
Dies ist jedoch nicht akzeptabel:
if (condition) body(); // bad!
Zeilenlänge begrenzen
Jede Textzeile in Ihrem Code darf höchstens 100 Zeichen lang sein. Diese Regel wurde zwar intensiv diskutiert, doch die Entscheidung bleibt noch bestehen. dass 100 Zeichen die maximale Zeichen enthalten, wobei folgende Ausnahmen:
- Wenn eine Kommentarzeile einen Beispielbefehl oder eine längere Literal-URL enthält mehr als 100 Zeichen enthält, kann diese Zeile für ausschneiden und einfügen lassen.
- Bei Importzeilen kann der Grenzwert überschritten werden, da sie nur selten von Menschen gesehen werden (Das vereinfacht auch das Schreiben in Tools.)
Java-Standardannotationen verwenden
Anmerkungen sollten anderen Modifikatoren für dieselbe Sprache vorangestellt werden.
-Elements. Anmerkungen zu einfachen Markierungen (z. B. @Override
) können auf der
in derselben Zeile wie das Language Element. Wenn es mehrere Anmerkungen gibt,
oder parametrisierten Anmerkungen
eine Zeile pro Zeile in
alphabetisch sortiert.
Android-Standardpraktiken für die drei vordefinierten Annotationen in Java sind:
-
Annotation
@Deprecated
verwenden immer dann, wenn von der Verwendung des annotierten Elements abgeraten wird. Wenn Sie die Annotation@Deprecated
enthält, benötigen Sie auch eine@deprecated
Javadoc und sollte eine alternative Implementierung nennen. Außerdem denken Sie daran, dass die Methode@Deprecated
weiterhin funktionieren sollte. Wenn Sie alten Code mit einem@deprecated
-Javadoc-Tag sehen, fügen Sie den@Deprecated
-Anmerkung. -
Verwenden Sie die Anmerkung
@Override
immer dann, überschreibt eine -Methode die Deklaration oder Implementierung aus einem zur Basisklasse abgerufen werden. Wenn Sie beispielsweise das Javadoc-Tag@inheritdocs
verwenden und von einer Klasse (und nicht von einer Schnittstelle) abgeleitet werden, müssen Sie auch annotieren, Die Methode überschreibt die Methode der übergeordneten Klasse. -
Annotation
@SuppressWarnings
verwenden wenn es unmöglich ist, eliminieren Sie eine Warnung. Wenn in einer Warnung die Meldung beseitigen“ Test, muss die Annotation@SuppressWarnings
so aussehen: So stellen Sie sicher, dass alle Warnungen die tatsächlichen Probleme Code.Wenn eine
@SuppressWarnings
-Annotation erforderlich ist, mit dem PräfixTODO
, in dem erklärt wird, beseitigen“ . Dies kennzeichnet normalerweise eine anstößige Klasse mit einer umständlichen Oberfläche. Beispiel:// TODO: The third-party class com.third.useful.Utility.rotate() needs generics @SuppressWarnings("generic-cast") List<String> blix = Utility.rotate(blax);
Wenn eine
@SuppressWarnings
-Annotation erforderlich ist, refaktorieren Sie den Code um die Softwareelemente zu isolieren, gilt.
Akronymen wie Wörter behandeln
Behandeln Sie Akronyme und Abkürzungen wie Wörter, um Variablen, Methoden, und Klassen, um Namen besser lesbar zu machen:
Gut | Schlecht |
---|---|
XmlHttpRequest | XMLHTTPRequest |
getCustomerId | getCustomerID |
Klasse "HTML" | Klasse HTML |
String-URL | String-URL |
lange ID | lange ID |
Da sowohl das JDK als auch die Android-Codebasis ist es praktisch unmöglich, konsistent mit den Begriffen umgebenden Code. Behandeln Sie Akronyme daher immer als Wörter.
TODO-Kommentare verwenden
Verwenden Sie TODO
-Kommentare für temporären Code, kurzfristige Lösung oder
gut genug, aber nicht perfekt. Diese Kommentare sollten die Zeichenfolge TODO
in allen
Großbuchstaben gefolgt von einem Doppelpunkt:
// TODO: Remove this code after the UrlTable2 has been checked in.
und
// TODO: Change this to use a flag instead of a constant.
Wenn deine TODO
das Format „Zu einem späteren Datum unternehmen“ hat sicherstellen
dass Sie entweder ein bestimmtes Datum angeben ("Beheben bis November 2005") oder
ein bestimmtes Ereignis („Diesen Code nach allen Produktionsmixern entfernen“
Protokoll V7 verstehen“).
Nur sparsam protokollieren
Das Logging ist zwar notwendig, wirkt sich aber negativ und verliert ihren Nutzen, wenn sie nicht angemessen terse. Die Logging-Funktionen bieten fünf verschiedene Logging-Ebenen:
-
ERROR
: Verwenden Sie diese Option, wenn etwas schwerwiegendes passiert ist, z. B. für den Nutzer sichtbare Folgen haben, die nicht wiederhergestellt werden können, ohne Daten zu löschen, Apps zu deinstallieren Löschen der Datenpartitionen oder Zurücksetzen des gesamten Geräts (oder Schlimmeres) Diese Ebene wird immer protokolliert. Probleme, die eine Protokollierung rechtfertigen,ERROR
-Stufe sind gute Kandidaten für eine Meldung an einen Server für die Erfassung von Statistiken. -
WARNING
: Verwenden Sie diese Option, wenn etwas Ernstes und Unerwartetes vorliegen. d. h. etwas mit für den Nutzer sichtbaren Konsequenzen, ist wahrscheinlich ohne Datenverlust wiederherstellbar, z. B. durch Warten oder Neustarten einer App zum erneuten Herunterladen einer neuen App-Version . Diese Ebene wird immer protokolliert. Probleme, die eine Protokollierung rechtfertigen aufWARNING
-Ebene kann auch für die Berichterstellung an einen Server für die Erfassung von Statistiken. -
INFORMATIVE
: Damit kannst du auf etwas Interessantes hinweisen. d. h. wenn eine Situation erkannt wird, weitreichende Auswirkungen haben, ist aber nicht unbedingt ein Fehler. So eine nur von einem Modul protokolliert werden, dass sie die maßgeblichste in dieser Domain ist (um doppelte Protokollierung durch nichtautoritative Komponenten). Diese Ebene wird immer protokolliert. -
DEBUG
: Hiermit können Sie verdeutlichen, was auf dem Gerät, das für die Untersuchung und Fehlerbehebung relevant sein könnte Verhaltensweisen. Nur die Daten protokollieren, die für eine ausreichende Menge an Daten erforderlich sind Informationen zu Ihrer Komponente erhalten. Wenn Sie zur Fehlerbehebung dominiert das Log, sollten Sie die ausführliche Logging.Diese Stufe wird auch bei Release-Builds protokolliert und ist erforderlich wird von einem
if (LOCAL_LOG)
- oderif LOCAL_LOGD)
-Block umgeben, wobeiLOCAL_LOG[D]
definiert ist in Ihrer Klasse oder Unterkomponente, sodass die Möglichkeit besteht, , um das gesamte Logging zu deaktivieren. Daher darf keine aktive Logik vorhanden sein, in einemif (LOCAL_LOG)
-Block. Die gesamte Zeichenfolgenerstellung für muss das Protokoll auch imif (LOCAL_LOG)
Block. Logging-Aufruf nicht refaktorieren in einen Methodenaufruf integriert, wenn dies dazu führt, der Zeichenfolgenerstellung außerhalb desif (LOCAL_LOG)
Block.Sie sehen Code, der immer noch
if (localLOGV)
lautet. Dieses wird ebenfalls als zulässig angesehen, obwohl der Name nicht normgerecht ist. -
VERBOSE
: Für alles andere verwenden. Diese Stufe ist nur in Debug-Builds protokolliert und sollte von einemif (LOCAL_LOGV)
-Block (oder Äquivalent), damit er kompiliert werden. Alle Schlangenbausteine werden aus veröffentlicht und muss imif (LOCAL_LOGV)
Block.
Hinweise
-
Innerhalb eines bestimmten Moduls, außer auf der Ebene
VERBOSE
, wird ein Fehler sollte nach Möglichkeit nur einmal gemeldet werden. Innerhalb einer Kette von innerhalb eines Moduls aufgerufen werden, sollte nur die innerste Funktion den Fehler zurückgeben. Aufrufer im selben Modul sollten Protokollierung, wenn das zur Isolierung des Problems beiträgt. -
Wenn in einer Kette von Modulen, außer auf der Ebene
VERBOSE
, ein untergeordnetes Modul erkennt ungültige Daten, die von einem sollte das untergeordnete Modul diese Situation nur imDEBUG
und nur dann, wenn das Logging Informationen liefert, die nicht für den Anrufer verfügbar sind. Insbesondere ist es nicht notwendig, in denen eine Ausnahme ausgelöst wird (die Ausnahme sollte alle relevanten Informationen enthalten) oder wenn die einzigen Informationen in einem Fehlercode enthalten. Das ist besonders in der Interaktion zwischen Framework und Apps wichtig. durch Drittanbieter-Apps verursacht, die ordnungsgemäß das vom Framework verarbeitete Logging nicht höher als der WertDEBUG
Level. Die Protokollierung sollte nurINFORMATIVE
oder höher liegt vor, wenn ein Modul oder eine App Folgendes erkennt: Fehler auf seiner eigenen Ebene oder auf einer niedrigeren Ebene. - Wenn eine Bedingung, die normalerweise ein gewisses Logging rechtfertigen würde, wahrscheinlich ist häufig auftreten, kann es eine gute Idee sein, einige um das Überlaufen der Logs mit vielen Duplikate derselben (oder sehr ähnlichen) Informationen.
-
Verluste der Netzwerkkonnektivität werden als weitverbreitet und vollständig
und sollten nicht
grundlos protokolliert werden. Ausfall des Netzwerks
Konnektivität, die Auswirkungen innerhalb einer App hat, sollte unter
DEBUG
- oderVERBOSE
-Level, je nachdem, schwerwiegenden und unerwarteten Ereignisse drohen, um in einem Release Build). - Ein vollständiges Dateisystem in einem Dateisystem, auf das oder auf dem für Drittanbieter-Apps auf Ebene des als INFORMATIVE.
-
Ungültige Daten aus nicht vertrauenswürdigen Quellen (einschließlich Dateien auf
freigegebenen Speicher oder Daten, die über ein Netzwerk eingehen,
Verbindung) als erwartet angesehen wird und keine
wird auf einer höheren Ebene als
DEBUG
protokolliert, ungültig (und selbst dann sollte die Protokollierung so begrenzt wie möglich sein). -
Bei Verwendung für
String
-Objekte kann der+
-Operator implizit erstellt eineStringBuilder
-Instanz mit der Standardeinstellung Puffergröße (16 Zeichen) und möglicherweise andere temporäreString
Objekte. Das explizite Erstellen vonStringBuilder
-Objekten ist teurer als der Standard-+
-Operator (und kann effizienter). Denken Sie daran, dass Code, derLog.v()
wird für Release-Builds kompiliert und ausgeführt. auch wenn die Protokolle nicht gelesen werden. -
Protokollieren, die von anderen gelesen und
die in Release-Builds verfügbar sind,
und verständlich sein. Dies schließt die gesamte Protokollierung mit ein
bis zum
DEBUG
-Level. - Protokollieren Sie nach Möglichkeit immer in einer einzigen Zeile. Es werden Zeilen mit bis zu 80 oder 100 Zeichen akzeptabel. Vermeiden Sie Längen von mehr als 130 oder 160 Zeichen (einschließlich der Länge des Tags) nach Möglichkeit.
-
Wenn die Protokollierung erfolgreich ist, verwenden Sie sie nie auf höheren Ebenen
als
VERBOSE
. -
Wenn Sie die temporäre Protokollierung nutzen, um ein Problem zu diagnostizieren, das schwer zu erkennen ist
auf der
DEBUG
- oderVERBOSE
-Ebene halten und einschließen, mit if-Blöcken, die eine Deaktivierung zu der Kompilierungszeit. - Seien Sie vorsichtig bei Sicherheitslücken im Protokoll. Privates Logging vermeiden Informationen. Achten Sie vor allem darauf, dass Informationen über geschützte Inhalte nicht protokolliert werden. Das ist besonders wichtig, Framework-Code zu schreiben, da es nicht leicht ist, im Voraus zu wissen, und enthalten keine privaten Informationen oder geschützten Inhalte.
-
Verwenden Sie niemals
System.out.println()
(oderprintf()
für nativen Code).System.out
undSystem.err
erhalten an/dev/null
weitergeleitet, sodass Ihre Druckauszüge keine sichtbaren Effekten. Die gesamte Zeichenfolgenerstellung für werden diese Aufrufe trotzdem ausgeführt. - Die goldene Regel beim Logging besagt, dass Logs unnötigerweise andere Logs aus dem Zwischenspeicher schieben, nicht herausfordern.
Stilregeln für Javatests
Halten Sie sich an die Benennungskonventionen für Testmethoden und verwenden Sie zum Trennen was mit dem jeweils getesteten Fall getestet wird. Dieser Stil sorgt dafür, leichter erkennen, welche Fälle getestet werden. Beispiel:
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)) }