Best practices for using flags in the Java method

What is the best practice for specifying flags in a Java method?

I saw SWT using int as bit fields, for example:

(example partially from Effective Java, 2nd ed. on page 159):

public class Text { public static final int STYLE_BOLD = 1 << 0; // 1 public static final int STYLE_ITALIC = 1 << 1; // 2 void printText(String text, int flags) { } } 

and your customer request is as follows:

 printText("hello", Text.STYLE_BOLD | Text.STYLE_ITALIC); 

.. but this is discouraging since you can mix flags (int values) from different classes together without any compiler checks.

In the same book (Effective Java) I see the use of EnumSet, but then your custom call becomes:

 printText("hello", EnumSet.of(Style.Bold, Style.ITALIC)); 

I find this a bit detailed, and I prefer the elegance of SWT.

Is there another alternative or are these basically two flavors you should choose?

+8
java swt flags enumset
source share
5 answers

Guess you hit the wall. I do not see another option. Java is a detailed fact. In such situations, I usually add a local variable to make the code more readable. You can do it,

 EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.ITALIC); printText("hello", styles); 
+7
source share

If you need bit-style flags, Java wraps them in a BitSet . It was an eternity, but few bothered to use it (preferring to embed C-style bit processing in ints).

Api for BitSet can be found here .

In combination with several well-chosen static ints, it works very well until you start checking and setting a few bits in a single pass.

+2
source share

I advise you to go with the EnumSet approach.

 EnumSet<Style> styles = EnumSet.of(Style.Bold, Style.Italic); 

This approach provides better type safety, and Style , which is an enumeration, will have full-blown OO capabilities.

+2
source share

Late answer for anyone who comes across this. Here is one way to do this to reduce memory and have a nice enum like api:

 public static class MyFlag { public static final MyFlag A = new MyFlag(1<<0); public static final MyFlag B = new MyFlag(1<<1); public static final MyFlag C = new MyFlag(1<<2); public static final MyFlag ALL = A.and(B).and(C); private final int flag; private MyFlag(int flag){ this.flag = flag; } public MyFlag and(MyFlag limit){ return new MyFlag(flag & limit.flag); } public MyFlag not(MyFlag limit){ return new MyFlag(flag | ~limit.flag); } public boolean isSet(MyFlag limit){ if(limit ==null){ return false; } return (this.flag & limit.flag) != 0; } } 

method:

 public void doFoo(MyFlag flag){ if(MyFlag.A.isSet(flag)){ .... } if(MyFlag.C.isSet(flag)){ .... } } 

call:

 x.doFoo(MyFlag.A.and(MyFlag.C)); 
+1
source share

If you have only a limited number of methods that will accept a set of styles (for example, printText , in your example), you can customize your signature to accept a variable number of style parameters:

 void printText(String text, Style... flags) { EnumSet<Style> style = logicalOr(flags); // see comment below ... } 

And then your calls are very close to the untyped (int) flag route:

 printText("hello", Style.BOLD, Style.ITALIC); 

Unfortunately, there is no EnumSet.of(E... ) factory, just EnumSet.of(E first, E... more) , so you will need the general logicalOr method to split your array into parts with the first + remainder. Left as an exercise to the reader =).

0
source share

All Articles