aspose file tools*
The moose likes Beginning Java and the fly likes Constants and switch statement Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Constants and switch statement" Watch "Constants and switch statement" New topic
Author

Constants and switch statement

Jeff Allison
Greenhorn

Joined: Dec 09, 2004
Posts: 20
I'm new to Java and have encountered a "there's got to be a better way to do this" situation. I'm writing an app that deals with output from a device attached via serial cable. I have a small number of "commands" to deal with, all of which have a 4-letter acronym. My thought on processing these was to use a switch statement based on the hash code of the acronym. I created constants to hold the hash codes of the commands, like this:

static final int PRID="PRID".hashCode();

But Java won't let me use PRID as a case label; it says it needs a constant there. I could figure out the hash code values for the commands and hard code them in, but there's got to be a better way than that. I thought "final" told the compiler that this is a constant, no?
Nathaniel Stoddard
Ranch Hand

Joined: May 29, 2003
Posts: 1258
Well, unfortunately, it's not that the case can't take final variables, it's just that the case value must be what the language spec calls a "constant expression". In your case, PRID isn't a constant expression because it's a final variable whose value isn't a literal value. For example, final int PRID = 3 would work, but ... = "PRID".hashCode() won't. Sorry.

I would suggest the good ol' fashioned if ... else if ... else.

If you're interested ... constant expression.


Nathaniel Stodard<br />SCJP, SCJD, SCWCD, SCBCD, SCDJWS, ICAD, ICSD, ICED
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

Hi Jeff,

Welcome to JavaRanch!

They have to be compile-time constants, not simply variables whose values won't change. The compiler won't evaluate "hashCode()" at compile time.

If the list of commands is fairly short, use "if-else"



The more Java-like method, and the way that you'd do things the object-oriented way, would be to use polymorphism, with a Command interface and one implementation per command. You could use a Map data structure to relate the commands to the Command objects. If you're interested, I could certainly tell you more about it. In any case, for a handful of commands, the if-else is going to work just fine.


[Jess in Action][AskingGoodQuestions]
Jeff Allison
Greenhorn

Joined: Dec 09, 2004
Posts: 20
Thanks for the quick reply. The if/else if/else if... is the obvious alternative, but I am loathe to go there because of the inefficiencies implied. Doing an indexOf() or startsWith() or any other string comparison method for every option seems brutal. You start doing things like putting the more likely commands early in the list. Just not elegant.

I'll probably just come up with a state machine that'll parse the incoming commands. I was trying to short-cut that process with the computed hash value, but that looks like a non-starter.

Thanks again.
Jeff Allison
Greenhorn

Joined: Dec 09, 2004
Posts: 20
The more Java-like method, and the way that you'd do things the object-oriented way, would be to use polymorphism, with a Command interface and one implementation per command. You could use a Map data structure to relate the commands to the Command objects. If you're interested, I could certainly tell you more about it. In any case, for a handful of commands, the if-else is going to work just fine.


Sure, I'm interested. There aren't many commands, but listing them all in an if-else violates my sensibilities. Plus it's always good to do things in the most natural way for the language you're using. After all, we can write FORTRAN in any language, right?

Thanks!
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

This is the basic idea. You probably will want your execute() method to take some arguments -- that's up to you. The Command object lookup will be cheap.

Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
That's a very cool approach. When you get into large systems you'll find parts that you'd like to call done and never touch again. This core "get a request, execute a command" routine would be a nice one. If you have another class somewhere that reads a configuration file and loads the map with 4-letter-instruction and a command instance, you can add new commands without touching this class.

If this sounds interesting Google for "dependency injection" and "application assembler". If it sounds too advanced, just shove those terms way back in your brain for later reference.


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Jeff Allison
Greenhorn

Joined: Dec 09, 2004
Posts: 20
This is the basic idea. You probably will want your execute() method to take some arguments -- that's up to you.


Fantastic! I have never receive such immediate and comprehensive assistance in a forum. This is exactly what I was after, only I wasn't sure how to get there.

I do get a warning from the compiler about unchedked or unsafe operations. I am guessing that is due to the cast from the generic object stored in the HashMap to the specific Commands object that I need. I'm ignoring that for now as the code works.

Thanks again, I very much appreciate the help.
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
The ideas presented in Ernest's post above are an implementation of a Design Pattern. Design Patterns are basically outlines of solutions to commonly found problems. In particular, I think this is called the Command Pattern. There are many generic design patterns as well as some that are specific to certain domains of problems (such as database or web programming). If you are interested in learning more about this fascinating (and useful) topic, I hope this post gives you some keywords that you can google for.

Layne


Java API Documentation
The Java Tutorial
Jeff Allison
Greenhorn

Joined: Dec 09, 2004
Posts: 20
In particular, I think this is called the Command Pattern.


And in C you'd just use an array of function pointers to implement it. My problem is getting away from C language thinking and into Java thinking. Looks like this forum will be helpful in that regard.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

This is indeed a great place. I stopped in one day for a drink, and never left...

But yeah, this is just like a dispatch table in C, and yes, the Patterns folks call this the Command Pattern.

The message about unsafe operations leads me to believe you're using the new Java 5, which has generic types. In Java 5 (which I haven't used extensively myself, yet) you can say



with no cast, and no warning.
Jeff Allison
Greenhorn

Joined: Dec 09, 2004
Posts: 20
The message about unsafe operations leads me to believe you're using the new Java 5, which has generic types. In Java 5 (which I haven't used extensively myself, yet) you can say...


Bingo. That did it. The syntax is weird, but I get the gist. Thanks again.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Constants and switch statement