constant : Java Glossary

*0-9ABCDEFGHIJKLMNOPQRSTUVWXYZ (all)

constant
Java is sloppy in its terminology. It muddles together the concepts of literals and constants.
Types of Constants Importing Constants
Compile Time vs Load Time Constants Rules of Thumb
Who Cares? Links

Types of Constants

There are seven different animals loosely called constants:
  1. Literals

    e.g.
    42, "abc"
    You may use byte, short, char and int literals as switch case labels. However, longs and Strings are not supported.
  2. Compile Time Constants

    or just plain compile constants, Officially known as compile-time constant expressions these are static finals whose value
    // constants known at compile time
    static final int ARMS = 2;
    static final int LIMBS = ARMS * 2;
    These can be used as switch case labels, subject, of course, to the usual byte, short, char and int-only restriction.
  3. Load-Time Class Constants

    or just plain load constants, static finals whose value is not known
    static final int SERIALNUMBER = ++generator;
    These cannot used in switch case labels. All the variables in an interface are implicitly static finals. They may be either compile time constants or load time constants.
  4. Instance Constants

    instance finals whose value is not known until object instantiation time, e. g. These too cannot used as switch case labels. It is sometimes possible for an instance constant to be evaluated at compile time. In that case it is treated like a literal, much like a static compile-time constant. You can use a compile-time local int constant as a case label.
  5. Local Constants

    stack finals whose value is not known until the method executes, e. g.
    final int bottomLine = getTax();
    These too cannot used as switch case labels.
    final int LEGS = 2;
    As in the example above, it is sometimes possible for a local constant to be evaluated at compile time. In that case it is treated like a literal, much like a static compile-time constant. You can use a compile-time local int constant as a case label.
  6. Parameter Constants

    A parameter marked final. This indicates the called method will never change its local copy of the passed parameter.
  7. enum Constants

    The names of the possibilities for an enum. These are under-the-hood static finals evaluated at load time, but through the magic of Java, you can use them as if they were known at compile time, e.g. as case labels.
Oracle’s coding conventions require constants to have names all in capital letters.

A key point that bears repeating is that constant references are constrained to point to the same object for their entire lifetimes. However, the object itself they point to is not necessarily constant. Its fields may or may not change. Whether they can change or not has nothing to do with whether the references that point to them are final.

See literals for how to specify Strings, integers etc. final in Java means a variable that will not change after it is initialised. The associated keywords with a named constant are static final. Constant values have alphabetic names, e.g. Math.PI. For most practical purposes constants in Java are called static final variables. However, only those static final variables whose value can be computed at compile time are true constants. Only true constants can be used as case labels. Note that constants always need to be qualified with the classname except in code inside the class. To further confuse the matter, the language specification refer to static final variables as values not constants.

Constants can be defined in both classes and interfaces. Interfaces without methods can be used simply as namespaces for related constants defined within them. For example, an interface MyConstants might define MAX_ROWS and MAX_COLS, accessed in other classes as MyConstants. MAX_ROWS and MyConstants.MAX_COLS. To access the constants in such an interface by unqualified name (e.g., MAX_ROWS) in methods of another class MyClass, you can make MyClass implement MyConstants. However, this trick comes with some costs, so should be used carefully. First, the constants become non-private class members of MyClass. Other classes can become dependent on MyClass implementing MyConstants — an implementation detail. Second, other classes that access those public members depend on the values in the last-compiled version of MyClass, which can differ from the current values in the interface. Third, if MyClass implements multiple such interfaces, ambiguities can be created in MyClass during maintenance of those other interfaces.

Compile Time vs Load Time Constants

Compile time constants are evaluated at compile time and treated as if they were literals, in-lined in the code. It is not totally obvious which expression Java can evaluate at compile time. Compile time and load time constants look similar. Both are static final. Here are some examples to help:
Compile Time vs Load Time Constants
Expression Compile Time
or
Load Time
public static final int DAYS_IN_WEEK = 7;
Compile Time
public static final int SECONDS_PER_HOUR = 60 * 60;
Compile Time
public static final String COPYRIGHT = "Copyright (c) " + "2005";
Compile Time
Compile Time
public static final int POSTAGE_IN_CENTS = 60;
public static final int HANDLING_IN_CENTS = 500;
public static final int BIGGER_IN_CENTS =
( POSTAGE_IN_CENTS > HANDLING_IN_CENTS )
? POSTAGE_IN_CENTS
: HANDLING_IN_CENTS;
Compile Time
Compile Time
Load Time
public static final Random wheel = new Random();
public static final int CARD = wheel.nextInt( 52 );
Load Time
Please pass on on more examples you have for the table above, particularly ones with surprising results.

To find out whether other expressions will be evaluated at compile time, you can use a decompiler to see what sort of code was generated for the initialisation.

Who Cares?

There are five reasons why it is important to you, the programmer, whether a constant is evaluated at compile time or load time.
  1. compile time int constants can be used as case labels. Load time constants cannot.
  2. There are various restrictions on accessing static variables, e.g. static references from enum constructors are not permitted. Compile time constants are generally immune from these restrictions since they are treated just like literals.
  3. Since the values of all compile time constants are computed at compile time, they are all known before any load time static initialisation is done. This lets you get away with forward references to compile-time constants.
  4. compile-time constants are in-lined, just as if you had specified a literal every time they were referenced. This means if class A uses class B’s compile time constants and you change the values of those constants in class B, class A still has the old values embedded all through it, in-lined, until it is recompiled to refresh the values. There is no record in class A where those literals came from. Thus, it is not sufficient for class A to just load a fresh copy of B’s class file. This is why you periodically must do clean compiles to recompile the universe.
  5. Compile time constants generate faster, leaner code. Get in the habit of adding final to any variable whose value is computed only once. It is good documentation, makes code easier to follow, prevents bugs and makes the code faster.
The JLS tends to use the term constant to refer only to interface constants which can be either compile time or run time, or to enum constants.

Importing Constants

If you want to use constants outside their class:

Rules of Thumb

If you follow these rules of thumb, you will get by without having to fully understand constants:

Gotchas

You cannot define static finals in an enum and use them in the enum constructors. You can put them in a separate private static nested class.


This page is posted
on the web at:

http://mindprod.com/jgloss/constant.html

Optional Replicator mirror
of mindprod.com
on local hard disk J:

J:\mindprod\jgloss\constant.html
logo
Please the feedback from other visitors, or your own feedback about the site.
Contact Roedy. Please feel free to link to this page without explicit permission.

IP:[65.110.21.43]
Your face IP:[54.204.108.121]
You are visitor number