Java Language
Oracle Official Code Standard
Zoeken…
Invoering
De officiële stijlgids van Oracle voor de Java-programmeertaal is een standaard die wordt gevolgd door ontwikkelaars bij Oracle en wordt aanbevolen om te worden gevolgd door een andere Java-ontwikkelaar. Het omvat bestandsnamen, bestandsorganisatie, inspringen, opmerkingen, verklaringen, verklaringen, witruimte, naamgevingsconventies, programmeermethoden en bevat een codevoorbeeld.
Opmerkingen
De bovenstaande voorbeelden volgen strikt de nieuwe officiële stijlgids van Oracle. Ze zijn met andere woorden niet subjectief verzonnen door de auteurs van deze pagina.
De officiële stijlgids is zorgvuldig geschreven om achterwaarts compatibel te zijn met de originele stijlgids en de meeste code in het wild.
De officiële stijlgids is peer- reviewed door onder andere Brian Goetz (Java Language Architect) en Mark Reinhold (Chief Architect van het Java Platform).
De voorbeelden zijn niet-normatief; Hoewel ze van plan zijn om de juiste manier van formatteren van de code te illustreren, kunnen er andere manieren zijn om de code correct te formatteren. Dit is een algemeen principe: er kunnen verschillende manieren zijn om de code te formatteren, allemaal volgens de officiële richtlijnen.
Naamgevingsconventies
Pakketnamen
- Pakketnamen moeten kleine letters zijn zonder onderstrepingstekens of andere speciale tekens.
- Pakketnamen beginnen met het omgekeerde deel van het webadres van het bedrijf van de ontwikkelaar. Dit deel kan worden gevolgd door een project / programmastructuur afhankelijke pakketonderbouw.
- Gebruik geen meervoudsvorm. Volg de conventie van de standaard API die bijvoorbeeld
java.lang.annotation
en geenjava.lang.annotations
. - Voorbeelden:
com.yourcompany.widget.button
,com.yourcompany.core.api
Klasse-, interface- en enumnamen
- Klasse- en enumnamen moeten doorgaans zelfstandige naamwoorden zijn.
- Interfacenamen moeten meestal zelfstandige naamwoorden of bijvoeglijke naamwoorden zijn die eindigen op ... capabel.
- Gebruik een hoofdletter met de eerste letter van elk woord in hoofdletters (bijv. CamelCase ).
- Overeenkomen met de reguliere expressie
^[AZ][a-zA-Z0-9]*$
. - Gebruik hele woorden en vermijd het gebruik van afkortingen tenzij de afkorting breder wordt gebruikt dan de lange vorm.
- Maak een afkorting op als een woord als deze deel uitmaakt van een langere klassennaam.
- Voorbeelden:
ArrayList
,BigInteger
,ArrayIndexOutOfBoundsException
,Iterable
.
Methodenamen
Methodenamen moeten meestal werkwoorden of andere beschrijvingen van acties zijn
- Ze moeten overeenkomen met de reguliere expressie
^[az][a-zA-Z0-9]*$
. - Gebruik gemengde letters met de eerste letter in kleine letters.
- Voorbeelden:
toString
,hashCode
Variabelen
Variabelenamen moeten in hoofdletters en kleine letters worden geplaatst
- Overeenkomen met de reguliere expressie
^[az][a-zA-Z0-9]*$
- Verdere aanbeveling: variabelen
- Voorbeelden:
elements
,currentIndex
Type variabelen
Gebruik voor eenvoudige gevallen waarbij er maar weinig typevariabelen zijn één hoofdletter.
- Overeenkomen met de reguliere expressie
^[AZ][0-9]?$
- Als de ene letter meer beschrijvend is dan de andere (zoals
K
enV
voor sleutels en waarden in kaarten ofR
voor een functie-retourtype), gebruik dat anders, gebruik andersT
- Gebruik voor complexe gevallen waarin variabelen van het enkele lettertype verwarrend worden langere namen die in hoofdletters zijn geschreven en gebruik een onderstrepingsteken (
_
) om woorden te scheiden. - Voorbeelden:
T
,V
,SRC_VERTEX
constanten
Constanten ( static final
velden waarvan de inhoud onveranderlijk is, door taalregels of volgens conventie) moeten met alle hoofdletters en een onderstrepingsteken ( _
) worden genoemd om woorden te scheiden.
- Overeenkomen met de reguliere expressie
^[AZ][A-Z0-9]*(_[A-Z0-9]+)*$
- Voorbeelden:
BUFFER_SIZE
,MAX_LEVEL
Andere richtlijnen voor naamgeving
- Vermijd methoden voor verbergen / schaduwen, variabelen en typevariabelen in buitenbereiken.
- Laat de verbosity van de naam correleren met de grootte van het bereik. (Gebruik bijvoorbeeld beschrijvende namen voor velden van grote klassen en korte namen voor lokale variabelen van korte duur.)
- Als u openbare statische leden een naam geeft, moet u de identificatie zelf beschrijven als u denkt dat deze statisch zullen worden geïmporteerd.
- Meer informatie: Naming Section (in de officiële Java Style Guide)
Bron: Java Style Guidelines van Oracle
Java-bronbestanden
Alle regels moeten worden afgesloten met een lijnteken (LF, ASCII-waarde 10) en niet bijvoorbeeld CR of CR + LF.
Er is mogelijk geen witruimte aan het einde van een regel.
De naam van een bronbestand moet gelijk zijn aan de naam van de klasse die het bevat, gevolgd door de
.java
extensie, zelfs voor bestanden die alleen een particuliere.java
bevatten. Dit is niet van toepassing op bestanden die geen klasseaangiften bevatten, zoalspackage-info.java
.
Speciale tekens
Afgezien van LF is het enige toegestane witruimteteken Spatie (ASCII-waarde 32). Merk op dat dit impliceert dat andere witruimtetekens (in bijvoorbeeld tekenreeks en lettertekens) moeten worden geschreven in ontsnapte vorm.
\'
,\"
,\\
,\t
,\b
,\r
,\f
en\n
hebben de voorkeur boven overeenkomstige octale (bijv.\047
) of Unicode (bijv.\u0027
)\u0027
.Als het nodig is om tegen de bovenstaande regels in te gaan om te testen, moet de test de vereiste input programmatisch genereren .
Pakket verklaring
package com.example.my.package;
De pakketdeclaratie mag niet in lijn zijn verpakt, ongeacht of deze de aanbevolen maximale lengte van een lijn overschrijdt.
Afschriften importeren
// First java/javax packages
import java.util.ArrayList;
import javax.tools.JavaCompiler;
// Then third party libraries
import com.fasterxml.jackson.annotation.JsonProperty;
// Then project imports
import com.example.my.package.ClassA;
import com.example.my.package.ClassB;
// Then static imports (in the same order as above)
import static java.util.stream.Collectors.toList;
Importafschriften moeten worden gesorteerd ...
- ... voornamelijk door niet-statisch / statisch met eerst niet-statische invoer.
- … In de tweede plaats op basis van de oorsprong van het pakket volgens de volgende volgorde
- java pakketten
- javax pakketten
- externe pakketten (bijv. org.xml)
- interne pakketten (bijv. com.sun)
- … Tertiair per pakket en klasse-ID in lexicografische volgorde
Importinstructies mogen niet in een regel worden ingepakt, ongeacht of deze de aanbevolen maximale lengte van een regel overschrijdt.
Er mag geen ongebruikte invoer aanwezig zijn.
Wildcard invoer
- Wildcard-invoer moet in het algemeen niet worden gebruikt.
- Bij het importeren van een groot aantal nauw verwante klassen (zoals het implementeren van een bezoeker over een boom met tientallen verschillende "knooppuntklassen"), kan een wildcard-import worden gebruikt.
- In elk geval mag niet meer dan één wildcard-import per bestand worden gebruikt.
Klasse structuur
Volgorde van de klasleden
Klasleden moeten als volgt worden besteld:
- Velden (in volgorde van openbaar, beveiligd en privé)
- constructors
- Fabriek methoden
- Andere methoden (in volgorde van openbaar, beschermd en privé)
Het is niet nodig om velden en methoden voornamelijk op basis van hun toegangsmodificator of ID te bestellen.
Hier is een voorbeeld van deze bestelling:
class Example {
private int i;
Example(int i) {
this.i = i;
}
static Example getExample(int i) {
return new Example(i);
}
@Override
public String toString() {
return "An example [" + i + "]";
}
}
Groepering van klasleden
- Gerelateerde velden moeten worden gegroepeerd.
- Een genest type kan vlak voor het eerste gebruik worden verklaard; anders moet het vóór de velden worden aangegeven.
- Constructeurs en overbelaste methoden moeten per functionaliteit worden gegroepeerd en met toenemende ariteit worden geordend. Dit houdt in dat delegatie tussen deze constructen naar beneden stroomt in de code.
- Constructors moeten worden gegroepeerd zonder andere leden ertussen.
- Overbelaste varianten van een methode moeten worden gegroepeerd zonder dat er andere leden tussen zitten.
modifiers
class ExampleClass {
// Access modifiers first (don't do for instance "static public")
public static void main(String[] args) {
System.out.println("Hello World");
}
}
interface ExampleInterface {
// Avoid 'public' and 'abstract' since they are implicit
void sayHello();
}
Modifiers moeten in de volgende volgorde worden geplaatst
- Toegangsmodificator (
public
/private
/protected
) -
abstract
-
static
-
final
-
transient
-
volatile
-
default
-
synchronized
-
native
-
strictfp
- Toegangsmodificator (
Modifiers mogen niet worden weggeschreven als ze impliciet zijn. Interfacemethoden mogen bijvoorbeeld noch
public
nochabstract
worden verklaard en geneste enums en interfaces mogen niet statisch worden verklaard.Methode parameters en lokale variabelen moeten niet
final
worden verklaard, tenzij het de leesbaarheid verbetert of een feitelijke ontwerpbeslissing documenteert.Velden moeten
final
worden verklaard, tenzij er een dwingende reden is om ze te wijzigen.
deuk
- Inspringend niveau is vier spaties .
- Alleen spaties mogen worden gebruikt voor inspringen. Geen tabbladen.
- Lege regels mogen niet worden ingesprongen. (Dit wordt geïmpliceerd door de regel 'geen volgspoor'.)
-
case
zin worden ingesprongen vier ruimten en verklaringen in de zaak moet worden ingesprongen met nog vier ruimten.
switch (var) {
case TWO:
setChoice("two");
break;
case THREE:
setChoice("three");
break;
default:
throw new IllegalArgumentException();
}
Raadpleeg Afwikkelingsverklaringen voor richtlijnen voor het laten inspringen van vervolgregels.
Inpakafschriften
Broncode en opmerkingen mogen in het algemeen niet meer dan 80 tekens per regel bevatten en zelden of nooit meer dan 100 tekens per regel, inclusief inspringen.
De tekenlimiet moet geval per geval worden beoordeeld. Wat echt belangrijk is, is de semantische "dichtheid" en de leesbaarheid van de regel. Door lijnen zinloos lang te maken, zijn ze moeilijk leesbaar; op dezelfde manier kan het maken van "heroïsche pogingen" om ze in 80 kolommen te plaatsen, ze ook moeilijk leesbaar maken. De hier geschetste flexibiliteit is bedoeld om ontwikkelaars in staat te stellen deze uitersten te vermijden, niet om het gebruik van monitor-onroerend goed te maximaliseren.
URL's of voorbeeldopdrachten mogen niet worden ingepakt.
// Ok even though it might exceed max line width when indented.
Error e = isTypeParam
? Errors.InvalidRepeatableAnnotationNotApplicable(targetContainerType, on)
: Errors.InvalidRepeatableAnnotationNotApplicableInContext(targetContainerType));
// Wrapping preferable
String pretty = Stream.of(args)
.map(Argument::prettyPrint)
.collectors(joining(", "));
// Too strict interpretation of max line width. Readability suffers.
Error e = isTypeParam
? Errors.InvalidRepeatableAnnotationNotApplicable(
targetContainerType, on)
: Errors.InvalidRepeatableAnnotationNotApplicableInContext(
targetContainerType);
// Should be wrapped even though it fits within the character limit
String pretty = Stream.of(args).map(Argument::prettyPrint).collectors(joining(", "));
Wikkelen op een hoger syntactisch niveau heeft de voorkeur boven wikkelen op een lager syntactisch niveau.
Er mag maximaal 1 afschrift per regel zijn.
Een vervolglijn moet op een van de volgende vier manieren worden ingesprongen
- Variant 1 : met 8 extra spaties ten opzichte van de inspringing van de vorige regel.
- Variant 2 : met 8 extra spaties ten opzichte van de startkolom van de verpakte uitdrukking.
- Variant 3 : Uitgelijnd met vorige broer of zus-expressie (zolang het duidelijk is dat het een vervolglijn is)
- Variant 4 : uitgelijnd met vorige methodeaanroep in een geketende uitdrukking.
Verpakkingsmethode verklaringen
int someMethod(String aString,
List<Integer> aList,
Map<String, String> aMap,
int anInt,
long aLong,
Set<Number> aSet,
double aDouble) {
…
}
int someMethod(String aString, List<Integer> aList,
Map<String, String> aMap, int anInt, long aLong,
double aDouble, long aLong) {
…
}
int someMethod(String aString,
List<Map<Integer, StringBuffer>> aListOfMaps,
Map<String, String> aMap)
throws IllegalArgumentException {
…
}
int someMethod(String aString, List<Integer> aList,
Map<String, String> aMap, int anInt)
throws IllegalArgumentException {
…
}
- Methode declaraties kunnen worden opgemaakt door de argumenten verticaal te vermelden, of door een nieuwe regel en +8 extra spaties
- Als een worpclausule moet worden ingepakt, plaatst u de regeleinde voor de worpclausule en zorgt u ervoor dat deze uit de argumentlijst komt, door +8 in te laten springen ten opzichte van de functieverklaring of +8 ten opzichte van de vorige regel.
Inpakuitdrukkingen
- Als een lijn de maximale tekenlimiet nadert, overweeg dan altijd om het op te splitsen in meerdere instructies / uitdrukkingen in plaats van de regel in te pakken.
- Pauze voor operators.
- Pauzeer voor de. in chained methodeaanroepen.
popupMsg("Inbox notification: You have "
+ newMsgs + " new messages");
// Don't! Looks like two arguments
popupMsg("Inbox notification: You have " +
newMsgs + " new messages");
Witte ruimte
Verticale witruimte
Een enkele lege regel moet worden gebruikt om ...
- Pakket verklaring
- Klasse verklaringen
- constructors
- methoden
- Statische initializers
- Instance initializers
... en kunnen worden gebruikt om logische groepen van te scheiden
- import verklaringen
- velden
- statements
Meerdere opeenvolgende lege regels mogen alleen worden gebruikt om groepen gerelateerde leden te scheiden en niet als de standaard afstand tussen de leden.
Horizontale witruimte
Er moet één spatie worden gebruikt ...
- Om trefwoorden te scheiden van aangrenzende open of sluitende haakjes en accolades
- Voor en na alle binaire operatoren en operator-achtige symbolen zoals pijlen in lambda-uitdrukkingen en de dubbele punt in verbeterde voor lussen (maar niet vóór de dubbele punt van een label)
- Na
//
begint dat een opmerking. - Na komma's die argumenten scheiden en puntkomma's die de delen van een for-lus scheiden.
- Na de laatste haakjes van een cast.
In variabele declaraties wordt het afgeraden om types en variabelen uit te lijnen.
Variabele verklaringen
- Eén variabele per aangifte (en maximaal één aangifte per regel)
- Vierkante haken van arrays moeten van het type (
String[] args
) zijn en niet van de variabele (String args[]
). - Declareer een lokale variabele vlak voordat deze voor het eerst wordt gebruikt en initialiseer deze zo dicht mogelijk bij de aangifte.
aantekeningen
Aangifte-aantekeningen moeten op een andere regel worden geplaatst dan de aangifte die wordt geannoteerd.
@SuppressWarnings("unchecked")
public T[] toArray(T[] typeHolder) {
...
}
Enkele of korte annotaties die een methode met één regel annoteren, kunnen echter op dezelfde regel worden geplaatst als de methode als deze de leesbaarheid verbetert. Je kunt bijvoorbeeld schrijven:
@Nullable String getName() { return name; }
Voor consistentie en leesbaarheid moeten alle annotaties op dezelfde regel worden geplaatst of moet elke annotatie op een afzonderlijke regel worden geplaatst.
// Bad.
@Deprecated @SafeVarargs
@CustomAnnotation
public final Tuple<T> extend(T... elements) {
...
}
// Even worse.
@Deprecated @SafeVarargs
@CustomAnnotation public final Tuple<T> extend(T... elements) {
...
}
// Good.
@Deprecated
@SafeVarargs
@CustomAnnotation
public final Tuple<T> extend(T... elements) {
...
}
// Good.
@Deprecated @SafeVarargs @CustomAnnotation
public final Tuple<T> extend(T... elements) {
...
}
Lambda-uitdrukkingen
Runnable r = () -> System.out.println("Hello World");
Supplier<String> c = () -> "Hello World";
// Collection::contains is a simple unary method and its behavior is
// clear from the context. A method reference is preferred here.
appendFilter(goodStrings::contains);
// A lambda expression is easier to understand than just tempMap::put in this case
trackTemperature((time, temp) -> tempMap.put(time, temp));
- Expressie-lambdas hebben de voorkeur boven blok-lambdas met één regel.
- Methode-referenties verdienen in het algemeen de voorkeur boven lambda-expressies.
- Voor methodenreferenties met gebonden instantie of methoden met een arity groter dan één, kan een lambda-expressie gemakkelijker te begrijpen zijn en daarom de voorkeur hebben. Vooral als het gedrag van de methode niet duidelijk is uit de context.
- De parametertypen moeten worden weggelaten, tenzij ze de leesbaarheid verbeteren.
- Als een lambda-expressie meer dan een paar regels beslaat, kunt u overwegen een methode te maken.
Overtollige haakjes
return flag ? "yes" : "no";
String cmp = (flag1 != flag2) ? "not equal" : "equal";
// Don't do this
return (flag ? "yes" : "no");
- Redundante groepering haakjes (dwz haakjes die de evaluatie niet beïnvloeden) kunnen worden gebruikt als ze de leesbaarheid verbeteren.
- Overtollige haakjes tussen groepen moeten meestal worden weggelaten in kortere uitdrukkingen met gemeenschappelijke operatoren, maar moeten worden opgenomen in langere uitdrukkingen of uitdrukkingen met operatoren waarvan de prioriteit en associativiteit onduidelijk is zonder haakjes. Ternaire uitdrukkingen met niet-triviale voorwaarden behoren tot de laatste.
- De volledige uitdrukking na een
return
zoekwoord mag worden omgeven door haakjes.
literals
long l = 5432L;
int i = 0x123 + 0xABC;
byte b = 0b1010;
float f1 = 1 / 5432f;
float f2 = 0.123e4f;
double d1 = 1 / 5432d; // or 1 / 5432.0
double d2 = 0x1.3p2;
-
long
letterlijke letters moeten het hoofdletterL
achtervoegsel gebruiken. - Hexadecimale letterlijke letters moeten hoofdletters
A
-F
. - Alle andere numerieke voorvoegsels, infixen en achtervoegsels moeten kleine letters bevatten.
Een beugel
class Example {
void method(boolean error) {
if (error) {
Log.error("Error occurred!");
System.out.println("Error!");
} else { // Use braces since the other block uses braces.
System.out.println("No error");
}
}
}
Openende accolades moeten aan het einde van de huidige regel worden geplaatst in plaats van op een afzonderlijke regel.
Er moet een nieuwe regel voor een afsluitende haak staan, tenzij het blok leeg is (zie Korte formulieren hieronder)
Accolades worden aanbevolen, zelfs wanneer de taal ze optioneel maakt, zoals single-line if- en loop-body's.
- Als een blok meer dan één regel overspant (inclusief opmerkingen), moet het accolades hebben.
- Als een van de blokken in een
if
/else
instructie accolades heeft, moet het andere blok dat ook doen. - Als het blok het laatst komt in een omhullend blok, moet het accolades hebben.
Het sleutelwoord
else
,catch
en hetwhile
indo…while
lussen gaan op dezelfde regel als de sluitende accolade van het voorgaande blok.
Korte vormen
enum Response { YES, NO, MAYBE }
public boolean isReference() { return true; }
De bovenstaande aanbevelingen zijn bedoeld om de uniformiteit te verbeteren (en daarmee de bekendheid / leesbaarheid te vergroten). In sommige gevallen zijn "korte formulieren" die afwijken van de bovenstaande richtlijnen net zo leesbaar en kunnen in plaats daarvan worden gebruikt. Deze gevallen omvatten bijvoorbeeld eenvoudige opsommingsverklaringen en triviale methoden en lambda-uitdrukkingen.