2011-05-20 21 views
8

¿Cuál es la mejor práctica para especificar indicadores en un método Java?Práctica recomendada para usar indicadores en el método Java

que he visto SWT usando int como campos de bits, como:

(ejemplo parcialmente de "Effective Java, 2ª Ed.", Página 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) { 

    } 
} 

y su llamada del cliente se ve como:

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

..pero esto se desanima que pueda banderas mixtos (valores int) de diferentes clases juntos sin ninguna comprobación de compilador.

En el mismo libro ("Effective Java"), veo el uso de EnumSet, pero entonces su llamada del usuario se convierte en:

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

Me parece un poco prolijo y prefiero la elegancia de SWT.

¿Hay alguna otra alternativa o es básicamente los dos gustos que debe elegir?

+2

Creo que te refieres a 'STYLE_ITALIC = 1 << 1'. –

+4

@Victor ¡Creo que es una gran demostración de un problema común con el enfoque de campo de bits! – Anonymoose

+0

Sí, de hecho lo es. :) –

Respuesta

7

Supongo que ha chocado contra una pared. No veo ninguna otra opción. Java es detallado, eso es un hecho. En situaciones como esta, generalmente agrego una variable local para hacer que el código sea más legible. Usted puede hacer esto,

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

Si desea indicadores de estilo de bits, Java los envuelve en un BitSet. Ha existido por siglos, sin embargo, pocas personas se molestan en usarlo (prefiriendo incrustar el manejo del bit de estilo C en ints).

The api for BitSet can be found here.

Junto con unas pocas entradas estáticas bien elegidas, funciona bastante bien hasta que empiezas a verificar y configurar múltiples bits en una sola pasada.

+0

Sí, he usado BitSet para banderas en el examen final de una de mis clases el último semestre. Era una solución elegante que ningún otro estudiante usó y mi profesor realmente me gustó. :) Animo a las personas a utilizar BitSet más, no parece que se use mucho. – RestInPeace

2

Aconsejo que vaya con el enfoque EnumSet.

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

Este enfoque proporciona una mejor seguridad de tipos, y Style ser un enum tendrá capacidades OO en toda regla.

1

Última respuesta para quien se encuentre con esto.Esta es una manera de hacerlo para reducir la memoria y tener un buen enumeración como 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; 
    } 
} 

método:

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

llamada:

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

¿Cómo reduce esto la memoria? – Eliezer

0

Si sólo dispone de un número limitado de los métodos que tomarán un conjunto de estilos (como printText, en su ejemplo), puede ajustar su firma para tomar un número variable de parámetros de estilo:

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

Y entonces sus llamadas están muy cerca de la sin tipo (int) de la bandera de rutas:

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

Lamentablemente, no hay EnumSet.of(E...) fábrica, simplemente EnumSet.of(E first, E... more), por lo que tendrá un método genérico para dividir logicalOr tu matriz en primeros pedazos de descanso. Izquierda como ejercicio para el lector =).

Cuestiones relacionadas