Usage of static block vs. direct static variable initialization [closed]

Posted on

Problem

Suppose, I have a data access layer class, where I want to specify database connection parameters. Usually, I do it as static variables and initialize it right after definition, e.g. see DB_NAME variable case.

Performing code review, I paid attention that sometimes such logic is implemented with a static block, e.g. see DB_HOST variable case.

public class DAL {

    private static final String DB_NAME = "MY_DB";
    private static final String DB_USER = "DB_ADMIN";
    private static final String DB_HOST;

    static {
        DB_HOST = "127.0.0.1";
    }
}

The questions:

  1. Is there any benefit from using a static block in such specific scenario?
  2. When should I prefer to use a static block over a regular static variable initialization?

P.S. I found a similar question on SO: Why use static blocks over initializing instance variables directly?, but if you have something to add, you’re welcome.

Solution

  1. In such scenario it only obstructs code readability. No benefits.
  2. You should use static block only if static field initialization is not enough (e.g. you should call several methods, or this methods throw checked exceptions).

Just created 2 sample classes:

public class Static {
    public static String s = "qwe";
}

public class StaticBlock {
    public static String s;
    static {
        s = "qwe";
    }
}

And using javap -c we can see bytecodes of this classes:

Compiled from "Static.java"
public class Static {
  public static java.lang.String s;

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

  static {};
    Code:
       0: ldc           #2                  // String qwe
       2: putstatic     #3                  // Field s:Ljava/lang/String;
       5: return
}

Compiled from "StaticBlock.java"
public class StaticBlock {
  public static java.lang.String s;

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

  static {};
    Code:
       0: ldc           #2                  // String qwe
       2: putstatic     #3                  // Field s:Ljava/lang/String;
       5: return
}

As you can see, bytecodes are identical 🙂

UPD: Its getting more interesting! If we add final modifier to our static field, bytecodes will be different.

public class Static {
    public static final String s = "qwe";
}

public class StaticBlock {
    public static final String s;
    static {
        s = "qwe";
    }
}

We will have:

Compiled from "Static.java"
public class Static {
  public static final java.lang.String s;

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

Compiled from "StaticBlock.java"
public class StaticBlock {
  public static final java.lang.String s;

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

  static {};
    Code:
       0: ldc           #2                  // String qwe
       2: putstatic     #3                  // Field s:Ljava/lang/String;
       5: return
}

I found a little bit of explanation in this question.

Leave a Reply

Your email address will not be published. Required fields are marked *