dev@glassfish.java.net

Re: should constants be used in a modularized system?

From: Ken Paulsen <Ken.Paulsen_at_Sun.COM>
Date: Fri, 21 Mar 2008 00:19:13 -0700

Lloyd, Bill and others:

To make sure I understand correctly, let me see if I can repeat back
what you're saying...

If you define a constant (public static final), for example:

public static final String C = "hello";

...then another class references that code, it will be contained in
bytecode (i.e. it won't look at the orginal C). In other words, if you
change "hello" to "goodbye" w/o recompiling all classes using C, you'll
still have "hello" in those classes that weren't recompiled.

However... if you define your "constant" like this:

private static String getC() { return "hello" }
public static final String C = getC();

Or even:

public static final String C;
static { C = "hello"; }

Then code refering to "C" *WILL* refer back to the class instead of
keeping it local via bytecode. This is arguably not a constant now
(although public static final, it cannot be "inlined" by other .class
code). In other words, if you change "hello" to "goodbye" and ONLY
compile the class which defines C, it will still be seen in ALL classes
referencing C (i.e. no more "hello" anywhere).

Is that right? And if so, what is your recommendation or design pattern
that we should follow? It was not clear (to me) from the email exchange.
Which if these should be preferred:

* Enum
* "public static final" initialized via a static method
* "public static final" initialized via a static block (probably the
same thing to the JVM??)
* No "public static final" use static getter method instead
* or ??

Thanks for bringing this up... this is one of those little things that
could cause big problems. :)

Ken

Lloyd L Chambers wrote:
> Bill,
>
> Agreed...though problem with enums for management (JMX) include:
>
> - they require a new class that might not be available on a client
> (across "the wire")
> - they might not map automatically to other non-Java protocols
>
> At least that's my understanding.
>
> So for values returned across the wire through a management interface,
> enums are an issue. A good example of this is java.util.logging.Level;
> I ran into this problem recently working with a developer on a JMX
> adapter.
>
> Lloyd
>
> On Mar 20, 2008, at 2:31 PM, Bill Shannon wrote:
>> Lloyd L Chambers wrote:
>>> In Glassfish V3 the system is highly modularized. Compiling one
>>> module against another might mean using static constants eg:
>>> // module B using org.glassfish.foo.bar from another module A
>>> import org.glassfish.foo.bar.CONSTANT1;
>>> ...
>>> doSomething( CONSTANT1 );
>>> ...
>>> If I understand correctly, java constants are compiled into the
>>> resulting bytecode.
>>> So if the constant is later changed in the defining module, code
>>> compiled against that module does *not* pick up the new value unless
>>> it is recompiled.
>>> In short, in a modular system, should constant values be fixed at
>>> compile time, or picked up dynamically at runtime? If they are to be
>>> dynamic, then our constants need to be written as methods eg:
>>> public static String getCONSTANT1();
>>> *not*
>>> public static final String CONSTANT1 = "val"
>>> Of course, there might not be a hard and fast rule. But if a module
>>> is newly-built and has new values for its constants, it might be
>>> reasonable to expect dependent modules to use the new values.
>>
>> Yes, we should all understand this. Primitives and String constants
>> are stored by *value*, not name. Once you choose a value for one of
>> these constants in a public API (across module boundaries), you're
>> committing to it, no matter what name you might use.
>>
>> Many of these constants should probably be enums, which don't have this
>> problem.
>>
>> String constants should really only be used for things that are
>> externally
>> defined and really won't change. Otherwise, if it can change, it's not
>> really a constant! :-)
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
>> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>>
>
> ---
> Lloyd L Chambers
> lloyd.chambers_at_sun.com
> Sun Microsystems, Inc
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>