14

This is from Effective Java

Programs that use the int enum pattern are brittle. Because int enums are compile-time constants, they are compiled into the clients that use them.

Can some one explain why the int enum pattern is called compiled type constant and what is meant by compiled into the clients?

Here s' an example of such a constant :

public static final int APPLE_FUJI = 0;
Geek
  • 26,489
  • 43
  • 149
  • 227

2 Answers2

20

Suppose you have two files:

Foo.java:
public class Foo
{
    public static final int SOMETHING = 1;
}

Bar.java:
public class Bar
{
    public static void main(String[] args)
    {
        System.out.println(Foo.SOMETHING);
    }
}

Compile them both, run java Bar and it will print out 1.

Now change Foo.java so that SOMETHING is 2, and recompile just Foo.java. Rerun java Bar and it will still print 1. The constant value will be copied to every piece of code that uses it, rather than asking for the value from Foo at execution time.

In practice, if you recompile everything any time anything changes, this isn't a problem.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • isn't Java a dynamic binding language ? Why do we have to recompile everything ? – Geek Aug 02 '12 at 08:15
  • 3
    @Geek You don't **have** to do it. But it is highly recommended in order to avoid what Jon Skeet is describing above. This behaviour of the Java compiler is a bad one, in my opinion. That constant should only be stored in `Foo.class`. `Bar` should ALWAYS get that constant from `Foo`. Like many other semi-stupid things in a language: it won't be changed because maybe it will break existing code. What a bunch of cry-babies... – Radu Murzea Aug 02 '12 at 08:19
  • @Geek: You'd have to define "dynamic binding language" for me to answer your first question. But the reason you have to recompile in this case is because the language specification explicitly calls out constant expressions like this. – Jon Skeet Aug 02 '12 at 08:30
  • @Jon dynamic binding in the sense that the clients of Foo should ask Foo for any constant belonging to Foo at run time (ie dynamic). – Geek Aug 02 '12 at 08:41
  • 2
    Types (classes) are bound dynamically but, as mentioned, constants are not. It's an optimization. If you want to preserve dynamic typing use real enums instead of int constants. – Adriaan Koster Aug 02 '12 at 09:38
6

The value '0' itself will be built into the .class files during compilation. If you then change that value, you have to recompile everything that uses it, including any client's code that uses your application/library.

If you don't, you won't get a warning, but rather incorrect behaviour.

If your compile-time constant is used solely in your code then it's less of a problem, assuming a complete clean/build cycle. If your code then reaches a wider audience then this becomes more of a problem.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440