masks and enums

W

Wojtek

If I have a mask set:

public static final long MASK_NONE = 0x000;
public static final long MASK_ONE = 0x001;
public static final long MASK_TWO = 0x002;
public static final long MASK_THREE = 0x004;
public static final long MASK_FOUR = 0x008;
public static final long MASK_FIVE = 0x010;

I can quite easily use them together:

MASK_ONE | MASK_FOUR

However as a constructor/method parameter I am passing in a long. I
would like to use an enum:

public enum Mask
{
NONE, ONE, TWO, THREE, FOUR, FIVE;
}

However the spec does not allow concatination of enums. To get around
this I can:
1. use a variable number of parameters
2. use an array of enums
3. use an object which contains a list (map) of the enums. However this
is as bad as having a complete set of isMaskX/setMaskX for each mask
type in some object.
4. list every possible combination of enums as their own enum. However
this expands really quickly and adding a new enum would be a royal
pain.
5. throw up my hands in disgust and keep using the longs
6. some other elegant solution?
 
P

Patricia Shanahan

Wojtek said:
If I have a mask set:

public static final long MASK_NONE = 0x000;
public static final long MASK_ONE = 0x001;
public static final long MASK_TWO = 0x002;
public static final long MASK_THREE = 0x004;
public static final long MASK_FOUR = 0x008;
public static final long MASK_FIVE = 0x010;

I can quite easily use them together:

MASK_ONE | MASK_FOUR

However as a constructor/method parameter I am passing in a long. I
would like to use an enum:

public enum Mask
{
NONE, ONE, TWO, THREE, FOUR, FIVE;
}

However the spec does not allow concatination of enums. To get around
this I can:
1. use a variable number of parameters
2. use an array of enums
3. use an object which contains a list (map) of the enums. However this
is as bad as having a complete set of isMaskX/setMaskX for each mask
type in some object.
4. list every possible combination of enums as their own enum. However
this expands really quickly and adding a new enum would be a royal pain.
5. throw up my hands in disgust and keep using the longs
6. some other elegant solution?

7. use java.util.EnumSet.

Patricia
 
R

Roedy Green

You might want to add that enumSet.contains(MyEnum.MASK) replaces a
standard bit comparison. I know it is part of the Collection classes,
but it could be highlighted.
contains expects an Object but the docs have nothing to say about the
type that object. What is this MASK? another EnumSet? a Long?
 
W

Wojtek

Roedy Green wrote :
I have updated the entry and written a new piece of sample code. See
if I covered everything you think is important.
see http://mindprod.com/jgloss/enumset.html

Yes, it is much clearer now as to how to use EnumSet.

I am curious about this statement: "Normally it would be public in its
own *.java file".

I usually place the enum on the class which uses it:

--------------------------------------
public Class Foo
{
public enum CompareType
{
TEXTUAL,
NUMERIC;
}

....

public boolean fooCompare(String value, CompareType compare )
{

if ( compare == NUMERIC )
// code to do a compare on 'value' after converting it to a number
else
// code to compare two strings
}
--------------------------------------

To me it makes more sense to place the enum within this class rather
than creating a separate class which only holds the enum. Or worse a
class which only holds all the enums for a project.

And since everything has an exception, I do place certain enums in a
singleton which holds application wide "magic numbers".
 
R

Roedy Green

I am curious about this statement: "Normally it would be public in its
own *.java file".

I usually place the enum on the class which uses it:

1. I though there was a limit of one public class per *.java file.

2. I like to put one class per *.java file because it makes classes
easier to find.

3. It seems to me, the compiler would have troubles finding the source
for classes if you don't do that, but obviously it somehow does.
 
S

Steve Wampler

Roedy said:
1. I though there was a limit of one public class per *.java file.

I think that's right, also. My best guess is that 'public enum' is
indeed a different entity than 'public class' and so operates under
different rules.

I'm not sure I like this, if true. I would have expected references
to an 'embedded' enum to behave like other class entities. That is,
references for:

public class Foo {
public enum CompareType {

would have needed to be qualified as Foo.CompareType, ala inner classes.
Not that it really matters, since it's a done deed, apparently.
 
W

Wojtek

Roedy Green wrote :
1. I though there was a limit of one public class per *.java file.

2. I like to put one class per *.java file because it makes classes
easier to find.

3. It seems to me, the compiler would have troubles finding the source
for classes if you don't do that, but obviously it somehow does.

But an enum is not really a "full" class. You cannot extend it for
instance.

I also only put one class per file, except where it makes more sense,
such as a private class only used within the enclosing class.

I do use somewhat deeply nested public classes in things like constants
where I organize information:

public class Foo
{
public static final String VALUE = "value";

public static class Bar
{
public static final String VALUE = "barValue";
}
}

which can be accessed as:

Foo.Bar.VALUE
 
W

Wojtek

Steve Wampler wrote :
I think that's right, also. My best guess is that 'public enum' is
indeed a different entity than 'public class' and so operates under
different rules.

I'm not sure I like this, if true. I would have expected references
to an 'embedded' enum to behave like other class entities. That is,
references for:

public class Foo {
public enum CompareType {

would have needed to be qualified as Foo.CompareType, ala inner classes.
Not that it really matters, since it's a done deed, apparently.

You do need to use Foo.CompareType ala inner classes. Unless, of
course, you are within the enclosing class.

Except in switch/case, where you can ONLY use the enums within the
CompareType. No qualification allowed.
 
L

Lew

Nested classes can be public.
I think that's right, also. My best guess is that 'public enum' is
indeed a different entity than 'public class' and so operates under
different rules.

The OP nested his enum.
I'm not sure I like this, if true. I would have expected references
to an 'embedded' enum to behave like other class entities. That is,
references for:

public class Foo {
public enum CompareType {

would have needed to be qualified as Foo.CompareType, ala inner classes.

That's the syntax for non-inner nested classes, not for inner classes. Inner
classes need an enclosing instance, e.g., "new Foo().CompareType".
Not that it really matters, since it's a done deed, apparently.

Inner classes don't have to be qualified by the enclosing instance when
referred to from the enclosing instance.

Which begs the question of why this particular inner enum is public in the
first place.

The OP's philosophy of always making such enums inner (why not static nested?)
is certainly open to debate. Endless debate, perhaps - the use of inner
classes generally is a black art and controversial to some.
 
W

Wojtek

Lew wrote :
Which begs the question of why this particular inner enum is public in the
first place.

Some are public, some are private, some are package level. Depends on
the circumstances and who needs to use it.
The OP's philosophy of always making such enums inner (why not static
nested?) is certainly open to debate. Endless debate, perhaps - the use of
inner classes generally is a black art and controversial to some.

As I understand it:

public enum

is the same as:

public static enum
 
D

Daniel Pitts

Lew wrote :


Some are public, some are private, some are package level. Depends on
the circumstances and who needs to use it.


As I understand it:

public enum

is the same as:

public static enum

Lew, enums are always "static".

I don't have a hard and fast rule about where I put my enums.
Sometimes they make since on there own, and sometimes they only make
since as "part of" another class. I tend to put them in the first
class that uses them, and then refactor them to package level if it
seems appropriate.
 
D

Daniel Pitts

Roedy Green wrote :





But an enum is not really a "full" class. You cannot extend it for
instance.

I also only put one class per file, except where it makes more sense,
such as a private class only used within the enclosing class.

I do use somewhat deeply nested public classes in things like constants
where I organize information:

public class Foo
{
public static final String VALUE = "value";

public static class Bar
{
public static final String VALUE = "barValue";
}

}

which can be accessed as:

Foo.Bar.VALUE

The the time you have nested constants, you might look into using an
external configuration, such as Properties, or a custom XML file. Or,
possibly using Dependency Injection.
 
W

Wojtek

Daniel Pitts wrote :
The the time you have nested constants, you might look into using an
external configuration, such as Properties, or a custom XML file. Or,
possibly using Dependency Injection.

So I lied a little :)

public class Lang
{
public class Report
{
public class Finance
{
public static final LangKey HEAD_TOTAL = new
LangKey("report.finance.head.total");
}
}
}

Used as: Lang.Report.Finance.HEAD_TOTAL

Which is used in my custom made I18N class. That way ONLY a LangKey can
be passed as a language key, which makes sure that a typo does not
occur. Or rather, that a typo can only be made in one place.

I do use properties, but then the keys for the properties are also
nested constants.

I really HATE magic numbers...
 
L

Lew

Daniel said:
Lew, enums are always "static".

I don't have a hard and fast rule about where I put my enums.
Sometimes they make since on there own, and sometimes they only make
since as "part of" another class. I tend to put them in the first
class that uses them, and then refactor them to package level if it
seems appropriate.

Right, good point. But the question still stands as to why they must be
nested, or when it might be better. That's the black art.
 
T

Twisted

Right, good point. But the question still stands as to why they must be
nested, or when it might be better. That's the black art.

Eh. Isn't it fairly simple?

public class Widget extends JComponent {
public static enum Alignment {LEFT, RIGHT, CENTER};
...
}

when only one class tree, Widget and descendants, uses the alignment,
and

public enum WidgetAlignmemt {LEFT, RIGHT, CENTER}

when lots of independent FooWidgets occur that have an alignment of
this sort, and there's no compelling type-safety reason to treat each
type's alignment options as a separate type.

In particular, if FooWidget might add new alignment options in the
future irrelevant to the others it should use its own nested enum, so
we can add TOP_LEFT, TOP, TOP_RIGHT, BOTTOM_LEFT, BOTTOM, and
BOTTOM_RIGHT when it has two degrees of freedom someday without all
the others that are just aligning text needing to now detect bogus
values like TOP_LEFT and throw exceptions, or translate them to use
only the horizontal part.

Of course that might be done by instead having a VAlignment {TOP,
BOTTOM, CENTER} enum and modifying FooWidget to use one of each, too.
But it's not always so orthogonally decomposable...

If you mean more general with nested and inner classes, ordinarily you
nest only when the would-be nested class is only used together with (a
subclass of) the would-be nesting class rather than having independent
use, and you make an inner class only when it's something that it
makes sense to tie to an instance, such as iterators viewing a
particular collection instance.
 
R

Roedy Green

Right, good point. But the question still stands as to why they must be
nested, or when it might be better.

You might nest them if they are used by only the enclosing class. I
find though the enums tend to be popular and reused elsewhere, so I
tend to put them in a separate public or default class in their own
file.

Also too, I tend now to put more and more logic in the enums, and less
in the classes that use them. It makes sense then to give them their
own file to grow in.

But the main reason is I can find them more easily then they are in
their own file.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,968
Messages
2,570,154
Members
46,702
Latest member
LukasConde

Latest Threads

Top