0
\$\begingroup\$

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.

\$\endgroup\$

closed as off-topic by 200_success, Ludisposed, VisualMelon, Toby Speight, IEatBagels Feb 6 at 18:02

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – 200_success, Ludisposed, VisualMelon, Toby Speight, IEatBagels
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    \$\begingroup\$ A static block is often used to fill a constant map; when a single expression is not feasible. Above it could only be a self-invented stylistic issue, maybe DB_HOST is intended to be replaced or always fixed. \$\endgroup\$ – Joop Eggen Feb 6 at 12:00
4
\$\begingroup\$
  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.

\$\endgroup\$
  • \$\begingroup\$ Regarding «You should use static block only if static field initialization is not enough», in such cases I write a method, which returns a desired value for the static variable. Is usage a static block a better alternative than approach I use? \$\endgroup\$ – Mike B. Feb 6 at 12:01
  • \$\begingroup\$ @MikeB. There is one major difference between them: static block is called only once by VM; static method could be called several times by users. Basically, in case of method, you just 'cache' method's result into variable. If this result is constant, there is no sense calling this method again ever, because you already have computed value in variable (and in this case introducing method could confuse developers, so they can call this method, instead of using variable). If method result is not constant and it makes sense to call this method later on, its absolutely ok to have this method) \$\endgroup\$ – Flame239 Feb 6 at 12:11
  • 1
    \$\begingroup\$ @MikeB. also take a look at another opinions: stackoverflow.com/questions/11618551/… \$\endgroup\$ – Flame239 Feb 6 at 12:13

Not the answer you're looking for? Browse other questions tagged or ask your own question.