39

Why are Java constants declared static?

class Foo {
    static final int FII = 2 ;
}

In this example I understand the use of final, But why does it have to be static? Why should it be a class variable and not an instance variable?

Dmitriy Popov
  • 2,150
  • 3
  • 25
  • 34
Vaibhav
  • 435
  • 1
  • 7
  • 11
  • 9
    Why would you want more than one instance to have its own copy of `FII`? – Bart Kiers Nov 11 '11 at 11:22
  • 1
    I can declare `final int FII = 2;` just fine. – Jon Lin Nov 11 '11 at 11:24
  • 1
    @JonLin: You can, but you shouldn't since it doesn't add value but only increases memory usage. Exception would be initialization of the constant in the constructor call - then each instance could have it's own constant value (constant after the constructor run) and could have a value like 'constructionTime' or similar. – Mathias Bader Aug 02 '15 at 08:22

4 Answers4

114

If a constant is not static, Java will allocate a memory for that constant in every object of the class (i.e., one copy of the constant per object).

If a constant is static, there will be only one copy of the constant for that class (i.e., one copy per class).

Therefore, if the constant has only one value, it should declared static.

If the constant might have different value for each object, for example the creation time of the object, it should not be declared static.

wannik
  • 12,212
  • 11
  • 46
  • 58
  • 1
    "If the constant might have different value for each object" then by definition it is not a constant. – Jezor Jan 31 '20 at 10:57
  • 2
    @Jezor No, it's a constant. It's ok for objects of the same class to have the same constant with different values. " for example the creation time of the object". – Rain Mar 26 '20 at 05:36
  • I see. Calling it a "constant" might be _technically correct_ but sounds rather strange. With this, every immutable object declared `final` is a constant, no matter the scope. – Jezor Apr 02 '20 at 13:39
  • @Rain Actually, as per java specs, A variable of primitive type or type String, that is final and initialized with a compile-time constant expression (§15.28), is called a constant variable. Constants during creation of the objects beat the purpose of Compile time – sss Apr 24 '20 at 07:16
  • @SameerSinha It doesn't matter if a constant value was defined at compile time or run time, that doesn't change the fact that it's a constant(a value that cannot be changed after it's been initialized). For example, in PHP language we have `const` and we have `define` one will be evaluated at compile time and the other at run time but most importantly they both create a constant. – Rain Apr 24 '20 at 07:59
  • If so then when the object was released then the constant property value still in memory, right? – William Hu Dec 14 '22 at 01:56
45

If it could vary by the instance of a class, then it's clearly not a constant. What would it mean to get a different value of pi for each instance of Math (not that Math even allows instances to be constructed)? Or a different case insensitive ordering for each instance of String?

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
13

It is simply so that you can access them without an instance of that class.

Requiring that an instance be created just to access constant fields is a bit of a waste of resources.

Mat
  • 202,337
  • 40
  • 393
  • 406
3

Why are java constants declared static ?

Technically they aren't, JLS defines constants as final constant expression (which are referred to but not formally in java as compile time constant expression). meaning a variable declared final which is initialized with a constant expression, meaning without static - https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.4

A constant variable is a final variable of primitive type or type String that is initialized with a constant expression.

But the specification does not address anything regarding Constant Types which java is all about, Classes and Objects - so Jon Skeet answer regarding Math example is missing one part, Math class is considered constant because you cannot instantiate it by making its constructor private.

http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/lang/Math.java -

public final class Math {


    /**

     * Don't let anyone instantiate this class.

     */

    private Math() {}

    public static final double PI = 3.14159265358979323846;

}

To support the Type itself being constant you need to make sure its state is also constant, but only for its members who are mutable and are exposed to changes from outside the type.

For example the literal PI is made public so it's available from outside the type. So to make sure it wont be changed from the outside it is made final, and also static so it will be part of the Class Class<Math> instance and could be exposed for use outside Math without the class being (explicitly) instantiated.

Dopefish
  • 111
  • 1
  • 1
  • 7