Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Runtime constant

Reply
Thread Tools

Runtime constant

 
 
MikL
Guest
Posts: n/a
 
      08-16-2005
Hi,

Can anyone suggest a workaround for the following problem? I have a
constant (static, final) whose value is calculated at runtime, when the
class is loaded. Because it isn't known at compile time, I can't use it in
a switch statement. But I'd like to.

public class StaticTest
{
public final int AAA = 1;
public final int BBB = 5 + 7;
public final int CCC = java.lang.String.class.getFields().length;
// ^-- just an example method

public void doSomething (int aIndex)
{
switch (aIndex)
{
case AAA: System.out.println("alpha"); break;
case BBB: System.out.println("bravo"); break;
case CCC: System.out.println("charlie"); break; // this line
doesn't compile
}
}
}


 
Reply With Quote
 
 
 
 
MikL
Guest
Posts: n/a
 
      08-16-2005
Oops, the listing missed the "static" keywords. Correct source with the
problem is as follows.

public class StaticTest
{
public static final int AAA = 1;
public static final int BBB = 5 + 7;
public static final int CCC = java.lang.String.class.getFields().length;

public void doSomething (int aIndex)
{
switch (aIndex)
{
case AAA: System.out.println("alpha"); break;
case BBB: System.out.println("bravo"); break;
case CCC: System.out.println("charlie"); break;
}
}
}


 
Reply With Quote
 
 
 
 
Roedy Green
Guest
Posts: n/a
 
      08-16-2005
On Tue, 16 Aug 2005 15:54:49 +1000, "MikL" <(E-Mail Removed)> wrote or
quoted :

> switch (aIndex)
> {
> case AAA: System.out.println("alpha"); break;
> case BBB: System.out.println("bravo"); break;
> case CCC: System.out.println("charlie"); break; // this line


make AAA BBB and CCC into enum constants. Then you can define an enum
instance function to produce the calculated int you want, perhaps with
the value passed in to the enum constant constructor. The enum
constants will work in a Switch.
 
Reply With Quote
 
Roedy Green
Guest
Posts: n/a
 
      08-16-2005
On Tue, 16 Aug 2005 15:58:12 +1000, "MikL" <(E-Mail Removed)> wrote or
quoted :

> case CCC: System.out.println("charlie"); break;


with enum you can define a function to provide the string "charlie"
rather than using a switch.

Ironically you use enum because they work in switches, but when you
are done most of your switches disappear, replaced by enum functions.
 
Reply With Quote
 
MikL
Guest
Posts: n/a
 
      08-16-2005
Roedy,

I like your suggestion, but alas I'm restricted to Java 1.4 for the moment.
I should have mentioned that.

Thanks,
Michael


 
Reply With Quote
 
MikL
Guest
Posts: n/a
 
      08-16-2005
The example was a little plain. Instead of the System.out.println(), my
"real" code would be running all sorts of logic -- it's not just an enum
toString() method.


 
Reply With Quote
 
Roedy Green
Guest
Posts: n/a
 
      08-16-2005
On Tue, 16 Aug 2005 16:15:06 +1000, "MikL" <(E-Mail Removed)> wrote or
quoted :

>The example was a little plain. Instead of the System.out.println(), my
>"real" code would be running all sorts of logic -- it's not just an enum
>toString() method.


you can still encapsulate that logic in enum functions. Each enum
constant can implement a different function. The switch logic
disappears.

I'm still hoping for a language/IDE that will let me examine enum
logic either one enum constant at a time, or comparing all enum
constants how they each implement a function, e.g. as if the code had
been done with switch.

I would like to flip back and forth between either view.

see http://mindprod.com/projects/scid.html

where I show a grid to demonstrate the idea.
 
Reply With Quote
 
Roedy Green
Guest
Posts: n/a
 
      08-16-2005
On Tue, 16 Aug 2005 16:12:39 +1000, "MikL" <(E-Mail Removed)> wrote or
quoted :

>I like your suggestion, but alas I'm restricted to Java 1.4 for the moment.
>I should have mentioned that.


Enums are implemented with an inner class per enum constant.

you can do pretty well everything in 1.4 EXCEPT the switch, but you
could do implement an ordinal function to use in switch.

to see what I mean, write the code in 1.5, then decompile it (see
http://mindprod.com/jgloss/decomiler.html)

Then use that to help you implement in 1.4.


 
Reply With Quote
 
Chris Uppal
Guest
Posts: n/a
 
      08-16-2005
MikL wrote:

> Can anyone suggest a workaround for the following problem? I have a
> constant (static, final) whose value is calculated at runtime, when the
> class is loaded. Because it isn't known at compile time, I can't use it
> in a switch statement.


You can't, the switch statement includes the value(s) directly in the generated
code, and therefore cannot be postponed until runtime.

Off the top of my head, I can't think of a workaround that would allow you to
use a switch that wouldn't be at least as slow, unclear, and unmaintainable, as
simply using cascaded "if"s.

-- chris


 
Reply With Quote
 
Roland
Guest
Posts: n/a
 
      08-16-2005
On 16-8-2005 7:54, MikL wrote:

> Hi,
>
> Can anyone suggest a workaround for the following problem? I have a
> constant (static, final) whose value is calculated at runtime, when the
> class is loaded. Because it isn't known at compile time, I can't use it in
> a switch statement. But I'd like to.
>
> public class StaticTest
> {
> public final int AAA = 1;
> public final int BBB = 5 + 7;
> public final int CCC = java.lang.String.class.getFields().length;
> // ^-- just an example method
>
> public void doSomething (int aIndex)
> {
> switch (aIndex)
> {
> case AAA: System.out.println("alpha"); break;
> case BBB: System.out.println("bravo"); break;
> case CCC: System.out.println("charlie"); break; // this line
> doesn't compile
> }
> }
> }
>
>


Convert your int index to an action object, which does the work for each
constant. IIRC this is the so-called Command Pattern. I've used it in
several occasions, both for primitive types (char, int, etc.) and
reference type (mostly Strings, but any type could do).

Below is an example how I'd implement it. You'll need a Map with ints as
keys (wrapped in Integer objects), and Action instances as values. In
the example I've chosen an interface, but Action could also be an
(abstract) class. Your switch now works by getting an Action object from
the Map that matches anIndex and call its method to do something.


import java.util.HashMap;
import java.util.Map;

public class CommandExample {

private static interface Action {
public void doSomething();
}

public static final int AAA = 1;
public static final int BBB = 5 + 7;
public static final int CCC =
java.lang.String.class.getFields().length;

private int someInstanceField;

private static Map actions;

public void doSomething(int anIndex) {
Action action = getAction(anIndex);
if (action != null) {
action.doSomething();
} else {
// default:
}
}

private static Action getAction(int anIndex) {
return (Action) getActions().get(new Integer(anIndex));
}
private static synchronized Map getActions() {
// lazily create the actions Map
if (actions == null) {

actions = new HashMap();

actions.put(new Integer(AAA), new Action() {
public void doSomething() {
System.out.println("alpha");
}
});

actions.put(new Integer(BBB), new Action() {
public void doSomething() {
System.out.println("bravo");
}
});

actions.put(new Integer(CCC), new Action() {
public void doSomething() {
System.out.println("charlie");
}
});
}
return actions;
}
}



You can easily extend it by adding additional methods to the Action
interface. These methods can have parameters. For instance, when you
need to access an instance field, you could pass this to the method:

private static interface Action {
public void doSomething();
public int calcSomething(CommandExample thiz);
}


You then would have to implement the calcSomething method for each Action:

private static synchronized Map getActions() {
// lazy create actions Map
if (actions == null) {
actions = new HashMap();
actions.put(new Integer(AAA), new Action() {
public int calcSomething(CommandExample thiz) {
return thiz.someInstanceField + 1;
}
public void doSomething() {
System.out.println("alpha");
}
});
// ... etcetera


Applying it would look like this:

public int calcSomething(int anIndex) {
Action action = getAction(anIndex);
if (action != null) {
return action.calcSomething(this);
} else {
// default:
return 0;
}
}

public static void main(String[] args) {
CommandExample example = new CommandExample();
example.doSomething(12);
System.out.println(example.calcSomething(1));
}
--
Regards,

Roland de Ruiter
` ___ ___
`/__/ w_/ /__/
/ \ /_/ / \
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
"error C2057: expected constant expression", "error C2466: cannot allocate an array of constant size 0". Why doesn't my simple program work??? hn.ft.pris@gmail.com C++ 13 01-22-2007 02:03 PM
pointers to constant characters and constant pointers to characters sam_cit@yahoo.co.in C Programming 4 12-14-2006 11:10 PM
len(var) is [CONSTANT] equal to len(var) == [CONSTANT]? Tor Erik Soenvisen Python 14 11-23-2006 09:57 PM
"Non-constant" constant can't be used as template argument Martin Magnusson C++ 2 10-08-2004 08:41 AM
Understanding How To Use #ifdef Constant #define Constant Sequence In Multible Files Christopher M. Lusardi C++ 1 09-02-2004 07:43 AM



Advertisments