【问题标题】:Test for invalid bit flags测试无效位标志
【发布时间】:2013-01-22 06:38:25
【问题描述】:

我正在使用位标志从一个字节中读取用户提供的选项。我想检查字节是否包含任何无效/未知的标志值。

到目前为止,我编写的快速测试代码如下所示:

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,但已经有一个 bug 抱怨 impossible the JavaDocs are to read 如何。

【问题讨论】:

  • 您的标志是否代表一组常量。如果是这样,您可以利用 Java 的 EnumSetEnum,这可以为您节省大量与位字段相关的工作。 Effective Java 2nd有一个很好的tips。
  • 已经很整洁了。使用int 来保存标志将删除强制转换。
  • 我看到你的代码是正确的。但是如果你不想计算 0x1、0x2、0x4,你可以做 "flag1 = 1
  • @Genzer 它们代表一组不互斥的选项。我想这排除了EnumSet
  • @ggrandes 非常好,非常有帮助,谢谢。

标签: java bit-manipulation flags


【解决方案1】:

您应该使用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(...)bytes 的数组中创建一个BitSet。有关详细信息,请参阅 JavaDoc。

【讨论】:

  • 在我的用例中,我从用户那里收到我的数据字节,我需要确定设置了哪些标志(以及是否设置了无效标志)。我无法从BitSet API 中看到我将如何做到这一点。有可能吗?
  • @DuncanJones 抱歉,我无意中链接了一个旧的 JavaDoc,请参阅我对 Java7 版本的更新,其中包括您可以使用的 valueOf 方法。
  • 感谢您的澄清。不幸的是,我必须使用 Java 6,所以 BitSet 对我来说并不是一个真正的选择。不过,我很欣赏这个答案。
猜你喜欢
  • 2021-12-12
  • 1970-01-01
  • 2020-12-10
  • 2021-08-05
  • 2017-02-10
  • 2014-09-08
  • 1970-01-01
  • 1970-01-01
  • 2022-06-13
相关资源
最近更新 更多