Why use static blocks over initializing instance variables directly?

前端 未结 5 2012
情歌与酒
情歌与酒 2021-01-04 20:15

Why would I use a static block:

static {
   B = 10;
}

over:

Integer B = 10;

What is the advantages/disadv

相关标签:
5条回答
  • 2021-01-04 20:34

    Actually, if you have

    private static Integer B = 10;
    

    The compiler will translate to, basically:

    private static Integer B;
    static {
        B = 10;
    }
    

    The thing with static blocks is that you can use the whole language and not just expressions to do initialisation. Imagine you need an array with a bunch of multiples of 7. You could do:

    private static Integer[] array;
    static {
        array = new Integer[1000];
        for (int i = 0; i < 1000; i++) {
            array[i] = 7 * i;
        }
    }
    

    Anyway, you could also do it this way:

    private static Integer[] array = initArray();
    private static Integer[] initArray() {
        Integer[] result = new Integer[1000];
        for (int i = 0; i < 1000; i++) {
            result[i] = 7 * i;
        }
        return result;
    }
    
    0 讨论(0)
  • 2021-01-04 20:40

    You should only use a static initializer block, when it is necessary. For example, sometimes you need to do several steps to calculate the final value of the field. In this case you have two opportunities: write a method that calculates the value and declare your field as static final Integer B = calculateB(), or use an initializer block:

    static final Integer B;
    static {
      int temp = ...;
      ...
      B = temp;
    }
    

    In this case I prefer the static block, because a method might be confusing (other developers might try to call it, although it is only meant to be called once during initialization).

    The same applies for instance fields as well, although normally one would avoid the unusual initialization block and simply write the initialization logic for fields into the constructor (which is of course not possible for static fields).

    0 讨论(0)
  • 2021-01-04 20:40

    The static block allows you to write more complex initialization logic for the attribute, whereas the one-line initialization limits you to a single expression.

    Be aware that initialization blocks exist for both instance and static attributes, for example this one initializes an instance attribute at instantiation time:

    private int a;
    { a = 10; }
    

    Whereas this one initializes a static attribute at class loading time:

    private static int b;
    static { b = 10; }
    

    The initialization procedure is explained in detail in here, as part of the JVM specification.

    0 讨论(0)
  • 2021-01-04 20:49

    First your Integer B appears to be a non static member variable and can not be accessed from a static block. So you either meant to write

    //Initialize static field
    static {
       B = 10;
    }
    static Integer B = 10;
    

    or

    //Initialize member field
    {
       B = 10;
    }
    Integer B = 10;
    

    In both cases you can use it to initialize B with a value that could cause an exception or do something more complex without writing a special method for init.

    {
       try{
          B = thisWillThrowAFileNotFound();
       }catch(FileNotFoundException){
          B = 10;//Set default
       }
    
    }
    
    0 讨论(0)
  • 2021-01-04 20:51

    Static initialization happens when the class is loaded.

    E.g. it would be a proper place to initialize member variables that could otherwise need synchronization due to access by multiple threads.

    The second case would happen if you called the constructor explicitely.

    The usage is different.
    E.g. you would prefer the second case for lazy loading of something (if you put it in static initializers it will always load and perhaps you would not want that-prefer to lazy load it)

    0 讨论(0)
提交回复
热议问题