AOSP Java Code Style for Contributors

De code-stijlen op deze pagina zijn strikte regels voor het bijdragen van Java-code aan het Android Open Source Project (AOSP). Bijdragen aan het Android platform die zich niet aan deze regels houden worden over het algemeen niet geaccepteerd. We erkennen dat niet alle bestaande code deze regels volgt, maar we verwachten dat alle nieuwe code aan deze regels voldoet. Zie Coding with Respect voor voorbeelden van terminologie die je wel en niet moet gebruiken voor een meer inclusief ecosysteem.

Ben consistent

Een van de eenvoudigste regels is BE CONSISTENT. Als je code aan het bewerken bent, neem dan een paar minuten de tijd om naar de omringende code te kijken en de stijl ervan te bepalen. Als die code spaties gebruikt rond de if clausules, zou jij dat ook moeten doen. Als het commentaar in de code sterretjes om zich heen heeft, zorg er dan voor dat jouw commentaar ook sterretjes om zich heen heeft.

Het doel van stijlrichtlijnen is om een gemeenschappelijke codewoordenschat te hebben, zodat lezers zich kunnen concentreren op wat je zegt, in plaats van op hoe je het zegt. We presenteren hier globale stijlregels zodat je de woordenschat kent, maar lokale stijl is ook belangrijk. Als de code die je aan een bestand toevoegt er drastisch anders uitziet dan de bestaande code eromheen, brengt dat lezers uit hun ritme als ze het lezen. Probeer dit te vermijden.

Java taalregels

Android volgt de standaard Java coderingsconventies met de aanvullende regels die hieronder worden beschreven.

Negeer uitzonderingen niet

Het kan verleidelijk zijn om code te schrijven die een uitzondering negeert, zoals:

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

Doe dit niet. Hoewel u misschien denkt dat uw code deze foutconditie nooit zal tegenkomen of dat het niet belangrijk is om deze af te handelen, creëert het negeren van dit soort uitzonderingen mijnen in uw code die iemand anders op een dag kan triggeren. U moet elke uitzondering in uw code op een principiële manier afhandelen; de specifieke afhandeling varieert afhankelijk van het geval.

“Telkens als iemand een lege catch clause heeft, moet hij een griezelig gevoel krijgen. Er zijn beslist momenten dat het juist is, maar je moet er in ieder geval over nadenken. In Java kun je niet ontsnappen aan het griezelige gevoel.” – James Gosling

Acceptabele alternatieven (in volgorde van voorkeur) zijn:

  • Gooi de exception naar de aanroeper van je methode.
     void setServerPort(String value) throws NumberFormatException { serverPort = Integer.parseInt(value); }
  • Gooi een nieuwe exception die geschikt is voor je abstractieniveau.
     void setServerPort(String value) throws ConfigurationException { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { throw new ConfigurationException("Port " + value + " is not valid."); } }
  • Handel de fout sierlijk af en vervang een geschikte waarde in het catch {} blok.
     /** 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 } }
  • Vang de uitzondering op en gooi een nieuwe instantie van RuntimeException. Dit is gevaarlijk, dus doe het alleen als je er zeker van bent dat als deze fout optreedt, het gepast is om te crashen.
     /** 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); } }
  • Als laatste redmiddel, als je er zeker van bent dat het negeren van de exception gepast is, dan mag je het negeren, maar je moet ook commentaar geven waarom met een goede reden.
    /** 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. }}

Vang geen generieke uitzonderingen

Het kan verleidelijk zijn om lui te zijn bij het vangen van uitzonderingen en zoiets als dit te doen:

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

Doe dit niet. In bijna alle gevallen is het ongepast om generieke Exception of Throwable af te vangen (bij voorkeur niet Throwable omdat die Error excepties bevat). Het is gevaarlijk omdat het betekent dat uitzonderingen die je nooit had verwacht (inclusief runtime uitzonderingen zoals ClassCastException) worden opgevangen in de foutafhandeling op app-niveau. Het verdoezelt de foutafhandelingseigenschappen van je code, wat betekent dat als iemand een nieuw type uitzondering toevoegt in de code die je aanroept, de compiler er niet op zal wijzen dat je de fout anders moet afhandelen. In de meeste gevallen zou je verschillende soorten uitzonderingen niet op dezelfde manier moeten afhandelen.

De zeldzame uitzondering op deze regel is test code en top-level code waar je allerlei soorten fouten wilt opvangen (om te voorkomen dat ze in een UI verschijnen, of om een batch job draaiende te houden). In deze gevallen kunt u generieke Exception (of Throwable) vangen en de fout op de juiste manier afhandelen. Denk echter goed na voordat je dit doet, en plaats commentaar waarin je uitlegt waarom het in deze context veilig is.

Alternatieven voor het vangen van generieke uitzonderingen:

  • Vang elke uitzondering apart als onderdeel van een multi-catch blok, bijvoorbeeld:
    try { ...} catch (ClassNotFoundException | NoSuchMethodException e) { ...}
  • Refactor je code om meer fijnmazige foutafhandeling te hebben, met meerdere try-blokken. Splits de IO van het parsen, en handel fouten apart af in beide gevallen.
  • Gooi de uitzondering weg. Vaak hoef je de exception op dit niveau toch niet af te vangen, maar laat je hem gewoon door de methode gooien.

Onthoud dat excepties je vriend zijn! Als de compiler klaagt dat je een exceptie niet afvangt, moet je niet fronsen. Glimlach! De compiler heeft het je net gemakkelijker gemaakt om runtime problemen in je code op te vangen.

Gebruik geen finalizers

Finalizers zijn een manier om een stuk code te laten uitvoeren wanneer een object wordt opgehaald. Hoewel finalizers handig kunnen zijn voor het opruimen (met name van externe bronnen), zijn er geen garanties over wanneer een finalizer zal worden aangeroepen (of zelfs dat hij überhaupt zal worden aangeroepen).

Android maakt geen gebruik van finalizers. In de meeste gevallen kun je in plaats daarvan een goede exception handling gebruiken. 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.*).

Java bibliotheek regels

Er zijn conventies voor het gebruik van Android’s Java bibliotheken en tools. In sommige gevallen is de conventie op belangrijke manieren veranderd en kan oudere code een deprecated patroon of bibliotheek gebruiken. Bij het werken met dergelijke code, is het goed om de bestaande stijl voort te zetten. Als je echter nieuwe componenten maakt, gebruik dan nooit afgeschreven bibliotheken.

Java stijlregels

Elk bestand moet bovenaan een copyright statement hebben, gevolgd door package en import statements (elk blok gescheiden door een lege regel), en tenslotte de class of interface declaratie. Beschrijf in het Javadoc commentaar wat de klasse of interface doet.

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

Elke klasse en niet-triviale publieke methode die u schrijft, moet een Javadoc commentaar bevatten met ten minste één zin die beschrijft wat de klasse of methode doet. Deze zin moet beginnen met een derde persoon beschrijvend werkwoord.

Voorbeelden

/** Returns the correctly rounded positive square root of a double value. */static double sqrt(double a) { ...}

of

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

Je hoeft geen Javadoc te schrijven voor triviale get en set methodes, zoals setFoo() als alles wat je Javadoc zou zeggen is “sets Foo”. Als de methode iets complexers doet (zoals een beperking afdwingen of een belangrijk neveneffect heeft), dan moet je het documenteren. Als het niet duidelijk is wat de eigenschap “Foo” betekent, moet je dat documenteren.

Elke methode die je schrijft, publiek of anderszins, zou baat hebben bij Javadoc. Publieke methoden zijn onderdeel van een API en vereisen daarom Javadoc. Android dwingt geen specifieke stijl af voor het schrijven van Javadoc commentaar, maar je zou de instructies moeten volgen in Hoe schrijf je Doc Commentaar voor de Javadoc Tool.

Schrijf korte methoden

Indien mogelijk, houd methoden klein en doelgericht. We erkennen dat lange methodes soms gepast zijn, dus er is geen harde limiet gesteld aan de lengte van methodes. Als een methode langer is dan een regel of 40, denk er dan over na of hij kan worden opgedeeld zonder de structuur van het programma te schaden.

Definieer velden op standaard plaatsen

Definieer velden ofwel bovenaan het bestand of onmiddellijk voor de methoden die ze gebruiken.

Limit variable scope

Beperk de scope van lokale variabelen tot een minimum. Dit vergroot de leesbaarheid en onderhoudbaarheid van je code en verkleint de kans op fouten. Declareer elke variabele in het binnenste blok dat alle gebruik van de variabele omsluit.

Declareer lokale variabelen op het punt waar ze voor het eerst worden gebruikt. Bijna elke declaratie van een lokale variabele moet een initializer bevatten. Als je nog niet genoeg informatie hebt om een variabele zinvol te initialiseren, stel de declaratie dan uit totdat je dat wel hebt gedaan.

De uitzondering zijn try-catch statements. Als een variabele wordt geïnitialiseerd met de retourwaarde van een methode die een gecontroleerde uitzondering gooit, moet deze binnen een try-blok worden geïnitialiseerd. 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:

  1. Android imports
  2. Imports from third parties (comjunitnetorg)
  3. java and javax

To exactly match the IDE settings, the imports should be:

  • Alfabetisch binnen elke groepering, met hoofdletters voor kleine letters (bijvoorbeeld, Z voor a)
  • Gescheiden door een lege regel tussen elke grote groepering (androidcomjunitnetorgjavajavax)

Oorspronkelijk was er geen stijlvoorschrift voor de volgorde, wat betekende dat IDE’s de volgorde steeds moesten veranderen of dat IDE-ontwikkelaars de functies voor automatisch importbeheer moesten uitschakelen en de imports handmatig moesten bijhouden. Dit werd als slecht beschouwd. Toen naar Java-stijl werd gevraagd, liepen de voorkeursstijlen sterk uiteen en kwam het erop neer dat Android gewoon “een volgorde moest kiezen en consistent moest zijn”. Dus hebben we een stijl gekozen, de stijlgids bijgewerkt, en de IDE’s eraan laten gehoorzamen. We verwachten dat als IDE-gebruikers aan de code werken, imports in alle pakketten aan dit patroon zullen voldoen zonder extra technische inspanning.

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:

  • Als een commentaarregel een voorbeeldcommando of een letterlijke URL bevat die langer is dan 100 tekens, dan mag die regel langer zijn dan 100 tekens voor het gemak van knippen en plakken.
  • Importregels mogen over de limiet gaan omdat mensen ze zelden zien (dit vereenvoudigt ook het schrijven van tools).

Gebruik standaard Java annotaties

Annotaties moeten voorafgaan aan andere modifiers voor hetzelfde taalelement. Eenvoudige marker annotaties (bijvoorbeeld @Override) kunnen op dezelfde regel met het language element worden gezet. Als er meerdere annotaties zijn, of geparametriseerde annotaties, vermeld ze dan één per regel in alfabetische volgorde.

De standaardpraktijken van Android voor de drie voorgedefinieerde annotaties in Java zijn:

  • Gebruik de @Deprecated annotatie wanneer het gebruik van het geannoteerde element wordt ontmoedigd. Als je de @Deprecated annotatie gebruikt, moet je ook een @deprecated Javadoc tag hebben en deze moet een alternatieve implementatie noemen. Bovendien, onthoud dat een @Deprecated methode nog steeds wordt verondersteld te werken. Als u oude code ziet die een @deprecated Javadoc tag heeft, voeg dan de @Deprecated annotatie toe.
  • Gebruik de @Override annotatie wanneer een methode de declaratie of implementatie van een superklasse overschrijft. Bijvoorbeeld, als je de @inheritdocs Javadoc tag gebruikt, en je leidt af van een klasse (niet een interface), moet je ook annoteren dat de methode de methode van de bovenliggende klasse overruled.
  • Gebruik de @SuppressWarnings annotatie alleen onder omstandigheden waarin het onmogelijk is om een waarschuwing te elimineren. 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 a TODO comment that explains the “impossible to eliminate” condition. This normally identifies an offending class that has an awkward interface. Bijvoorbeeld:

    // 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.

en

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

Als uw TODO van de vorm “Doe op een toekomstige datum iets” is, zorg er dan voor dat u ofwel een specifieke datum (“Repareer tegen november 2005”) of een specifieke gebeurtenis (“Verwijder deze code nadat alle productiemixers protocol V7 begrijpen.”) opneemt.

Log spaarzaam

Hoewel loggen noodzakelijk is, heeft het een negatieve invloed op de prestaties en verliest het zijn nut als het niet redelijk beknopt wordt gehouden. De logging-faciliteiten bieden vijf verschillende niveaus van logging:

  • ERROR: Gebruik dit als er iets fataals is gebeurd, dat wil zeggen, iets dat gevolgen heeft die zichtbaar zijn voor de gebruiker en niet kan worden hersteld zonder gegevens te wissen, apps te verwijderen, de gegevenspartities te wissen of het hele apparaat te reflashen (of erger). Dit niveau wordt altijd gelogd. Problemen die logging op het ERROR niveau rechtvaardigen zijn goede kandidaten om aan een statistieken verzamelende server te worden gemeld.
  • WARNING: Te gebruiken wanneer er iets ernstigs en onverwachts is gebeurd, dat wil zeggen, iets dat gevolgen zal hebben die zichtbaar zijn voor de gebruiker, maar dat waarschijnlijk kan worden hersteld zonder gegevensverlies door een of andere expliciete actie uit te voeren, variërend van wachten of opnieuw opstarten van een app tot het opnieuw downloaden van een nieuwe versie van een app of het opnieuw opstarten van het apparaat. Dit niveau wordt altijd gelogd. Problemen die logging op het niveau WARNING rechtvaardigen, kunnen ook worden overwogen voor rapportage aan een server voor het verzamelen van statistieken.
  • INFORMATIVE: Gebruikt om op te merken dat er iets interessants is gebeurd, dat wil zeggen, wanneer een situatie wordt gedetecteerd die waarschijnlijk een wijdverspreide impact heeft, maar niet noodzakelijkerwijs een fout is. Zo’n toestand zou alleen gelogd mogen worden door een module die denkt dat hij de meest gezaghebbende is in dat domein (om dubbele logging door niet-gezaghebbende componenten te vermijden). Dit niveau wordt altijd gelogd.
  • DEBUG: Gebruik dit om verder te noteren wat er op het apparaat gebeurt dat relevant kan zijn om onverwacht gedrag te onderzoeken en te debuggen. Log alleen wat nodig is om voldoende informatie te verzamelen over wat er met uw component gebeurt. Als je debug logs het log overheersen, dan moet je verbose logging gebruiken.

    Dit niveau wordt zelfs op release builds gelogd, en moet worden omgeven door een if (LOCAL_LOG) of if LOCAL_LOGD) blok, waarbij LOCAL_LOG is gedefinieerd in je class of subcomponent, zodat er een mogelijkheid is om al deze logging uit te schakelen. Daarom mag er geen actieve logica in een if (LOCAL_LOG) blok zitten. Alle string building voor de log moet ook binnen het if (LOCAL_LOG) blok geplaatst worden. Refactor de logging-aanroep niet naar een method-aanroep als dat ertoe leidt dat de string building buiten het if (LOCAL_LOG)-blok plaatsvindt.

    Er is code die nog steeds if (localLOGV) zegt. Dit wordt ook acceptabel geacht, hoewel de naam niet standaard is.

  • VERBOSE: Gebruik voor al het andere. Dit niveau wordt alleen gelogd op debug builds en moet worden omgeven door een if (LOCAL_LOGV) blok (of gelijkwaardig) zodat het standaard kan worden uitgecompileerd. Elke string building wordt uit release builds gestript en moet binnen het if (LOCAL_LOGV) blok staan.

Noten

  • Binnen een gegeven module, anders dan op het VERBOSE niveau, zou een fout slechts eenmaal gemeld moeten worden indien mogelijk. Binnen een enkele keten van functie-aanroepen binnen een module moet alleen de binnenste functie de fout teruggeven, en aanroepers in dezelfde module moeten alleen wat logging toevoegen als dat aanzienlijk helpt om het probleem te isoleren.
  • In een keten van modules, anders dan op het niveau VERBOSE, moet een module op een lager niveau, wanneer hij ongeldige gegevens van een module op een hoger niveau ontdekt, deze situatie alleen loggen in de DEBUG log, en alleen als logging informatie oplevert die anders niet beschikbaar is voor de aanroeper. In het bijzonder is het niet nodig om situaties te loggen waarin een uitzondering wordt gegooid (de uitzondering moet alle relevante informatie bevatten), of waarin de enige informatie die wordt gelogd een foutcode is. Dit is vooral belangrijk in de interactie tussen het raamwerk en apps, en omstandigheden veroorzaakt door apps van derden die correct worden afgehandeld door het raamwerk zouden geen logging hoger dan het DEBUG niveau moeten triggeren. De enige situaties die logging moeten triggeren op het INFORMATIVE niveau of hoger is wanneer een module of app een fout detecteert op zijn eigen niveau of afkomstig van een lager niveau.
  • Wanneer een conditie die normaal logging zou rechtvaardigen, waarschijnlijk vele malen zal voorkomen, kan het een goed idee zijn om een rate-limiting mechanisme te implementeren om te voorkomen dat de logs overlopen worden met vele dubbele kopieën van dezelfde (of zeer vergelijkbare) informatie.
  • Verlies van netwerkconnectiviteit wordt als normaal beschouwd en wordt volledig verwacht, en zou niet gratuit gelogd moeten worden. Een verlies van netwerkconnectiviteit dat gevolgen heeft binnen een app moet worden gelogd op het DEBUG of VERBOSE niveau (afhankelijk van of de gevolgen ernstig genoeg en onverwacht genoeg zijn om te worden gelogd in een release build).
  • Het hebben van een volledig bestandssysteem op een bestandssysteem dat toegankelijk is voor of namens apps van derden zou niet moeten worden gelogd op een niveau hoger dan INFORMATIEF.
  • Ongeldige gegevens die afkomstig zijn van een niet-vertrouwde bron (inclusief bestanden op gedeelde opslag, of gegevens die via een netwerkverbinding binnenkomen) worden als verwacht beschouwd en mogen niet leiden tot logging op een hoger niveau dan DEBUG wanneer wordt ontdekt dat ze ongeldig zijn (en zelfs dan moet logging zo beperkt mogelijk zijn).
  • Bij gebruik op String objecten maakt de + operator impliciet een StringBuilder instantie aan met de standaard buffergrootte (16 tekens) en mogelijk andere tijdelijke String objecten. Dus het expliciet maken van StringBuilder objecten is niet duurder dan vertrouwen op de standaard + operator (en kan een stuk efficiënter zijn). Houd in gedachten dat code die Log.v() aanroept, wordt gecompileerd en uitgevoerd op release builds, inclusief het bouwen van de strings, zelfs als de logs niet worden gelezen.
  • Alle logging die bedoeld is om door andere mensen gelezen te worden en beschikbaar te zijn in release builds moet beknopt zijn zonder cryptisch te zijn, en moet begrijpelijk zijn. Dit omvat alle logging tot aan het DEBUG niveau.
  • Indien mogelijk, houd logging op een enkele regel. Regellengtes tot 80 of 100 tekens zijn acceptabel. Vermijd indien mogelijk lengtes langer dan ongeveer 130 of 160 tekens (inclusief de lengte van de tag).
  • Als logging successen rapporteert, gebruik het dan nooit op niveaus hoger dan VERBOSE.
  • Als je tijdelijke logging gebruikt om een moeilijk te reproduceren probleem te diagnosticeren, houd het dan op het DEBUG of VERBOSE niveau en sluit het in met if blokken die het mogelijk maken om het tijdens het compileren uit te schakelen.
  • Wees voorzichtig met veiligheidslekken via de log. Vermijd het loggen van privé informatie. Vermijd in het bijzonder het loggen van informatie over beveiligde inhoud. Dit is vooral belangrijk bij het schrijven van framework code, omdat het niet eenvoudig is om van tevoren te weten wat wel en wat niet privé informatie of beschermde inhoud zal zijn.
  • Gebruik nooit System.out.println() (of printf() voor native code). System.out en System.err worden omgeleid naar /dev/null, dus uw print statements hebben geen zichtbare effecten. Maar alle string building die voor deze aanroepen gebeurt, wordt nog steeds uitgevoerd.
  • De gouden regel van loggen is dat jouw logs andere logs niet onnodig uit de buffer mogen duwen, net zoals anderen die van jou niet uit de buffer mogen duwen.

Javatests stijlregels

Volg de naamgevingsconventies van testmethoden en gebruik een underscore om wat wordt getest te scheiden van de specifieke case die wordt getest. Deze stijl maakt het makkelijker om te zien welke gevallen worden getest. 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))}

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *