lor
lor

Reputation: 137

Java - Static initializers versus default values for static variables

I was doing some reading on Java classes, and I came upon static initializers. However, I can't see the point of using them when you can just set default values in the first place. For example,

static int a;
static {
    a = 5;
} 

versus

static int a = 5

in a class definition.

Is there a difference between these two? If not, when would you use static initializers versus default values?

Upvotes: 3

Views: 329

Answers (6)

ChrisCantrell
ChrisCantrell

Reputation: 3853

There is no difference. In fact, the compiler changes the short form into a declaration-plus-static-block for you. If you run "javap" on the resulting classes they are identical.

The "javap" tool that comes in the JDK with the compiler is a great way to look at the code and know exactly "what is the difference"!

public class Test {

    //static int a= 5;

    static int a;
    static {
        a = 5;
    }

}

javap -c Test.class

Compiled from "Test.java"
public class Test {
  static int a;

  static {};
    Code:
       0: iconst_5
       1: putstatic     #10                 // Field a:I
       4: return

  public Test();
    Code:
       0: aload_0
       1: invokespecial #15                 // Method java/lang/Object."<init>":()V
       4: return
}

Upvotes: 1

saurzcode
saurzcode

Reputation: 837

Is there a difference between these two?

No, In this case there is no difference as in your static initializer block you are just assigning a value to a variable.But in some very complex scenarios this may not be the case.

If not, when would you use static initializers versus default values?

This works well when the initialization value is available and the initialization can be put on one line. However, this form of initialization has limitations because of its simplicity. If initialization requires some logic (for example, error handling or a for loop to fill a complex array), simple assignment is inadequate.

A static initialization block is a normal block of code enclosed in braces, { }, and preceded by the static keyword. Here is an example:

static {
    // whatever code is needed for initialization goes here
}

A class can have any number of static initialization blocks, and they can appear anywhere in the class body. The runtime system guarantees that static initialization blocks are called in the order that they appear in the source code.

There is an alternative to static blocks — you can write a private static method:

class Whatever {
    public static varType myVar = initializeClassVariable();

    private static varType initializeClassVariable() {

        // initialization code goes here
    }
}

The advantage of private static methods is that they can be reused later if you need to reinitialize the class variable.

Upvotes: 1

UVM
UVM

Reputation: 9914

Is there a difference between these two?

No, in this case the code that you shared

If not, when would you use static initializers versus default values?

There are many scenarios, you need static initializers like , in case your application needs only one instance of an object. You can use static block in which you can implement the logic for how to get the single instance.

Upvotes: 0

awksp
awksp

Reputation: 11867

If memory serves, there's no effective difference. However, a static block can be helpful for readability purposes, or for doing tasks which take multiple steps. Take this (bad) example from my freshman year of college:

// Pattern of initial memory values, used during critter file parsing
private static Pattern memoryMatcher;
private static Pattern sugarMatcher;
private static Pattern generalMemoryMatcher;
// Block to create memoryMatcher
static {
    final StringBuilder builder = new StringBuilder();

    // Append each of the sugar values, separated by a pipe
    builder.append("(?i)(");
    for (final Sugar sugar : Sugar.values()) {
        builder.append(sugar.toString());
        builder.append("|");
    }

    // Replace final pipe with close parenthesis and create sugarMatcher
    sugarMatcher = Pattern.compile(builder.replace(
            builder.length() - 1, builder.length(), ")").toString());

    // Append some stuff to catch ": <number>" and whitespace, then
    // create memoryMatcher
    memoryMatcher = Pattern.compile(builder.insert(4, "(")
            .insert(builder.length() - 1, "|mem\\[-?\\d+\\]")
            .append(":\\s*-?\\d*|\\s*)").toString());

    // Should match mem[<number>]
    generalMemoryMatcher = Pattern.compile("mem\\[-?\\d+\\]");
}

Prior to Java 8, the code that involves the for loop I don't believe would be able to work as part of a single assignment. While Java 8's streams would let me do this as part of an assignment, the work for memoryMatcher and sugarMatcher would replicate some work, which isn't really desirable.

Upvotes: 1

user207421
user207421

Reputation: 310860

Is there a difference between these two?

Not in the example you posted. However the static {} form can include arbitrary code including loops, try/catch, etc.

If not, when would you use static initializers versus default values?

When you need the extra features.

Upvotes: 2

Thilo
Thilo

Reputation: 262474

No difference.

when would you use static initializers versus default values?

When the code to evaluate the expression is more complex, especially if exceptions are involved.

static int a ;
static {
    String x = System.getProperty("abc");
    try{  
       a = Integer.parseInt(x);
    }
    catch (Exception e){
       throw new IllegalArgumentException
          ("missing or invalid system property 'abc': "+x);
    }
}

But then it is probably best practice to move the code into a private static method.

final static int a = complexCalculation();

Upvotes: 4

Related Questions