Ho un problema con i bit di flag. Ho una variabile int
per contenere i flag. Per prima cosa ho impostato alcuni flag su quella variabile. Successivamente ho bisogno di controllare quanti flag sono stati impostati in quella variabile. Ma non so farlo.
Per verificare se è impostato un valore bit:
int value = VALUE_TO_CHECK | OTHER_VALUE_TO_CHECK; if ((value & VALUE_TO_CHECK) == VALUE_TO_CHECK) { // do something--it was set } if ((value & OTHER_VALUE_TO_CHECK) == OTHER_VALUE_TO_CHECK) { // also set (if it gets in here, then it was defined in // value, but it does not guarantee that it was set with // OR without other values. To guarantee it's only this // value just use == without bitwise logic) }
È importante notare che non si dovrebbe avere un valore di controllo come 0 a meno che non rappresenti Tutto o Nessuno (e non usare la logica bit per bit per confrontare, basta usare il value == 0
) perché qualsiasi value & 0
è SEMPRE 0.
Inoltre, considerare l’utilizzo di un EnumSet
invece dei campi bit. Vedi anche Bloch, punto 32 .
Addendum: come esempio concreto:
I set Enum forniscono anche una sostituzione ricca e sicura per bit tradizionali:
EnumSet.of(Style.BOLD, Style.ITALIC);
Si noti in particolare i metodi convenienti ereditati da AbstractSet
e AbstractCollection
.
Se vuoi controllare se a
ha tutti i bit di flag in b
set, puoi controllarlo come:
(a & b) == b
Sto usando il seguente:
public class BitFlags { public static boolean isFlagSet(byte value, byte flags) { return (flags & value) == value; } public static byte setFlag(byte value, byte flags) { return (byte) (flags | value); } public static byte unsetFlag(byte value, byte flags) { return (byte) (flags & ~value); } }
Tuttavia, se non ne hai bisogno “a basso livello”, si consiglia di utilizzare EnumSets
invece per il beneficio aggiuntivo di sicurezza del tipo.