Re: Where do you keep contants in Interfaces or in classes?

Discussion in 'Java' started by Stefan Ram, Mar 30, 2008.

  1. Stefan Ram

    Stefan Ram Guest

    Newsgroups: comp.lang.java.gui,comp.lang.java.programmer
    Followup-To: comp.lang.java.programmer

    Royan <> writes:
    >I have some controversial information on what is the best place to
    >keep constants, is there any fundamental recommendation?


    The best place for a question not related to GUI programming
    is outside of »comp.lang.java.gui«.

    The best place for a question in the subject header line is
    a copy in the body of a post.

    (1) Constants can only be kept in interfaces, classes might
    have »final fields« or »constant variables«, but these are not
    called »constants« in Java.

    JLS3, 4.2.4 mentions constants in classes:

    »Other useful constructors, methods, and constants are
    predefined in the classes Float, Double, and Math.«

    I admit that this contradicts my previous statement (1). But
    this might be the only place, where the JLS3 mentions
    »constants in classes«.

    In JLS3, however, 6.8.6 the wording is:

    »The names of constants in interface types should be, and
    final variables of class types may conventionally be, ...«

    This supports (1).

    (BTW, »final variable of class type« seems ambigous to me.

    Is this a final variable /whose type/ is a class, such as:

    final java.lang.Object v; ?

    Or is this a final variable that is /a field/ of a class:

    class Example { ... final int v; ... } ? - ... Never mind)

    Constant-related terms are also mentioned in JLS3, 8.3.2.1:

    »One subtlety here is that, at run time, static variables
    that are final and that are initialized with compile-time
    constant values are initialized first. This also applies
    to such fields in interfaces (§9.3.1). These variables are
    constants” that will never be observed to have their
    default initial values (§4.12.5), even by devi-ous
    programs. See §12.4.2 and §13.4.9 for more discussion.«

    The definition of an instance of an enum type is called
    an »enum constant« by JLS3, 8.9.

    At least, the BNF-grammar given in the JLS3 only seems to
    mention »constant declaration« for interfaces (JLS3, 9.1.4):

    InterfaceMemberDeclaration:
    ConstantDeclaration

    This seems to suggest that by the grammar only interfaces
    can have constants (and enumerations can have enum constants).

    I also found this related little-read paragraph from JLS3,
    13.4.10 interesting:

    »The best way to avoid problems with "inconstant
    constants" in widely-distributed code is to declare as
    compile time constants only values which truly are
    unlikely ever to change. Other than for true mathematical
    constants, we recommend that source code make very
    sparing use of class variables that are declared static
    and final. If the read-only nature of final is required,
    a better choice is to declare a private static variable
    and a suitable accessor method to get its value. [...]

    We also recommend, as a general rule, that only truly
    constant values be declared in interfaces. We note, but do
    not recommend, that if a field of primitive type of an
    interface may change, its value may be expressed
    idiomatically as in:

    interface Flags {
    boolean debug =new Boolean(true).booleanValue();
    }

    insuring that this value is not a constant. Similar idioms
    exist for the other primi-tive types.«

    So now the JLS does not only specify Java, but also acts
    as a style guide.

    By 15.28, a compile-time constant expression does not have to
    be a constant, it might be a name refering to a constant
    variable (4.12.4).

    Newsgroups: comp.lang.java.gui,comp.lang.java.programmer
    Followup-To: comp.lang.java.programmer
    Stefan Ram, Mar 30, 2008
    #1
    1. Advertising

  2. Stefan Ram

    Royan Guest


    > The best place for a question not related to GUI programming
    > is outside of »comp.lang.java.gui«.
    >
    > The best place for a question in the subject header line is
    > a copy in the body of a post.


    Oops, it was done unintentionally

    Thanks a lot for the answer Stefan! I think i'll use interfaces then
    Royan, Mar 30, 2008
    #2
    1. Advertising

  3. Stefan Ram

    Roedy Green Guest

    On Sun, 30 Mar 2008 11:07:37 -0700 (PDT), Royan <>
    wrote, quoted or indirectly quoted someone who said :

    >Thanks a lot for the answer Stefan! I think i'll use interfaces then


    If the constants are used to implement an interface, the put them in
    an interface. Otherwise use classes, and possibly use import static to
    cut the verbosity of using them.
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
    Roedy Green, Mar 30, 2008
    #3
  4. Stefan Ram

    Lew Guest

    Stefan Ram wrote:
    > (1) Constants can only be kept in interfaces,


    Which is known as the Constant Interface Antipattern. It's also not true.

    > classes might have »final fields« or »constant variables«, but these are not
    > called »constants« in Java.


    Acxtually, they are, if they conform to the JLS's rules for what is called a
    "constant variable", which if statis is the same thing as a "constant".

    > JLS3, 4.2.4 mentions constants in classes:
    >
    > »Other useful constructors, methods, and constants are
    > predefined in the classes Float, Double, and Math.«
    >
    > I admit that this contradicts my previous statement (1). But


    Uh, yeah, only completely.

    > this might be the only place, where the JLS3 mentions
    > »constants in classes«.


    Section 15.28, "Constant Expression", provides the definitive definition:
    <http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.28>
    > Qualified names of the form TypeName . Identifier that refer to constant variables


    In other words, a static final variable that refers to a constant.

    It also references section 4.12.4,
    > We call a variable, of primitive type or type String, that is final and
    > initialized with a compile-time constant expression (§15.28) a constant variable.


    Not only are constants used in classes, but it's a bad idea to define
    constants in interfaces.

    --
    Lew
    Lew, Mar 30, 2008
    #4
  5. Stefan Ram

    Royan Guest

    On 31 $B'^'Q'b(B, 02:44, Lew <> wrote:
    > Stefan Ram wrote:
    > > (1) Constants can only be kept in interfaces,

    >
    > Which is known as the Constant Interface Antipattern. It's also not true.
    >
    > > classes might have $B"d(Bfinal fields$B"c(B or $B"d(Bconstant variables$B"c(B, but these are not
    > > called $B"d(Bconstants$B"c(B in Java.

    >
    > Acxtually, they are, if they conform to the JLS's rules for what is called a
    > "constant variable", which if statis is the same thing as a "constant".
    >
    > > JLS3, 4.2.4 mentions constants in classes:

    >
    > > $B"d(BOther useful constructors, methods, and constants are
    > > predefined in the classes Float, Double, and Math.$B"c(B

    >
    > > I admit that this contradicts my previous statement (1). But

    >
    > Uh, yeah, only completely.
    >
    > > this might be the only place, where the JLS3 mentions
    > > $B"d(Bconstants in classes$B"c(B.

    >
    > Section 15.28, "Constant Expression", provides the definitive definition:
    > <http://java.sun.com/docs/books/jls/third_edition/html/expressions.htm...>
    >
    > > Qualified names of the form TypeName . Identifier that refer to constant variables

    >
    > In other words, a static final variable that refers to a constant.
    >
    > It also references section 4.12.4,
    >
    > > We call a variable, of primitive type or type String, that is final and
    > > initialized with a compile-time constant expression ($B!x(B15.28) a constant variable.

    >
    > Not only are constants used in classes, but it's a bad idea to define
    > constants in interfaces.
    >
    > --
    > Lew


    Ok I know the answer to my question, which at least for me appears to
    be fair. I've started to search and found this article:
    http://java.sun.com/j2se/1.5.0/docs/guide/language/static-import.html,
    I know a couple of people have already mentioned static imports but i
    would like to quote the main argument against constant in interfaces:
    *******
    The problem is that a class's use of the static members of another
    class is a mere implementation detail. When a class implements an
    interface, it becomes part of the class's public API. Implementation
    details should not leak into public APIs.
    *******
    So, I'm changing my previous decision to use interfaces as the place
    to keep constants. Instead I will use the following approach:

    package org.megaware.constants;

    public final class Constants {
    public final static int GENERIC_INT = 0;
    // some other generic consts here
    public final static class Network {
    // some other Network consts here
    public final static int DEFAULT_PORT = 55888;
    }

    public final static class Gui {
    // some other GUI consts here
    public final static String APP_TITLE = "Megaware";
    }
    }


    I believe this is the best approach for any types of constants that
    you want to use across your application. Another argument against
    interfaces is that you can extend them as opposed to the final classes
    (note that in my example). Why the possibility to extend interfaces
    that contain constants is bad? In fact it is worse than flying over
    Atlantic on a brutally hard economic seat with something they call
    beef y penne for dinner, brrr... Imagine you have interface called
    IGenericConstants then you decide that you need some network constants
    and extend IGenericConstants with INetworkConstants. As a result all
    your generic constants propagate to network constants container and a
    couple of months later you notice that your junior programmer has
    mistakenly used constants defined in IGenericConstants all over across
    his newly written network class (just because the values suited his
    needs and he didn't want to add new constants to INetworkConstants, so
    why not just using INetworkConstants.CONSTANT_FROM_GENERIC?). Of
    course this wont lead to a bug, or...? Another week later you spend a
    sleepless debug nightmare night. Finally you decide to annotate
    INetworkConstants and ready to tear your hair out because Ben, another
    programmer from network team, has refactored some networking code
    including INetworkConstants interface and overridden
    INetworkConstants.CONSTANT_FROM_GENERIC field with some other value.
    The scenario can be easier to imagine if you take a look on the
    following code:

    public interface IGenericConstants {
    public final static int GENERIC_INT = 0;
    }

    public interface INetworkConstants extends IGenericConstants {
    public final static int GENERIC_INT = 10000; //Ouch thats not what I
    want!
    }

    The approach I suggest:

    public final class Constants {
    public final static int GENERIC_INT = 0;
    // some other generic consts here
    public final static class Network {
    // some other Network consts here
    public final static int GENERIC_INT = 10000;
    }
    }

    prevents from such bug
    Royan, Mar 31, 2008
    #5
  6. Stefan Ram

    Lew Guest

    Royan wrote:
    > So, I'm changing my previous decision to use interfaces as the place
    > to keep constants. Instead I will use the following approach:
    >
    > package org.megaware.constants;
    >
    > public final class Constants {
    > public final static int GENERIC_INT = 0;
    > // some other generic consts here
    > public final static class Network {
    > // some other Network consts here
    > public final static int DEFAULT_PORT = 55888;
    > }
    >
    > public final static class Gui {
    > // some other GUI consts here
    > public final static String APP_TITLE = "Megaware";
    > }
    > }


    You'll probably find it easier to maintain this code if you push your
    'Network' and 'Gui' classes to top level instead of nesting them.

    --
    Lew
    Lew, Mar 31, 2008
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Boba

    ADO and COM contants

    Boba, Feb 26, 2004, in forum: Python
    Replies:
    2
    Views:
    400
  2. sasha
    Replies:
    7
    Views:
    385
    thusa12
    Aug 5, 2008
  3. puzzlecracker
    Replies:
    0
    Views:
    236
    puzzlecracker
    Jul 29, 2008
  4. Kless

    Security in use of contants

    Kless, Aug 17, 2008, in forum: Ruby
    Replies:
    37
    Views:
    311
    David Masover
    Aug 20, 2008
  5. hisan
    Replies:
    1
    Views:
    1,315
    Dan Stromberg
    Jun 25, 2012
Loading...

Share This Page