Java Language
Oracle Official Code Standard
Sök…
Introduktion
Oracle officiella stilguide för Java Programming Language är en standard följt av utvecklare på Oracle och rekommenderas att följas av någon annan Java-utvecklare. Det täcker filnamn, filorganisation, intryck, kommentarer, förklaringar, uttalanden, vitrum, namnkonventioner, programmeringsmetoder och innehåller ett kodexempel.
Anmärkningar
Exemplen ovan följer strikt den nya officiella stilguiden från Oracle. De är med andra ord inte subjektivt sammansatta av författarna till denna sida.
Den officiella stilguiden har noggrant skrivits för att vara bakåtkompatibel med den ursprungliga stilguiden och majoriteten av koden ute i naturen.
Den officiella stilguide har inbördes granskas av bland andra Brian Goetz (Java Language Architect) och Mark Reinhold (chefsarkitekt för Java Platform).
Exemplen är icke-normativa; Medan de tänker illustrera korrekt sätt att formatera koden kan det finnas andra sätt att korrekt formatera koden. Detta är en allmän princip: Det kan finnas flera sätt att formatera koden, alla följer de officiella riktlinjerna.
Namnkonventioner
Paketnamn
- Paketnamn ska vara små bokstäver utan understreck eller andra specialtecken.
- Paketnamn börjar med den omvända myndighetsdelen av webbadressen för företagets utvecklare. Denna del kan följas av en projekt- / programstrukturberoende paketunderstruktur.
- Använd inte plural form. Följ konventionen om standard API som använder till exempel
java.lang.annotation
och intejava.lang.annotations
. - Exempel:
com.yourcompany.widget.button
,com.yourcompany.core.api
Klass, gränssnitt och enumnamn
- Klass- och enumnamn bör vanligtvis vara substantiv.
- Gränssnittsnamn bör vanligtvis vara substantiv eller adjektiv som slutar med ... kan.
- Använd blandad bokstav med den första bokstaven i varje ord med stora bokstäver (dvs. CamelCase ).
- Matcha det reguljära uttrycket
^[AZ][a-zA-Z0-9]*$
. - Använd hela ord och undvik att använda förkortningar om inte förkortningen används mer än den långa formen.
- Formatera en förkortning som ett ord om det är en del av ett längre klassnamn.
- Exempel:
ArrayList
,BigInteger
,ArrayIndexOutOfBoundsException
,Iterable
.
Metodnamn
Metodnamn bör vanligtvis vara verb eller andra beskrivningar av handlingar
- De bör matcha det reguljära uttrycket
^[az][a-zA-Z0-9]*$
. - Använd blandad bokstav med den första bokstaven med små bokstäver.
- Exempel:
toString
,hashCode
variabler
Variabla namn ska vara i bland med den första bokstaven med små bokstäver
- Matcha det reguljära uttrycket
^[az][a-zA-Z0-9]*$
- Ytterligare rekommendation: Variabler
- Exempel:
elements
,currentIndex
Typvariabler
För enkla fall där det är få typvariabler involverade använder du en enda versaler.
- Matcha det reguljära uttrycket
^[AZ][0-9]?$
- Om en bokstav är mer beskrivande än en annan (som
K
ochV
för nycklar och värden i kartor ellerR
för en funktionstyp), använd annarsT
- För komplexa fall där variabler med enstaka bokstäver blir förvirrande, använd längre namn skrivna i alla stora bokstäver och använd understreck (
_
) för att skilja ord. - Exempel:
T
,V
,SRC_VERTEX
Konstanter anter~~POS=HEADCOMP
Konstanter ( static final
slutfält vars innehåll är oföränderligt, efter språkregler eller konvention) ska namnges med alla stora bokstäver och understruk ( _
) för att skilja ord.
- Matcha det reguljära uttrycket
^[AZ][A-Z0-9]*(_[A-Z0-9]+)*$
- Exempel:
BUFFER_SIZE
,MAX_LEVEL
Andra riktlinjer för namngivning
- Undvik att dölja / skugga metoder, variabler och typvariabler i yttre omfång.
- Låt namnets verbositet korrelera med storleken på omfattningen. (Använd t.ex. beskrivande namn för fält i stora klasser och korta namn för lokala kortvariga variabler.)
- När du namnger offentliga statiska medlemmar, låt identifieraren vara självbeskrivande om du tror att de kommer att importeras statiskt.
- Mer information: Namnsavdelning (i den officiella Java Style Guide)
Källa: Java Style Guidelines från Oracle
Java-källfiler
Alla linjer måste avslutas med en radmatningstecken (LF, ASCII-värde 10) och inte till exempel CR eller CR + LF.
Det kan inte finnas något bakre vitt utrymme i slutet av en linje.
Namnet på en källfil måste vara lika med namnet på klassen som den innehåller följt av
.java
förlängningen, även för filer som endast innehåller en paket privat klass. Detta gäller inte filer som inte innehåller några klassdeklarationer, till exempelpackage-info.java
.
Speciella karaktärer
Förutom LF är det enda tillåtna vitrumstecknet Space (ASCII-värde 32). Observera att detta innebär att andra vitrumstecken (i exempelvis sträng och bokstavstecken) måste skrivas i undviken form.
\'
,\"
,\\
,\t
,\b
,\r
,\f
och\n
bör föredras framför motsvarande oktala (t.ex.\047
) eller Unicode (t.ex.\u0027
)\u0027
tecken.Om det är nödvändigt att strida mot ovanstående regler för testningens skull bör testet generera den erforderliga inmatningen programmatiskt.
Paketdeklaration
package com.example.my.package;
Paketdeklarationen ska inte vara lindad, oavsett om den överskrider den rekommenderade maximala längden på en linje.
Importera uttalanden
// 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;
Importmeddelanden ska sorteras ...
- ... främst genom icke-statisk / statisk med icke-statisk import först.
- ... sekundärt efter paketets ursprung enligt följande ordning
- java-paket
- javax-paket
- externa paket (t.ex. org.xml)
- interna paket (t.ex. com.sun)
- ... högskola per paket och klassidentifierare i leksikografisk ordning
Importmeddelanden ska inte vara lindade, oavsett om de överskrider den rekommenderade maximala längden på en rad.
Ingen oanvänd import ska finnas.
Wildcard-import
- Wildcard-import bör i allmänhet inte användas.
- När du importerar ett stort antal närbesläktade klasser (som att implementera en besökare över ett träd med dussintals distinkta "noder" -klasser), kan en jokertimport användas.
- I alla fall bör inte mer än en jokertimport per fil användas.
Klassstruktur
Klassmedlemmarnas ordning
Klassmedlemmar bör beställas enligt följande:
- Fält (i ordning för offentliga, skyddade och privata)
- konstruktörer
- Fabriksmetoder
- Andra metoder (i ordning för offentliga, skyddade och privata)
Beställning av fält och metoder främst av deras åtkomstmodifierare eller identifierare krävs inte.
Här är ett exempel på denna ordning:
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 + "]";
}
}
Gruppering av klassmedlemmar
- Relaterade fält ska grupperas tillsammans.
- En kapslad typ kan förklaras rätt före dess första användning. annars bör det deklareras före fälten.
- Konstruktörer och överbelastade metoder bör grupperas efter funktionalitet och beställas med ökande arity. Detta innebär att delegering bland dessa konstruktioner flyter nedåt i koden.
- Konstruktörer bör grupperas utan andra medlemmar mellan.
- Överbelastade varianter av en metod bör grupperas utan andra medlemmar mellan.
modifierare
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();
}
Modifierare bör gå i följande ordning
- Åtkomstmodifierare (
public
/private
/protected
) -
abstract
-
static
-
final
-
transient
-
volatile
-
default
-
synchronized
-
native
-
strictfp
- Åtkomstmodifierare (
Ändringar bör inte skrivas ut när de är implicita. Exempelvis bör gränssnittsmetoder varken förklaras
public
ellerabstract
, och kapslade enums och gränssnitt ska inte förklaras statiska.Metodparametrar och lokala variabler bör inte förklaras
final
om det inte förbättrar läsbarheten eller dokumenterar ett faktiskt designbeslut.Fält bör förklaras
final
om det inte finns ett tvingande skäl att göra dem muterbara.
Indrag
- Indikationsnivån är fyra mellanslag .
- Endast mellanslagstecken får användas för indragning. Inga flikar.
- Tomma rader får inte föras in. (Detta antyds av den inget släpande vitrumsregeln.)
-
case
linjer bör vara indragen med fyra platser, och uttalanden inom målet bör vara indragen med ytterligare fyra platser.
switch (var) {
case TWO:
setChoice("two");
break;
case THREE:
setChoice("three");
break;
default:
throw new IllegalArgumentException();
}
Se Uttalanden om inslagning för riktlinjer för hur du kan strecksätta fortsättningslinjer.
Inslagning av uttalanden
Källkod och kommentarer bör i allmänhet inte överstiga 80 tecken per rad och sällan om det någonsin överstiga 100 tecken per rad, inklusive intryck.
Teckengränsen måste bedömas från fall till fall. Det som verkligen är viktigt är den semantiska "densiteten" och linjens läsbarhet. Att göra linjer otillräckligt långa gör dem svåra att läsa; På liknande sätt kan du göra "heroiska försök" för att passa in dem i 80 kolumner också göra dem svåra att läsa. Flexibiliteten som beskrivs här syftar till att möjliggöra för utvecklare att undvika dessa ytterligheter, inte att maximera användningen av bildskärmsfastigheter.
URL: er eller exempelkommandon bör inte lindas.
// 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(", "));
Inpackning på en högre syntaktisk nivå föredras framför inslagning på en lägre syntaktisk nivå.
Det bör vara högst 1 uttalande per rad.
En fortsättningslinje bör indragas på ett av följande fyra sätt
- Variant 1 : Med 8 extra utrymmen i förhållande till indragningen av föregående rad.
- Variant 2 : Med 8 extra mellanslag relativt startkolumnen för det inslagna uttrycket.
- Variant 3 : I linje med tidigare syskonuttryck (så länge det är uppenbart att det är en fortsättningslinje)
- Variant 4 : I linje med tidigare metodsamtal i ett kedjat uttryck.
Förklaringar om omslagsmetod
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 {
…
}
- Metoddeklarationer kan formateras genom att lista argumenten vertikalt, eller med en ny rad och +8 extra mellanslag
- Om en kast-klausul måste lindas, lägg linjeavbrottet framför kast-klausulen och se till att den sticker ut från argumentlistan, antingen genom att indraga +8 i förhållande till funktionsdeklarationen, eller +8 i förhållande till föregående rad.
Inpackning av uttryck
- Om en linje närmar sig den maximala teckengränsen, överväg alltid att dela upp den i flera uttalanden / uttryck istället för att linda in linjen.
- Bryt före operatörerna.
- Bryt före. i kedjade metodsamtal.
popupMsg("Inbox notification: You have "
+ newMsgs + " new messages");
// Don't! Looks like two arguments
popupMsg("Inbox notification: You have " +
newMsgs + " new messages");
mellanslag
Vertikalt vitrum
En enda tom linje bör användas för att separera ...
- Paketdeklaration
- Klassdeklarationer
- konstruktörer
- metoder
- Statiska initialiseringar
- Instansinitierare
... och kan användas för att separera logiska grupper av
- importförklaringar
- fält
- uttalanden
Flera på varandra följande tomma rader bör endast användas för att separera grupper av relaterade medlemmar och inte som standardavstånd mellan medlemmar.
Horisontellt vitrum
Ett enda utrymme bör användas ...
- För att separera nyckelord från närliggande öppnings- eller stängningsfästen och hängslen
- Före och efter alla binära operatörer och operatörer gillar symboler som pilar i lambda-uttryck och kolon i förbättrad för slingor (men inte före kolon på en etikett)
- Efter
//
startar en kommentar. - Efter komma-separering av argument och semikolon som separerar delarna av en för-loop.
- Efter avslutad parentes av en roll.
I variabla deklarationer rekommenderas det inte att anpassa typer och variabler.
Variabla förklaringar
- En variabel per deklaration (och högst en deklaration per rad)
- Fyrkantiga parenteser av matriser bör vara av typen (
String[] args
) och inte på variabeln (String args[]
). - Förklara en lokal variabel direkt innan den först används och initiera den så nära deklarationen som möjligt.
anteckningar
Deklarationsanteckningar bör läggas på en separat rad från deklarationen som antecknas.
@SuppressWarnings("unchecked")
public T[] toArray(T[] typeHolder) {
...
}
Emellertid kan få eller korta kommentarer som kommenterar en enkelradsmetod läggas på samma rad som metoden om det förbättrar läsbarheten. Till exempel kan man skriva:
@Nullable String getName() { return name; }
För en fråga om konsistens och läsbarhet bör antingen alla kommentarer läggas på samma rad eller varje anteckning bör läggas på en separat rad.
// 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-uttryck
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));
- Expression lambdas är att föredra framför single-line block lambdas.
- Metodreferenser bör i allmänhet föredras framför lambda-uttryck.
- För referenser till bundna instansmetoder, eller metoder med större arity än en, kan ett lambda-uttryck vara lättare att förstå och därför föredraget. Särskilt om metodens beteende inte är tydligt ur sammanhanget.
- Parametertyperna bör utelämnas om de inte förbättrar läsbarheten.
- Om ett lambda-uttryck sträcker sig över mer än några få rader, överväg att skapa en metod.
Redundanta parenteser
return flag ? "yes" : "no";
String cmp = (flag1 != flag2) ? "not equal" : "equal";
// Don't do this
return (flag ? "yes" : "no");
- Redundanta gruppering parenteser (dvs. parenteser som inte påverkar utvärderingen) kan användas om de förbättrar läsbarheten.
- Redundanta gruppering av parenteser bör typiskt utelämnas i kortare uttryck som involverar vanliga operatörer men inkluderas i längre uttryck eller uttryck som involverar operatörer vars företräde och associativitet är oklar utan parenteser. Ternära uttryck med icke-triviala förhållanden hör till det senare.
- Hela uttryck efter en
return
sökord får inte omges av parenteser.
litteraler
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
bokstäver bör använda det stora bokstavenL
suffix. - Hexadecimala bokstäver bör använda stora bokstäver
A
-F
- Alla andra numeriska prefix, infix och suffix bör använda små bokstäver.
Tandställning
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");
}
}
}
Öppnande hängslen bör placeras på slutet av den aktuella linjen snarare än på en linje ensam.
Det bör finnas en ny linje framför en stängningsstång om inte blocket är tomt (se korta formulär nedan)
Hängslen rekommenderas även när språket gör dem frivilliga, till exempel om en-linje-if-och-loop-kroppar.
- Om ett block sträcker sig över mer än en rad (inklusive kommentarer) måste det ha hängslen.
- Om ett av blocken i ett
if
/else
uttalande har hängslen måste det andra blocket också. - Om blocket kommer sist i ett slutande block måste det ha hängslen.
Det
else
,catch
ochwhile
nyckelordet ido…while
slingor går på samma linje som stängning av föregående block.
Korta former
enum Response { YES, NO, MAYBE }
public boolean isReference() { return true; }
Ovanstående rekommendationer är avsedda att förbättra enhetligheten (och därmed öka kännedom / läsbarhet). I vissa fall är ”korta former” som avviker från ovanstående riktlinjer lika läsbara och kan användas istället. Dessa fall inkluderar till exempel enkla enumdeklarationer och triviala metoder och lambda-uttryck.