2013-01-20 51 views
2

我正在使用位標誌從一個字節讀取用戶提供的選項。我想檢查該字節是否包含任何無效/未知標誌值。測試無效位標誌

至今我所編寫的快速測試代碼如下所示:

public class Test { 
    static byte flag1 = 0x01; 
    static byte flag2 = 0x02; 
    static byte flag3 = 0x04; 

    public static void main(String[] args) { 
    byte invalidFlags = 0x0F; 
    byte goodFlags = (byte) (flag1 | flag2); 

    System.out.println(flagsAreOK(invalidFlags)); 
    System.out.println(flagsAreOK(goodFlags)); 

    // prints: 
    // 
    // false 
    // true 
    } 

    private static boolean flagsAreOK(byte value) { 
    byte allFlags = (byte) (flag1 | flag2 | flag3); 
    byte badFlags = (byte) ~allFlags; 

    return ((value & badFlags) == 0); 
    } 
} 

這似乎工作確定。然而,有誰知道:

  • 一個更好的方法來做到這一點?無論如何,我都不是一個操縱專家的人。

  • 處理標誌操作的現有庫?我已經從Apache Commons Lang找到BitField,但是已經有一個抱怨impossible the JavaDocs are to read的錯誤。

+1

您的標誌是否代表一組常量。如果是這樣,你可以利用Java的'EnumSet'和'Enum',這爲你節省了大量的位字段工作。 [Effective Java 2nd]中有一個非常好的提示(http://dhruba.name/2008/12/31/effective-java-item-32-use-enumset-instead-of-bit-fields/)。 – Genzer

+0

它已經很整齊了。使用'int'來保存標誌將刪除這些轉換。 – harold

+1

我看到你的代碼正確。 但是如果你不想計算0x1,0x2,0x4,你可以做「flag1 = 1 << 0」(1),「flag2 = 1 << 1」(2),「flag3 = 1 << 2 「(4)。 如果你的旗幟沒有空白,可以檢查所有沒有或全部,「allFlags =((flag3 << 1) - 1)」 – ggrandes

回答

2

你應該使用BitSet,但是你正在做的方式是檢查,看看是否唯一有效標誌設置的正確方法。

你舉的例子修改:

public class Test { 
    static BitSet flag1 = new BitSet(); 
    static BitSet flag2 = new BitSet(); 
    static BitSet flag3 = new BitSet(); 

    public static void main(String[] args) { 
    flag1.set(0, true); 
    flag2.set(1, true); 
    flag3.set(2, true); 

    BitSet invalidFlags = new BitSet(); 
    invalidFlags.set(0, 3, true); 
    BitSet goodFlags = new BitSet(); 
    goodFlags.or(flag1); 
    goodFlags.or(flag2); 

    System.out.println(flagsAreOK(invalidFlags)); 
    System.out.println(flagsAreOK(goodFlags)); 
    } 

    private static boolean flagsAreOK(BitSet value) { 
    return value.get(0, value.length()).clear(0, 2).cardinality() == 0; 
    } 
} 

您可以使用BitSet.valueOf(...)從的byte秒的陣列創建BitSet。有關更多信息,請參閱JavaDoc。

+0

在我的用例中,我收到了用戶的數據字節,我需要確定設置了哪些標誌(以及是否設置了無效標誌)。我無法從'BitSet' API看到我會如何做到這一點。可能嗎? –

+0

@DuncanJones道歉,我偶然鏈接了一箇舊的JavaDoc,請參閱我的Java7版本更新,其中包含一個可以使用的'valueOf'方法。 –

+0

感謝您的澄清。不幸的是我必須使用Java 6,所以'BitSet'對我來說並不是真正的選擇。然而,我很欣賞答案。 –