Li'
Li'

Reputation: 3183

Calculate the enum value

I have seen a piece of Java code about 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);

output: 32

I suppose the result is 2 to the power of 5.

generally, if it is

i << j 

What does the express(i << j) mean? How can i and j affect the result? Can someone point me to a tutorial?

Upvotes: 1

Views: 472

Answers (3)

Eric Jablow
Eric Jablow

Reputation: 7899

Java enums are classes. They can have instance variables, though it is really bad form to make them writable. The constructor

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

means that Classname instances must be constructed with the int value. The declaration UIViewAutoresizingNone(0) sets the value of UIViewAutoresizingNone to 0, presumably for working with external code.

However, this is a somewhat silly way to work in Java. In C, one would write a similar enum as:

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

The difference between Java and C is that in C enums are really ints at heart. It is perfectly legal to write, given the above declaration,

Classname windowOptions = UIViewAutoresizingFlexibleLeftMargin |
                          UIViewAutoresizingFlexibleRightMargin;

This sets windowOptions to 1 | 4 == 5, and the external system would be able to use the & operator to pick the options out.

In Java, you can't do that. Instead, you'd use an EnumSet<Classname>:

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

The windowing system would use Set.contains to determine which options have been set. To do what one does in the C world, someone would have to write:

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

This is, frankly, a mess.

Upvotes: 0

rgettman
rgettman

Reputation: 178263

The << operator is the left bit-shift operator in Java. E.g. i is 1, the bits are 00000001. Bit shift left (j) is 5: 00100000 which is 32. Shifting bits to the left is a fast way to multiply an integer value by a power of 2.

Additionally, I should mention that the datatype int used here is 32 bits, not 8 (I showed the lowest 8 bits above for simplicity). It is also possible to shift bits "off" the end and lose them if you're not careful.

Upvotes: 3

srstinson
srstinson

Reputation: 141

<< is the left shift operator. If you consider an integer as a binary string, it shifts the string one to the left and cuts off the leftmost bit (i.e. 0b000101 becomes 0b01010). In terms of basic arithmetic, excluding overflow, this acts as a multiplication by two. Thus, 1<<5 is 0b100000, or 2^5, or 32.

In the expression i<<j, i is the base number being operated on, where j is the number of shifts occurring. When i is one, as in your example, 1<<n creates a binary string where the n+1th bit is set and no other bits are set. This is useful because you can then add these strings together and check each individual bit to see if that particular option is on.

Upvotes: 0

Related Questions