Domanda

Qual è la migliore pratica per specificare le bandiere in un metodo Java?

Ho visto SWT usando int come bitfields, come:

(esempio parzialmente da "Java efficace, 2nd ed." Pagina 159):

public class Text {
  public static final int STYLE_BOLD = 1 << 0; // 1
  public static final int STYLE_ITALIC = 1 << 1; // 2

  void printText(String text, int flags) {

  }
}
.

E la tua chiamata del cliente sembra:

printText("hello", Text.STYLE_BOLD | Text.STYLE_ITALIC);
.

.. Ma questo è scoraggiato come puoi miscelare flags (appt valori) da diverse classi insieme senza alcun controllo del compilatore.

Nello stesso libro ("Efficace Java"), vedo l'uso di Enumset, ma quindi la chiamata utente diventa:

printText("hello", EnumSet.of(Style.Bold, Style.ITALIC));
.

Trovo che questo un po 'verboso e preferisco l'eleganza del SWT.

C'è qualche altra alternativa o questo è fondamentalmente i due gusti che devi scegliere?

È stato utile?

Soluzione

Indovina che hai colpito un muro.Non vedo nessun'altra opzione.Java è verboso questo è un dato di fatto.In situazioni come questa aggiungo di solito una variabile locale per rendere il codice più leggibile.Puoi farlo,

EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.ITALIC);
printText("hello", styles);
.

Altri suggerimenti

Se si desidera bandiere di stile bit, Java li avvolge in un BitSet.È stato in giro per le età, eppure poche persone si preoccupano di usarlo (preferendo l'incorporamento della movimentazione di bit di stile C in interni).

L'API per BitSet può essere trovato qui .

Accoppiato con alcuni intercetti statici ben scelti, fa abbastanza bene finché non inizi a controllare e impostare più bit in un passaggio.

Consiglio di andare con l'approccio EnumSet.

EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.Italic);
.

Questo approccio fornisce una migliore sicurezza di tipo e Style che è un enum avrà funzionalità OO a pieno titolo.

Risposta tardiva per chiunque abbia incontrato questo.Ecco un modo per farlo per ridurre la memoria e avere un bello enum come API:

public static class MyFlag {

    public static final MyFlag A = new MyFlag(1<<0);
    public static final MyFlag B = new MyFlag(1<<1);
    public static final MyFlag C = new MyFlag(1<<2);
    public static final MyFlag ALL = A.and(B).and(C);

    private final int flag;

    private MyFlag(int flag){
        this.flag = flag;
    }

    public MyFlag and(MyFlag limit){
        return new MyFlag(flag & limit.flag);
    }

    public MyFlag not(MyFlag limit){
        return new MyFlag(flag | ~limit.flag);
    }

    public boolean isSet(MyFlag limit){
        if(limit ==null){
            return false;
        }
        return (this.flag & limit.flag) != 0;
    }
}
.

Metodo:

public void doFoo(MyFlag flag){
   if(MyFlag.A.isSet(flag)){
   ....
   }
   if(MyFlag.C.isSet(flag)){
   ....
   }
}
.

Chiamata:

x.doFoo(MyFlag.A.and(MyFlag.C));
.

Se hai solo un numero limitato di metodi che prenderanno un set di stili (come printText, nel tuo esempio), puoi modificare la propria firma per scattare un numero variabile di parametri di stile:

void printText(String text, Style... flags) {
  EnumSet<Style> style = logicalOr(flags); // see comment below
  ...
 }
.

E poi le tue chiamate sono molto vicine alla rotta non adulate (int) flag:

printText("hello", Style.BOLD, Style.ITALIC);
.

Purtroppo, non esiste una fabbrica di EnumSet.of(E... ), solo EnumSet.of(E first, E... more), quindi avrai bisogno di un metodo Generico logicalOr per dividere il tuo array nei primi pezzi di riposo. a sinistra come esercizio al lettore=) .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top