4

I was experimenting with initialisation of different type of variables in Java. I can initialise final variable (e.g. final int b) and static variable (e.g. static int c) in constructor but I can't initialise static final variable (e.g. static final int d) in constructor. The IDE also display error message.

Why might Java not allow initialisation of static final variable in constructor?

public class InitialisingFields {
    int a;
    final int b;
    static int c;
    static final int d;

    InitialisingFields(){
        a = 1;
        b = 2;
        c = 3;
        d = 4;
    }

    public static void main(String[] args) {
        InitialisingFields i = new InitialisingFields(); 
    }

}

Error message:

Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - cannot assign a value to final variable d
    at JTO.InitialisingFields.<init>(InitialisingFields.java:22)
    at JTO.InitialisingFields.main(InitialisingFields.java:26)
Java Result: 1
halfer
  • 19,824
  • 17
  • 99
  • 186
Thor
  • 9,638
  • 15
  • 62
  • 137

3 Answers3

6

A static variable is shared by all instances of the class, so each time to create an instance of your class, the same variable will be assigned again. Since it is final, it can only be assigned once. Therefore it is not allowed.

static final variables should be guaranteed to be assigned just once. Therefore they can be assigned either in the same expression in which they are declared, or in a static initializer block, which is only executed once.

Eran
  • 387,369
  • 54
  • 702
  • 768
3

Because

  1. the static variable must be set whether or not you create an instance of the class, so it must happen outside a constructor;
  2. it can only be set once, so you couldn't change its value the second time you create an instance.

You can read a static final variable before it is initialised, and its value would be the default value for the type, e.g.

class Nasty {
  static final int foo = yuk();
  static final int bar = 1;

  static int yuk() {
    System.out.println(bar);  // prints 0.
    return 99;
  }
}

However, this is a bizarre case, and almost certainly not what is desired.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • Being a static int, wouldn't this variable be initialized to 0 even before an instance is created ? – Arnaud Apr 06 '16 at 14:22
  • 1
    You can read it before it is assigned, and its value would be zero, yes. However, that is a bizarre case and almost certainly undesirable. – Andy Turner Apr 06 '16 at 14:23
0

You can't reassign final field. Final means that variable can't be changed. Remove final and you are ok.

edasssus
  • 331
  • 4
  • 15
  • Nope. That's not the answer. – TheLostMind Apr 06 '16 at 14:18
  • @TheLostMind Actually… it's exactly what causes the error message. – Biffen Apr 06 '16 at 14:20
  • @Biffen - `static final` fields can be initialised in a `static` block and instance level final fields can be initialised in an instance level block or constructor.. This is not related to only the `final` property of a field. The answer should involve the fact that the field is `static`. – TheLostMind Apr 06 '16 at 14:27
  • @TheLostMind Agreed. But the answer isn't *wrong* per se, IMHO. – Biffen Apr 06 '16 at 14:28
  • @Biffen - Look at the other 2 answers.. They stress on the fact that the field is `static` and how that affects the OPs code. This answer is just a *general statement* (which is not wrong, but doesn't answer the OPs question accurately) IMHO :) – TheLostMind Apr 06 '16 at 14:32