2013-04-23 80 views
1

我看到一段Java代码约enum计算枚举值

public enum Classname { 
    UIViewAutoresizingNone(0), 
    UIViewAutoresizingFlexibleLeftMargin(1 << 0), 
    UIViewAutoresizingFlexibleWidth(1 << 1), 
    UIViewAutoresizingFlexibleRightMargin(1 << 2), 
    UIViewAutoresizingFlexibleTopMargin(1 << 3), 
    UIViewAutoresizingFlexibleHeight(1 << 4), 
    UIViewAutoresizingFlexibleBottomMargin(1 << 5); 

    private int value; 

    // constructor 
    private Classname(int v) { 
     this.value = v; 
    } 

    public int value() { 
     return value; 
    } 
} 

System.out.println(Classname.UIViewAutoresizingFlexibleBottomMargin.value); 

输出:32

我想结果为2至5。

的功率一般,如果是

i << j 

什么是快递(我< < j)是什么意思?我和j怎样影响结果?有人可以指点我一个教程吗?

+0

相关:http://stackoverflow.com/q/16162290/1065197 – 2013-04-24 00:00:23

+1

它在[tutorial](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html)中有解释。 – jlordo 2013-04-24 00:00:52

回答

3

<<运算符是Java中的left bit-shift operator。例如。 i是1,位是00000001。位的移位左(j)为5:00100000其是32比特移位到左边是由2

另外的功率乘以一个整数值的快速方法,我应该指出,这里所使用的数据类型是int 32位,而不是8位(为简单起见,我显示了最低8位)。如果你不小心,也可以将位移到最后,并丢掉它们。

0

<<是左移运算符。如果将整数视为二进制字符串,则会将字符串向左移一位并切断最左边的位(即0b000101变为0b01010)。就基本算术而言,除了溢出之外,这是两倍的乘法。因此,1 < < 5是0b100000,或2^5,或32

在表达式i<<ji是正在操作的基数,其中j是存在的移位的数量。当i是一个,如在你的例子中,1<<n创建一个二进制字符串,其中第n + 1位被设置,并且没有其他位被设置。这很有用,因为您可以将这些字符串添加到一起,并检查每个单独的位以查看该特定选项是否处于打开状态。

0

Java枚举类是类。他们可以拥有实例变量,但它们是可写的非常糟糕的形式。构造函数

private Classname(int v) { 
    this.value = v; 
} 

表示Classname实例必须使用int值构造。声明UIViewAutoresizingNone(0)UIViewAutoresizingNone的值设置为0,大概是为了使用外部代码。

但是,这是一种在Java中工作的有点愚蠢的方式。在C语言中,一个会写一个类似枚举为:

typedef enum { 
    UIViewAutoresizingNone     = 0, 
    UIViewAutoresizingFlexibleLeftMargin = 1 << 0, 
    UIViewAutoresizingFlexibleWidth  = 1 << 1, 
    UIViewAutoresizingFlexibleRightMargin = 1 << 2, 
    UIViewAutoresizingFlexibleTopMargin = 1 << 3, 
    UIViewAutoresizingFlexibleHeight  = 1 << 4, 
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5 
} Classname; 

Java和C之间的区别是,在C枚举真的ints的心脏。这是完全合法的写,给出了上述声明,

Classname windowOptions = UIViewAutoresizingFlexibleLeftMargin | 
          UIViewAutoresizingFlexibleRightMargin; 

这台windowOptions到1 | 4 == 5,和外部系统将能够使用&运营商挑选的选择了。

在Java中,你不能这样做。相反,你会使用一个EnumSet<Classname>

EnumSet<Classname> windowOptions = 
    EnumSet.of(Classname.UIViewAutoresizingFlexibleLeftMargin, 
       Classname.UIViewAutoresizingFlexibleRightMargin); 

窗口系统将使用Set.contains确定哪个选项已经被设置。要在C世界做什么,有人会写:

int bitMask = 0; 
for(Classname option: windowOptions) { 
    bitMask |= option.getValue(); 
} 

坦率地说,这是一团糟。