From: www on
I really like Java enums, so I use it a lot. Probably I have abused it.
Below is my enum ABC_ENUM,java. Is that ok? My understanding is
ABC_ENUM.A is one static object, ABC_ENUM.B is another static object, etc.

If I have two threads running the same method, but on different data. If
one thread's ABC_ENUM.A boolean value is changed, another thread's
ABC_ENUM.A value will be changed too??!! What should I do if I want that
change(ABC_ENUM.A boolean value changed to "true") is only effective
within the current thread, not affect another thread?

If this is poor design, can you give me some recommendation? Thank you.


public enum ABC_ENUM
{
A("A", false),
B("B", false),
C("C", true);

private String _techName;
private boolean _boolValue;

private ABC_ENUM(final String techName, final boolean boolValue)
{
_techName = techName;
_boolValue = boolValue;
}

public String techniqueName()
{
return _techName;
}

public void setBoolValue(final boolean boolValue)
{
_boolValue = boolValue;
}

public boolean boolValue()
{
return _boolValue;
}

@Override
public String toString()
{
return _techName + "[" + _boolValue + "]";
}

/**
* Reset these constants' boolVaue to their original values to
erase the changes made by previous run.
*/
public static void reSetToDefaultValues()
{
A._boolValue = false;
B._boolValue = false;
C._boolValue = true;
}

}
From: Peter Duniho on
www wrote:
> I really like Java enums, so I use it a lot. Probably I have abused it.
> Below is my enum ABC_ENUM,java. Is that ok? My understanding is
> ABC_ENUM.A is one static object, ABC_ENUM.B is another static object, etc.
>
> If I have two threads running the same method, but on different data. If
> one thread's ABC_ENUM.A boolean value is changed, another thread's
> ABC_ENUM.A value will be changed too??!! What should I do if I want that
> change(ABC_ENUM.A boolean value changed to "true") is only effective
> within the current thread, not affect another thread?
>
> If this is poor design, can you give me some recommendation? Thank you.

Yes, I would say that is poor design. An enum should be essentially a
constant. In fact, I find it remarkable that the language does not
require enum fields to be "final".

You should fix your design. The enum should only have "final" fields.
If the type doesn't work with "final" fields, then it shouldn't be an
enum. Just use a plain class instead if you need values that are unique
per thread, so that each thread can have its own collection of values.

For what it's worth, the code you've shown looks like what you really
want is a HashMap<String, boolean>, one instance per thread.

Pete
From: www on
(I am the original poster. I am now accessing this newsgroup from
Google Group at home.)

Thank you, Pete. I appreciate your recommendation.

I hope to add one more question to help me understand better: I have
two junit tests (in Eclipse, on Linux). Each junit test runs the same
Java program from the beginning to the end with different input data
and generates different output data. If I run the two tests in a row,
the second test fails. The cause of 2nd junit test failing is that
ABC_NUM values were modified by the 1st junit test and be picked up by
the second test which is the wrong value for the 2nd test. If I run
one test each time, every test passes. Or, at the beginning of my Java
program, if I add this line:

ABC_ENUM.reSetToDefaultValues(); //refresh, get rid of the values by
previous run

I can run the 2 tests in a row and every test passes. It seems Eclipse
stores ABC_ENUM in a buffer or somewhere. If two junit tests run in a
row, the second test just access that SAME ABC_ENUM left over by the
1st run.

Is this Eclipse's feature/bug? Thank you again.
From: Lew on
www wrote:
> I hope to add one more question to help me understand better: I have
> two junit tests (in Eclipse, on Linux). Each junit test runs the same
> Java program from the beginning to the end with different input data
> and generates different output data. If I run the two tests in a row,
> the second test fails. The cause of 2nd junit test failing is that
> ABC_NUM values were modified by the 1st junit test and be picked up by
> the second test which is the wrong value for the 2nd test. If I run
> one test each time, every test passes. Or, at the beginning of my Java
> program, if I add this line:
>
> ABC_ENUM.reSetToDefaultValues(); //refresh, get rid of the values by
> previous run
>
> I can run the 2 tests in a row and every test passes. It seems Eclipse
> stores ABC_ENUM in a buffer or somewhere. If two junit tests run in a

I'll bet this "buffer or somewhere" is an instance variable of your test
class, yes? If so, it's not Eclipse storing it, it's your own code.

> row, the second test just access that SAME ABC_ENUM left over by the
> 1st run.
>
> Is this Eclipse's feature/bug?

No, it's yours.

Consider using 'setUp()' and 'tearDown()' to, well, set up and tear down your
test scenarios. Those methods are run before and after (respectively) each
test method of the class, let alone successive runs of the same test-class
instance.

public class FooTest
{
private final Logger logger = getLogger( getClass() );

private Foo foo; // for some reason, use member var

/**
* Set up the test.
*/
@Before
public void setUp()
{
logger.debug( "Set up the test." );
foo = new Foo();
}

/**
* Tear down the test.
*/
@After
public void tearDown()
{
logger.debug( "Tear down the test." );
foo = null;
}

/**
* Test of getHandle method, of class Person.
*/
@Test
public void testDoSomething()
{
Bar bar = foo.doSomething();
assertNotNull( bar );
}
}

Naturally you'll add test-case setup and teardown code to flesh out those methods.

BTW, setting up an instance variable is maybe a bad thing; better to create a
local 'Foo foo' inside each 'testX()' method, perhaps. That depends on the
nature of your test scenarios.

--
Lew
From: Roedy Green on
On Wed, 14 Jul 2010 14:42:57 -0400, www <www(a)nospam.com> wrote, quoted
or indirectly quoted someone who said :

>
> private ABC_ENUM(final String techName, final boolean boolValue)
> {
> _techName = techName;
> _boolValue = boolValue;
> }

the usual convention would look like this:

ABC ( final String techName , final boolean boolValue )
{
this.techName = techName;
this.boolValue = boolValue;
}

This ties the variables together more tightly.

boolValue is a poor choice of variable name. See
http://mindprod.com/jgloss/naming.html for how to compose a better
one.
--
Roedy Green Canadian Mind Products
http://mindprod.com

You encapsulate not just to save typing, but more importantly, to make it easy and safe to change the code later, since you then need change the logic in only one place. Without it, you might fail to change the logic in all the places it occurs.