Ricerca…


introduzione

La guida di stile ufficiale di Oracle per Java Programming Language è uno standard seguito dagli sviluppatori di Oracle e consigliato per essere seguito da qualsiasi altro sviluppatore Java. Copre nomi di file, organizzazione di file, indentazione, commenti, dichiarazioni, dichiarazioni, spazi bianchi, convenzioni di denominazione, pratiche di programmazione e include un esempio di codice.

Osservazioni

  • Gli esempi sopra seguono rigorosamente la nuova guida di stile ufficiale di Oracle. In altre parole, non sono inventati in modo soggettivo dagli autori di questa pagina.

  • La guida di stile ufficiale è stata scrupolosamente scritta per essere retrocompatibile con la guida di stile originale e la maggior parte del codice in circolazione.

  • La guida ufficiale stile è stato pari rivisto , tra gli altri, Brian Goetz (Java Architect Language) e Mark Reinhold (Chief Architect del Java Platform).

  • Gli esempi non sono normativi; Mentre intendono illustrare il modo corretto di formattazione del codice, potrebbero esserci altri modi per formattare correttamente il codice. Questo è un principio generale: ci possono essere diversi modi per formattare il codice, tutti aderendo alle linee guida ufficiali.

Convenzioni di denominazione

Nomi dei pacchetti

  • I nomi dei pacchetti devono essere tutti in minuscolo senza caratteri di sottolineatura o altri caratteri speciali.
  • I nomi dei pacchetti iniziano con la parte dell'autorità invertita dell'indirizzo Web della società dello sviluppatore. Questa parte può essere seguita da una sottostruttura del pacchetto dipendente dal progetto / struttura.
  • Non usare la forma plurale. Seguire la convenzione dell'API standard che utilizza ad esempio java.lang.annotation e non java.lang.annotations .
  • Esempi: com.yourcompany.widget.button , com.yourcompany.core.api

Nomi di classe, interfaccia e enum

  • I nomi di classe e enum in genere dovrebbero essere nomi.
  • I nomi delle interfacce dovrebbero in genere essere nomi o aggettivi che terminano con ... in grado.
  • Usa maiuscole e minuscole con la prima lettera di ciascuna parola in maiuscolo (es. CamelCase ).
  • Abbina l'espressione regolare ^[AZ][a-zA-Z0-9]*$ .
  • Usa parole intere ed evita di usare le abbreviazioni a meno che l'abbreviazione non sia più usata della forma lunga.
  • Formatta un'abbreviazione come parola se fa parte di un nome di classe più lungo.
  • Esempi: ArrayList , BigInteger , ArrayIndexOutOfBoundsException , Iterable .

Nomi dei metodi

I nomi dei metodi dovrebbero in genere essere verbi o altre descrizioni di azioni

  • Dovrebbero corrispondere all'espressione regolare ^[az][a-zA-Z0-9]*$ .
  • Usa maiuscole e minuscole con la prima lettera in minuscolo.
  • Esempi: toString , hashCode

variabili

I nomi delle variabili dovrebbero essere in maiuscolo con la prima lettera in minuscolo

  • Abbina l'espressione regolare ^[az][a-zA-Z0-9]*$
  • Ulteriore raccomandazione: variabili
  • Esempi: elements , currentIndex

Digita le variabili

Per i casi semplici in cui ci sono poche variabili di tipo coinvolte usa una sola lettera maiuscola.

  • Abbina l'espressione regolare ^[AZ][0-9]?$
  • Se una lettera è più descrittiva di un'altra (come K e V per le chiavi e i valori nelle mappe o R per un tipo di ritorno di funzione), usa quella, altrimenti usa T
  • Per i casi complessi in cui le variabili di tipo a lettera singola diventano confuse, utilizzare nomi più lunghi scritti in lettere maiuscole e utilizzare il carattere di sottolineatura ( _ ) per separare le parole.
  • Esempi: T , V , SRC_VERTEX

costanti

Le costanti (campi static final cui contenuto è immutabile, per regole linguistiche o per convenzione) devono essere denominati con tutte le lettere maiuscole e il carattere di sottolineatura ( _ ) per separare le parole.

  • Abbina l'espressione regolare ^[AZ][A-Z0-9]*(_[A-Z0-9]+)*$
  • Esempi: BUFFER_SIZE , MAX_LEVEL

Altre linee guida sulla denominazione

  • Evitare metodi di occultamento / ombreggiamento, variabili e variabili di tipo negli ambiti esterni.
  • Lascia che la verbosità del nome sia correlata alla dimensione dell'ambito. (Ad esempio, utilizzare nomi descrittivi per campi di classi grandi e nomi brevi per variabili locali di breve durata.)
  • Quando si nominano membri statici pubblici, lasciare che l'identificatore sia auto-descrittivo se si ritiene che verranno importati staticamente.
  • Ulteriori letture: Naming Section (nella guida ufficiale allo stile Java)

Fonte: linee guida stile Java da Oracle

File di origine Java

  • Tutte le linee devono essere terminate con un carattere di avanzamento riga (LF, valore ASCII 10) e non per esempio CR o CR + LF.

  • Potrebbe non esserci spazio bianco finale alla fine di una riga.

  • Il nome di un file sorgente deve essere uguale al nome della classe che contiene seguito dall'estensione .java , anche per i file che contengono solo una classe privata del pacchetto. Questo non si applica ai file che non contengono dichiarazioni di classe, come package-info.java .

Personaggi speciali

  • Oltre a LF, il solo spazio bianco consentito è Spazio (valore ASCII 32). Nota che ciò implica che altri caratteri di spazio bianco (in, ad esempio, caratteri letterali di stringa e caratteri) devono essere scritti in forma di escape.

  • \' , \" , \\ , \t , \b , \r , \f e \n dovrebbero essere preferiti rispetto ai corrispondenti caratteri ottali (ad esempio \047 ) o Unicode (ad esempio \u0027 ).

  • In caso di necessità di andare contro le regole di cui sopra per motivi di test, il test dovrebbe generare l'input richiesto in modo programmatico.

Dichiarazione del pacchetto

package com.example.my.package;

La dichiarazione del pacchetto non deve essere incentrata sulla linea, indipendentemente dal fatto che superi la lunghezza massima consigliata di una linea.

Importa le dichiarazioni

// 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;
  • Le istruzioni di importazione dovrebbero essere ordinate ...

    • ... principalmente da non statici / statici con importazioni non statiche prima.
    • ... secondariamente dall'origine della confezione in base al seguente ordine
      • pacchetti java
      • pacchetti javax
      • pacchetti esterni (ad es. org.xml)
      • pacchetti interni (es. com.sun)
    • ... terziario per pacchetto e identificatore di classe in ordine lessicografico
  • Le istruzioni di importazione non devono essere allineate alla linea, indipendentemente dal fatto che superi la lunghezza massima consigliata di una linea.

  • Non dovrebbero essere presenti importazioni inutilizzate.

Importazioni con caratteri jolly

  • Le importazioni con caratteri jolly non dovrebbero in generale essere utilizzate.
  • Quando si importa un numero elevato di classi strettamente correlate (come l'implementazione di un visitatore su un albero con dozzine di classi distinte "nodo"), può essere utilizzata un'importazione con caratteri jolly.
  • In ogni caso, non dovrebbe essere utilizzata più di una importazione di caratteri jolly per file.

Struttura di classe

Ordine dei membri della classe

I membri della classe dovrebbero essere ordinati come segue:

  1. Campi (in ordine pubblico, protetto e privato)
  2. Costruttori
  3. Metodi di fabbrica
  4. Altri metodi (in ordine pubblico, protetto e privato)

I campi e i metodi di ordinazione principalmente dai loro modificatori di accesso o identificatore non sono richiesti.

Ecco un esempio di questo ordine:

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 + "]";
    }

}

Raggruppamento di membri della classe

  • I campi correlati dovrebbero essere raggruppati insieme.
  • Un tipo annidato può essere dichiarato subito prima del suo primo utilizzo; altrimenti dovrebbe essere dichiarato prima dei campi.
  • Costruttori e metodi sovraccaricati dovrebbero essere raggruppati per funzionalità e ordinati con crescente arbit. Ciò implica che la delega tra questi costrutti scorre verso il basso nel codice.
  • I costruttori dovrebbero essere raggruppati insieme senza altri membri tra.
  • Le varianti di overload di un metodo dovrebbero essere raggruppate insieme senza altri membri tra.

modificatori

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();
}
  • I modificatori dovrebbero andare nel seguente ordine

    • Modificatore di accesso ( public / private / protected )
    • abstract
    • static
    • final
    • transient
    • volatile
    • default
    • synchronized
    • native
    • strictfp
  • I modificatori non dovrebbero essere scritti quando sono impliciti. Ad esempio, i metodi di interfaccia non devono essere dichiarati publicabstract e le enumerazioni e le interfacce nidificate non devono essere dichiarate statiche.

  • I parametri del metodo e le variabili locali non devono essere dichiarati final meno che non migliorino la leggibilità o documentino una decisione di progettazione effettiva.

  • I campi devono essere dichiarati final meno che non vi sia un valido motivo per renderli mutabili.

dentellatura

  • Il livello di indentazione è di quattro spazi .
  • Solo i caratteri di spazio possono essere usati per il rientro. Nessun tab.
  • Le linee vuote non devono essere rientrate. (Ciò è implicito nella regola dello spazio bianco senza fine).
  • case linee di case devono essere rientrate con quattro spazi e le istruzioni all'interno del caso dovrebbero essere rientrate con altri quattro spazi.
switch (var) {
    case TWO:
        setChoice("two");
        break;
    case THREE:
        setChoice("three");
        break;
    default:
        throw new IllegalArgumentException();
}

Fare riferimento alle istruzioni Wrapping per le linee guida su come indentare le linee di continuazione.

Dichiarazioni di avvolgimento

  • Il codice sorgente e i commenti non dovrebbero in genere superare gli 80 caratteri per riga e raramente se mai superare i 100 caratteri per riga, incluso il rientro.

    Il limite di caratteri deve essere valutato caso per caso. Ciò che conta davvero è la "densità" semantica e la leggibilità della linea. Rendere le linee gratuitamente lunghe le rende difficili da leggere; allo stesso modo, fare "tentativi eroici" per adattarli a 80 colonne può anche renderli difficili da leggere. La flessibilità qui delineata mira a consentire agli sviluppatori di evitare questi estremi, non massimizzare l'uso del monitor immobiliare.

  • URL o comandi di esempio non devono essere incapsulati.

// 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(", "));
  • Il wrapping ad un livello sintattico più alto è preferito rispetto al wrapping ad un livello sintattico più basso.

  • Ci dovrebbe essere al massimo 1 affermazione per riga.

  • Una linea di continuazione dovrebbe rientrare in uno dei quattro modi seguenti

    • Variante 1 : con 8 spazi in più rispetto al rientro della riga precedente.
    • Variante 2 : con 8 spazi aggiuntivi rispetto alla colonna iniziale dell'espressione avvolta.
    • Variante 3 : allineata con la precedente espressione di pari livello (purché sia ​​chiaro che è una linea di continuazione)
    • Variante 4 : allineata alla precedente chiamata di metodo in un'espressione concatenata.

Dichiarazioni sul metodo di avvolgimento

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 {
    …
}
  • Le dichiarazioni dei metodi possono essere formattate elencando gli argomenti verticalmente, oppure con una nuova riga e +8 spazi aggiuntivi
  • Se una clausola throws deve essere avvolta, ponete l'interruzione di riga davanti alla clausola throws e assicuratevi che si distingua dall'elenco degli argomenti, facendo rientrare +8 rispetto alla dichiarazione della funzione, o +8 rispetto alla riga precedente.

Espressioni di avvolgimento

  • Se una linea si avvicina al limite massimo di caratteri, considera sempre di scomporlo in più istruzioni / espressioni invece di avvolgere la linea.
  • Pausa prima degli operatori.
  • Pausa prima del. in chiamate di metodo concatenate.
popupMsg("Inbox notification: You have "
        + newMsgs + " new messages");

// Don't! Looks like two arguments
popupMsg("Inbox notification: You have " +
         newMsgs + " new messages");

Lo spazio bianco

Spazio bianco verticale

  • Una singola riga vuota dovrebbe essere utilizzata per separare ...

    • Dichiarazione del pacchetto
    • Dichiarazioni di classe
    • Costruttori
    • metodi
    • Inizializzatori statici
    • Inizializzatori di istanze
  • ... e può essere usato per separare i gruppi logici di

    • dichiarazioni di importazione
    • i campi
    • dichiarazioni
  • È possibile utilizzare più righe vuote consecutive per separare i gruppi di membri correlati e non come interlinea standard tra i membri.

Spazio bianco orizzontale

  • Un singolo spazio dovrebbe essere usato ...

    • Per separare le parole chiave dalle parentesi graffe o parentesi di apertura o chiusura vicine
    • Prima e dopo tutti gli operatori binari e gli operatori come simboli come le frecce nelle espressioni lambda e i due punti migliorati per cicli (ma non prima dei due punti di un'etichetta)
    • Dopo // inizia un commento.
    • Dopo le virgole che separano gli argomenti e il punto e virgola che separano le parti di un ciclo for.
    • Dopo la parentesi di chiusura di un cast.
  • Nelle dichiarazioni variabili non è consigliabile allineare tipi e variabili.

Dichiarazioni variabili

  • Una variabile per dichiarazione (e al massimo una dichiarazione per riga)
  • Le parentesi quadre degli array dovrebbero essere al tipo ( String[] args ) e non alla variabile ( String args[] ).
  • Dichiarare una variabile locale subito prima che venga utilizzata per la prima volta e inizializzarla il più vicino possibile alla dichiarazione.

annotazioni

Le annotazioni della dichiarazione devono essere riportate su una riga separata dalla dichiarazione che viene annotata.

@SuppressWarnings("unchecked")
public T[] toArray(T[] typeHolder) {
    ...
}

Tuttavia, poche o brevi annotazioni che annotano un metodo a linea singola possono essere messe sulla stessa linea del metodo se migliora la leggibilità. Ad esempio, si può scrivere:

@Nullable String getName() { return name; }

Per una questione di coerenza e leggibilità, tutte le annotazioni dovrebbero essere messe sulla stessa riga o ogni annotazione dovrebbe essere messa su una riga separata.

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

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));
  • I lambda di espressione sono preferiti rispetto ai lambdas a blocco su una riga.
  • I riferimenti al metodo dovrebbero generalmente essere preferiti rispetto alle espressioni lambda.
  • Per i riferimenti al metodo dell'istanza associata, oi metodi con l'arità maggiore di uno, un'espressione lambda può essere più semplice da comprendere e quindi preferibile. Soprattutto se il comportamento del metodo non è chiaro dal contesto.
  • I tipi di parametro dovrebbero essere omessi a meno che non migliorino la leggibilità.
  • Se un'espressione lambda si estende su più di poche righe, prendere in considerazione la creazione di un metodo.

Parentesi ridondanti

return flag ? "yes" : "no";

String cmp = (flag1 != flag2) ? "not equal" : "equal";

// Don't do this
return (flag ? "yes" : "no");
  • Le parentesi di raggruppamento ridondanti (ovvero le parentesi che non influiscono sulla valutazione) possono essere utilizzate se migliorano la leggibilità.
  • Le parentesi di raggruppamento ridondanti dovrebbero in genere essere lasciate in espressioni più brevi che coinvolgono operatori comuni ma incluse in espressioni più lunghe o espressioni che coinvolgono operatori la cui precedenza e associatività non è chiara senza parentesi. Le espressioni ternarie con condizioni non banali appartengono a quest'ultima.
  • L'intera espressione che segue una parola chiave return non deve essere racchiusa tra parentesi.

letterali

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 letterali long dovrebbero usare il suffisso L lettera maiuscola.
  • I letterali esadecimali devono usare lettere maiuscole A - F
  • Tutti gli altri prefissi, infissi e suffissi numerici devono utilizzare lettere minuscole.

Bretelle

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");
        }
    }
}
  • Le parentesi graffe di apertura devono essere posizionate alla fine della riga corrente anziché su una linea di sua proprietà.

  • Dovrebbe esserci una nuova riga davanti a una parentesi graffa di chiusura a meno che il blocco non sia vuoto (vedere i moduli brevi di seguito)

  • Le parentesi graffe sono raccomandate anche laddove la lingua le rende facoltative, come ad esempio i corpi a singola fila e quelli a cappio.

    • Se un blocco si estende su più di una riga (inclusi i commenti), deve contenere parentesi.
    • Se uno dei blocchi in una istruzione if / else ha parentesi graffe, anche l'altro blocco deve esserlo.
    • Se il blocco arriva per ultimo in un blocco che lo racchiude, deve avere le parentesi graffe.
  • La parola chiave else , catch e the while in do…while loop si posiziona sulla stessa riga della parentesi di chiusura del blocco precedente.

Forme brevi

enum Response { YES, NO, MAYBE }
public boolean isReference() { return true; }

Le raccomandazioni di cui sopra hanno lo scopo di migliorare l'uniformità (e quindi aumentare la familiarità / leggibilità). In alcuni casi, le "forme brevi" che si discostano dalle linee guida di cui sopra sono leggibili e possono essere utilizzate al loro posto. Questi casi includono per esempio dichiarazioni enum semplici e metodi banali e espressioni lambda.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow