5
  • First example

    public class MyClass {
        final int x = 2;
    }
    

    x is

    1. final which means it can never be set after initialization.
    2. Initialized at declaration which means it can't have a different value assigned to it later (even in the constructor).
    3. fixed (regardless of the instance) because its value can't be changed in the constructor (or anywhere else really).
  • Second example

    public class MyOtherClass {
        static final int x = 3;
    }
    

    x is

    1. final which means it can never be set after initialization.
    2. Initialized at declaration which means it can't have a different value assigned to it later.
    3. a static field and the value will always remain the same regardless of the instance.
    4. constant because it is both static and final.

My questions are

What are the differences between both? (excluding creation time)

Am i missing something?

  • This is my first question so, feel free to comment on the style and if i can improve it. –  Jul 19 '15 at 14:23
  • If you initialise a final variable at declaration time then it should probably be static... – assylias Jul 19 '15 at 14:26
  • 1
    One potential difference is a `static final` primitive is not used during runtime. The compiler would 've replaced all occurances of it with the value during compilation making it more optimised. – Codebender Jul 19 '15 at 14:27
  • 1
    @Codebender: that applies to the non-`static` variable as well, and even for local variables. *All* `final` variables which are initialized with a compile-time constant are compile-time constants and never accessed by ordinary Java code. – Holger Jul 23 '15 at 19:13

4 Answers4

5

The differences between x in MyClass and MyOtherClass are:

  • the first can only be accessed via a MyClass instance and there can be multiple copies of the constant.

  • the second can be accessed without MyOtherClass instance and only one copy can exist.

In your example, there is no practical difference1 between having one or multiple instances of the constant. However consider this:

public class YetAnotherClass {
    final int x;

    public YetAnotherClass(int x) {
        this.x = x;
    }
}

... which shows how an instance constant can have different values in different instances.


1 - That is an overstatement. First, static final int x = 3; is declaring a compile-time constant, and a compile-time constant can be used in a switch case expression, where a non-compile-time constant can't. Second the non-static version of the constant will occupy space in each and every instance of MyClass. Finally, there will be differences in behaviour if you are daft enough to try to change the constants using reflection. (Just don't do it ...)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Could escape analysis / JIT optimizations cache value of x when only `final int x` is used? – TheLostMind Jul 19 '15 at 14:50
  • Possibly. However, the code would still need to work if the constant was accessed using reflection, so the field would probably need to be allocated anyway. – Stephen C Jul 19 '15 at 15:17
  • makes sense. This would then apply to `static final int` as well.. – TheLostMind Jul 19 '15 at 15:21
  • 1
    In the `static final` case, if the constant qualifies as a compile-time constant, the optimization is performed (in part) by the bytecode compiler. – Stephen C Jul 19 '15 at 16:09
  • It seems to be an often overlooked thing of the Java programming language, maybe because some tutorials get it wrong as well, but there is no difference between `static` variables and non-`static` variables when it comes to compile-time constant behavior. *All* `final` variables, which are initialized with a compile-time constant, are compile-time constants as well and never read by ordinary Java code. This applies to local variables as well and *yes*, that means you can use local variables in `case` clauses of a `switch` statement, if they are compile-time constants. – Holger Jul 23 '15 at 19:19
  • @Holger - Yes. See footnote 1. :-) – Stephen C Jul 23 '15 at 22:33
1

Although final, the JVM does not make any optimizations or assumptions, so each instance of the class will have an instance of x. If you declare the member static, each instance of the class will share the same instance of x because it's statically allocated. Moreover, as written (x has package visibility), other classes can potentially access x statically, i.e., without having an instance of the class available.

Giovanni Botta
  • 9,626
  • 5
  • 51
  • 94
1

If you create multiple instances of both type of classes then,

In First scenario all object of MyClass would have own final x field.

Where as in second scenario all object of MyOtherClass would have points to one final x class field as because it is static in nature.

Subhrajyoti Majumder
  • 40,646
  • 13
  • 77
  • 103
1

Difference : Static belongs to class So You can access it without any instance of the class and hence only one copy of it.

While for accessing second one you need instance of an class to access it so you can have as many copy of non static final Object as it belongs to Object.

You can Verify with Byte Code: For Static

Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return

For Non-Static Final

Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: iconst_2
         6: putfield      #2                  // Field x:I
         9: return
      LineNumberTable:

As you can see it's has putfield Which sets the value of the field identified in objectref (a reference to an object)

Ankur Anand
  • 3,873
  • 2
  • 23
  • 44
  • 3
    It baffles me that people think that it is a good idea to explain the Java language to beginners by showing them bytecode sequences. – Stephen C Jul 19 '15 at 14:45
  • 2
    @StephenC - defending this answer.. This answer could be useful for others (intermediate level?) as well :).. Not just the OP.. – TheLostMind Jul 19 '15 at 14:47
  • 1
    @StephenC It's just for everyone :) – Ankur Anand Jul 19 '15 at 14:48
  • 2
    No it is not for everyone. It is for people who understand bytecodes. That precludes beginners, like the OP (I expect). Besides, the OP is asking about differences **excluding creation time**, and surely this is about creation time ... – Stephen C Jul 19 '15 at 14:54
  • 1
    "While for accessing second one" Second one is the static one. but, I get your point. I also as mentioned by @StephanC do not understand bytecode. but, it might be useful for others. –  Jul 19 '15 at 16:00