• Post Reply Bookmark Topic Watch Topic
  • New Topic

Help debugging an enum  RSS feed

 
Jon Swanson
Ranch Hand
Posts: 230
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm not sure you can help, but I am at my wits end trying to sort out why my enum is not working. My main problem is that my test case works fine, but not when I use it in my larger program.

Here are my test files:




I run this and it works. For example, at the start, I see:
SETTING NAME Low
SETTING VAR ONE 1.0
SETTING VAR TWO 2.0
SETTING NAME Default
SETTING VAR ONE 2.0
SETTING VAR TWO 3.0
SETTING NAME High
SETTING VAR ONE 3.0
SETTING VAR TWO 4.0

Here is snippets of the 'real' code

The DesignConstants file includes the lines:

The result I see when the program starts is:
SETTING NAME Low
SETTING ISOMULT 0.0
SETTING SAMMULT 0.0
SETTING NAME Default
SETTING ISOMULT 0.0
SETTING SAMMULT 0.0
SETTING NAME High
SETTING ISOMULT 0.0
SETTING SAMMULT 0.0

If I hard code the values, they are used in the enum. But these values are used elsewhere and I would like to have one place where I set them.

Could anyone give a suggestion of why I can create my enum using constants in my example and I cannot do what seems to me to be the exact same thing in my larger program? I am at a loss as to where to look for the problem. I can't make the test case fail or the real case work, so I assume I am missing the some key knowledge and am looking in the wrong place for the problem.

Thanks.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jon Swanson wrote:I'm not sure you can help, but I am at my wits end trying to sort out why my enum is not working. My main problem is that my test case works fine, but not when I use it in my larger program.
Could anyone give a suggestion of why I can create my enum using constants in my example and I cannot do what seems to me to be the exact same thing in my larger program? I am at a loss as to where to look for the problem. I can't make the test case fail or the real case work, so I assume I am missing the some key knowledge and am looking in the wrong place for the problem.

I think it would be useful if, rather than showing us the code, you described to us what this enum is intended for.

Enums ARE, to all intents and purposes, constants, so if I was writing it, I would probably have just done something like:but presumably you have some reason why you don't want to do that.

Also: I wouldn't override toString() like you have. It's not specifically wrong, but it's not generally advisable. If you want to return your "name", why not just use a "getter" (ie, getName()) - or indeed, call your instance 'Low' instead of 'LOOSE'.

Winston
 
Jon Swanson
Ranch Hand
Posts: 230
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What I am most interested in at the moment is this-



Works.



FAILS.

Why is this? Is this expected? I would have thought the compiler would have made the latter pretty much like the former. What could I be doing wrong such that the former works and the latter fails? I'm feeling I am missing some fundamental programming point, as I don't see why the latter should fail. And, it does not fail in my simple cases I created to debug the problem. So I am clearly not understanding what the source of the problem might be.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jon Swanson wrote:Why is this? Is this expected?

Not by me - although you haven't shown us your MyConstants class.

Also: what you have defined elsewhere are NOT constants; they are variables.
The declaration for a constant is:
public static final double lowOne = 1.00;

However, this all seems incredibly tortuous. If, as I say, you could explain what you want this Enum to do, we might be able to help more.

Winston
 
Mohamed Sanaulla
Bartender
Posts: 3185
34
Google App Engine Java Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is what I tried"


And the output which I get is:


It works as expected i.e when I use the double values directly the enum uses them and when I use the double values via a public static variable the enum uses them.

I am running on JDK 8, not sure if its an issue specific to some version of Java. Try and execute the above program and see if you get the same results.
 
Jon Swanson
Ranch Hand
Posts: 230
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Winston.

I am still not sure why I could use the declaration:

public static double lowOne = 1.00;

in my EnumConstants class in my example, yet I need to use the declaration:

public static final double ARC_isoMult = 2.00;

in my actual code. But making that change in the latter results in a program that works.

OK. So on to designing the program better. See if this helps you understand why I set things up the way I did.

There is a concept in the program of a 'window' within which the correct solution must fall. In version 1, the window was fixed. What changed was how one got the solution that was tested. So I had an interface that defined methods that were independent of how the solution was obtained. For example, each implementation allowed calling 'isValid().' Later, it was requested that the window be displayed in the GUI. So I added a method to one of the display panels that grabbed the same window bounds constants. Later it was decided that there would be more than one window width, depending on how tightly the user wanted to constrain the result. The exact naming of this concept has since changed three times (which is why the name of LOOSE is Low), I suspect it will change again. So now I have a combobox that uses the names to allow the user to select what is now called a confidence level. That maps to the enum and I call isValid( enum ). My idea was that would free me up to add more than three levels in the future (which is likely to be required) as the methods in the enum allow me to get the window bounds straight from the enum. It is rather unlikely that the program will ever use a test other than the window boundaries for testing validity, as that idea maps well to the underlying science. It is likely that the exact number of options and their values will change again.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jon Swanson wrote:I am still not sure why I could use the declaration:
public static double lowOne = 1.00;

Because that defines a static variable called lowOne, that can be changed by any program/class that knows about it - which is why they're generally a very bad idea. It possibly also explains what you were seeing, but to be honest, I'm not sure of the exact mechanics (it'll no doubt be in the JLS somewehere; but I couldn't even advise where to look).

OK. So on to designing the program better. See if this helps you understand why I set things up the way I did...

Ah, OK. It sounds to me like a design that's "morphed" over time into a bit of a monster.

I think, if it was me, I'd put these values in a properties file, and simply read them into the enum at initialization time. That way, all your logic is contained in the enum, rather than scattered over multiple classes. You could also then supply the name of the file to your program when you call it, allowing you to plug in test values if you ever need them.

Winston
 
Jon Swanson
Ranch Hand
Posts: 230
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks again.

I think I will not worry about why I could get away with using a static variable in one case and not the other and just focus on cleaning things up so that things I intended to be constants are correctly declared static and final.

I have gotten in the habit of having a static class for each package that defines its constants. When I have a set of related classes that I might reuse, I try to extract them into their own package. Now you mention the idea of configuration files, it fits right in with the logic of why I defined the enum in the interface (rather than my static class of constants). I was trying to localize the definition to the classes that actually would use it. I have resisted configuration files before, not sure why. Thanks for getting me thinking.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't know. Enums that get values out of properties files smell funny to me. Almost seems like you're mixing two concerns there. IMO, enums should be well-defined and hardly, if ever, need to change. Having part of their definition come from properties files implies a certain level of changeability that doesn't fit the nature of enums as I see it. Could be just me but just sayin'...
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I also smell an explosion of classes in your design, Jon. Some of those constants don't seem like they need to live in a different file or have a public scope. I admit, I have only done a cursory review of the code you provided so I may be missing some subtleties but from what I can see, you seem to have gone off the deep end in trying to separate concerns. To paraphrase Einstein, "Strive to make things as separate as they can be, but no separated-er (?)." Hmm, "separate" doesn't work very well for that one.
 
Jon Swanson
Ranch Hand
Posts: 230
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Unfortunately, in my world, constant tends to be rather relative. 'Constants' tend to be tweaked. So the default window might be 2 - 3 today, but after some experimenting, it might be decided that 1.75 - 3.25 is really a better default. Then after some discussion, 1.8 - 3.1 might be chosen as a compromise. Right now, most of the code does not care. If it is using the default, it is using SomeEnum.DEFAULT with the values SomeEnum.DEFAULT.varOne() and SomeEnum.DEFAULT.varTwo(). I'm never likely to need to change that. The remaining discussion is then whether to hard-code the values in the enum, have an initialization file, or a file of 'constants.' I'd claim the latter two separate what changes from what does not, even though it might seem odd the 'constants' change the most.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Then why call them "constants"? That just muddles the conversation and leads to confusion or misunderstandings. A better term would be "configuration parameters" or "initialization parameters".
 
Jon Swanson
Ranch Hand
Posts: 230
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry for the confusion. The way I am doing things at the moment, I have a file of Java constants (static final) that represent the parameters of the program. Technically, once appropriate parameters are determined, they should change infrequently or not at all. In practice, they change more often than I would like. So rather than hard-code them in the respective classes, I put them all in one place, as, at least for me, its easier to find and change them when the need arises. And some are used in multiple classes, for example, the same thing needs the same name everywhere, but people can't decide on what the name should be, and so it changes from time to time.
 
Junilu Lacar
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jon Swanson wrote:Sorry for the confusion.

No need to apologize to us. I meant confusion and misunderstanding within your development org and in your code. We have no stake in this so it doesn't matter much to us. I was just trying to point out that names carry meaning and if that meaning does not fit the usage, then it can cause misunderstanding and confusion when it's used.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Junilu Lacar wrote:I don't know. Enums that get values out of properties files smell funny to me. Almost seems like you're mixing two concerns there. IMO, enums should be well-defined and hardly, if ever, need to change. Having part of their definition come from properties files implies a certain level of changeability that doesn't fit the nature of enums as I see it. Could be just me but just sayin'...

Not sure I agree; although a properties file might just be an interim stage in the design. Lots of systems use configuration files to supply otherwise "constant" values at runtime; and if you need more sophisticated "meta" information, there's also dependency injection.

@Jon: What you're trying to do can get quite involved and, as you can see, even we experienced bods don't always agree on how to do it. But that's the fun side of programming - nobody's "right" or "wrong" here; Junilu just sees enums slightly differently to me.

As I say, if you want to take this a stage further, you might want to have a look at dependency injection. There are several products out there; but Guice was one of the first general-purpose "injectors" on the market (although it may have been overtaken by others since it came out).
It also has an excellent introduction video, which might help to show you how powerful the technique can be - although in your case as it stands, it might be overkill.

HIH

Winston
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!