Static Initialization Blocks

前端 未结 14 1253
暗喜
暗喜 2020-11-22 01:56

As far as I understood the \"static initialization block\" is used to set values of static field if it cannot be done in one line.

But I do not understand why we ne

相关标签:
14条回答
  • 2020-11-22 02:32

    The non-static block:

    {
        // Do Something...
    }
    

    Gets called every time an instance of the class is constructed. The static block only gets called once, when the class itself is initialized, no matter how many objects of that type you create.

    Example:

    public class Test {
    
        static{
            System.out.println("Static");
        }
    
        {
            System.out.println("Non-static block");
        }
    
        public static void main(String[] args) {
            Test t = new Test();
            Test t2 = new Test();
        }
    }
    

    This prints:

    Static
    Non-static block
    Non-static block
    
    0 讨论(0)
  • 2020-11-22 02:35

    You first need to understand that your application classes themselves are instantiated to java.class.Class objects during runtime. This is when your static blocks are ran. So you can actually do this:

    public class Main {
    
        private static int myInt;
    
        static {
            myInt = 1;
            System.out.println("myInt is 1");
        }
    
        //  needed only to run this class
        public static void main(String[] args) {
        }
    
    }
    

    and it would print "myInt is 1" to console. Note that I haven't instantiated any class.

    0 讨论(0)
  • 2020-11-22 02:38

    I would say static block is just syntactic sugar. There is nothing you could do with static block and not with anything else.

    To re-use some examples posted here.

    This piece of code could be re-written without using static initialiser.

    Method #1: With static

    private static final HashMap<String, String> MAP;
    static {
        MAP.put("banana", "honey");
        MAP.put("peanut butter", "jelly");
        MAP.put("rice", "beans");
      }
    

    Method #2: Without static

    private static final HashMap<String, String> MAP = getMap();
    private static HashMap<String, String> getMap()
    {
        HashMap<String, String> ret = new HashMap<>();
        ret.put("banana", "honey");
        ret.put("peanut butter", "jelly");
        ret.put("rice", "beans");
        return ret;
    }
    
    0 讨论(0)
  • 2020-11-22 02:40

    static block is used for any technology to initialize static data member in dynamic way,or we can say for the dynamic initialization of static data member static block is being used..Because for non static data member initialization we have constructor but we do not have any place where we can dynamically initialize static data member

    Eg:-class Solution{
             // static int x=10;
               static int x;
           static{
            try{
              x=System.out.println();
              }
             catch(Exception e){}
            }
           }
    
         class Solution1{
          public static void main(String a[]){
          System.out.println(Solution.x);
            }
            }
    

    Now my static int x will initialize dynamically ..Bcoz when compiler will go to Solution.x it will load Solution Class and static block load at class loading time..So we can able to dynamically initialize that static data member..

    }

    0 讨论(0)
  • 2020-11-22 02:41

    So you have a static field (it's also called "class variable" because it belongs to the class rather than to an instance of the class; in other words it's associated with the class rather than with any object) and you want to initialize it. So if you do NOT want to create an instance of this class and you want to manipulate this static field, you can do it in three ways:

    1- Just initialize it when you declare the variable:

    static int x = 3;
    

    2- Have a static initializing block:

    static int x;
    
    static {
     x=3;
    }
    

    3- Have a class method (static method) that accesses the class variable and initializes it: this is the alternative to the above static block; you can write a private static method:

    public static int x=initializeX();
    
    private static int initializeX(){
     return 3;
    }
    

    Now why would you use static initializing block instead of static methods?

    It's really up to what you need in your program. But you have to know that static initializing block is called once and the only advantage of the class method is that they can be reused later if you need to reinitialize the class variable.

    let's say you have a complex array in your program. You initialize it (using for loop for example) and then the values in this array will change throughout the program but then at some point you want to reinitialize it (go back to the initial value). In this case you can call the private static method. In case you do not need in your program to reinitialize the values, you can just use the static block and no need for a static method since you're not gonna use it later in the program.

    Note: the static blocks are called in the order they appear in the code.

    Example 1:

    class A{
     public static int a =f();
    
    // this is a static method
     private static int f(){
      return 3;
     }
    
    // this is a static block
     static {
      a=5;
     }
    
     public static void main(String args[]) {
    // As I mentioned, you do not need to create an instance of the class to use the class variable
      System.out.print(A.a); // this will print 5
     }
    
    }
    

    Example 2:

    class A{
     static {
      a=5;
     }
     public static int a =f();
    
     private static int f(){
      return 3;
     }
    
     public static void main(String args[]) {
      System.out.print(A.a); // this will print 3
     }
    
    }
    
    0 讨论(0)
  • 2020-11-22 02:42

    It's also useful when you actually don't want to assign the value to anything, such as loading some class only once during runtime.

    E.g.

    static {
        try {
            Class.forName("com.example.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            throw new ExceptionInInitializerError("Cannot load JDBC driver.", e);
        }
    }
    

    Hey, there's another benefit, you can use it to handle exceptions. Imagine that getStuff() here throws an Exception which really belongs in a catch block:

    private static Object stuff = getStuff(); // Won't compile: unhandled exception.
    

    then a static initializer is useful here. You can handle the exception there.

    Another example is to do stuff afterwards which can't be done during assigning:

    private static Properties config = new Properties();
    
    static {
        try { 
            config.load(Thread.currentThread().getClassLoader().getResourceAsStream("config.properties");
        } catch (IOException e) {
            throw new ExceptionInInitializerError("Cannot load properties file.", e);
        }
    }
    

    To come back to the JDBC driver example, any decent JDBC driver itself also makes use of the static initializer to register itself in the DriverManager. Also see this and this answer.

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