18

The following code, when executed, prints nitesh null instead of the expected nitesh 130. Why isn't n initialized before executing the static block?

class test
{
      static
      {
             System.out.println(test.str+"   "+test.n);
      }
      final static String str="nitesh";
      final static Float n=130f;
      public static void main(String []args)
      {
      }
}
Bakuriu
  • 85,459
  • 18
  • 168
  • 202
Nits
  • 867
  • 2
  • 8
  • 10
  • 8
    [`This question should be closed because it is answered by JonSkeet`](http://meta.stackexchange.com/a/13300/256679) – user3459110 Jun 13 '14 at 12:28

1 Answers1

25

str is a compile-time constant - n is not, because it's of type Float. If you change it to final static float n = 130f then you'll see the value in the static initialization block.

So currently, in the static initializer block, the value of str is actually being inlined - your code is equivalent to:

System.out.println("nitesh   "+test.n);

From JLS section 15.28 (constant expressions):

A constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following: [...]

Float is not a primitive type.

Additionally, even without the inlining, the constant variable str is initialized before any of the static initializer blocks are executed. From section 12.4.2 of the JLS (class initialization details):

  • ...
  • Then, initialize the static fields of C which are constant variables (§4.12.4, §8.3.2, §9.3.1).
  • ...
  • Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.
Jon Skeet
  • 1,261,211
  • 792
  • 8,724
  • 8,929
  • @TAsk: No, that's in no way a shorter version of what I said. It's all to do with which variables are actually compile-time constants, whose values are inlined wherever they're used. – Jon Skeet Jun 13 '14 at 10:28
  • Oppss!! Agree.Need to spend more time With JavaDoc. _Thanks for the clarification._ (_By the way +10 for your answer_) – ΔȺȾΔ Jun 13 '14 at 10:33
  • But Float is a primitive type http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html – Arijit Jun 13 '14 at 10:37
  • 6
    @Arijit: No, `float` is a primitive type. `Float` is a wrapper type. They're different. – Jon Skeet Jun 13 '14 at 10:38
  • Does static initializer block run before `static final` variables are initialized?? Why? so surprised... – ikh Jun 13 '14 at 11:25
  • @ikh: See my quote: *constant* variables are initialized first, but then static initializers (including both static field initializers and static initializer blocks) are run in textual order. – Jon Skeet Jun 13 '14 at 11:31
  • 1
    Which means that moving the static block after the declarations also fixes the issue. – JAB Jun 13 '14 at 14:17