静态代码块的加载与执行

By heiry on 2019-04-17 [ in 技术 ]

java中的静态代码块,在被载入内存的时候被执行,而且只执行一次,正因如此,某些场景下我们可以用静态代码块实现单例模式。但是对于静态代码块的执行顺序,如果没好好理解,就容易掉坑。

静态代码块装载时才执行。类在第一次被使用的时候才被装载,而不是程序启动时就装载所有的类,因此含静态代码块的所在类被装载时静态代码块才会运行。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public class StaticCodeTest {
public static void main(String [] args){
System.out.println("main fun running");
}
static {
System.out.println("this static area run auto");
}
}
public class StaticCodeTest { public static void main(String [] args){ System.out.println("main fun running"); } static { System.out.println("this static area run auto"); } }
public class StaticCodeTest { 
        public static void main(String [] args){ 
        System.out.println("main fun running");
    }
  static { 
        System.out.println("this static area run auto"); 
    } 
}

以上代码运行结果如下:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
this static area run auto
main fun running
this static area run auto main fun running
this static area run auto
main fun running

StaticCodeTest类在载入时自动运行了静态代码块,而且静态代码块优先于main方法执行。

在上述的代码基础上,我们加入两个类

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public class StaticCodeTest {
public static void main(String [] args){
System.out.println("main fun running");
}
static {
System.out.println("this static area run auto");
}
}
class StaticAreaDemo_1{
static String siteName = "blog.mosang.net";
static{
System.out.println("来自"+siteName+"的静态代码块1被执行");
}
}
class StaticAreaDemo_2{
static String siteName = "www.mosang.net";
static{ System.out.println("来自"+siteName+"的静态代码块1被执行");
}
}
public class StaticCodeTest { public static void main(String [] args){ System.out.println("main fun running"); } static { System.out.println("this static area run auto"); } } class StaticAreaDemo_1{ static String siteName = "blog.mosang.net"; static{ System.out.println("来自"+siteName+"的静态代码块1被执行"); } } class StaticAreaDemo_2{ static String siteName = "www.mosang.net"; static{ System.out.println("来自"+siteName+"的静态代码块1被执行"); } }
public class StaticCodeTest { 
    
        public static void main(String [] args){ 
        System.out.println("main fun running");
      
    }
  static { 
        System.out.println("this static area run auto"); 
    } 
}

class StaticAreaDemo_1{
static String siteName = "blog.mosang.net";
static{
System.out.println("来自"+siteName+"的静态代码块1被执行");
}
}
class StaticAreaDemo_2{
static String siteName = "www.mosang.net";
static{ System.out.println("来自"+siteName+"的静态代码块1被执行");
}
}

运行结果如下

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
this static area run auto
main fun running
this static area run auto main fun running
this static area run auto
main fun running

可见,如果静态代码块所在类没有被装载,静态代码块是不会自动运行的。

创建新增两个类的对象,代码及运行结果如下

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public class StaticCodeTest {
public static void main(String [] args){
System.out.println("main fun running");
StaticAreaDemo_1 p1 = new StaticAreaDemo_1();
StaticAreaDemo_2 p2 = new StaticAreaDemo_2();
}
static {
System.out.println("this static area run auto");
}
}
class StaticAreaDemo_1{
static String siteName = "blog.mosang.net";
static{
System.out.println("来自"+siteName+"的静态代码块被执行");
}
}
class StaticAreaDemo_2{
static String siteName = "www.mosang.net";
static{ System.out.println("来自"+siteName+"的静态代码块被执行");
}
}
public class StaticCodeTest { public static void main(String [] args){ System.out.println("main fun running"); StaticAreaDemo_1 p1 = new StaticAreaDemo_1(); StaticAreaDemo_2 p2 = new StaticAreaDemo_2(); } static { System.out.println("this static area run auto"); } } class StaticAreaDemo_1{ static String siteName = "blog.mosang.net"; static{ System.out.println("来自"+siteName+"的静态代码块被执行"); } } class StaticAreaDemo_2{ static String siteName = "www.mosang.net"; static{ System.out.println("来自"+siteName+"的静态代码块被执行"); } }
public class StaticCodeTest { 
    
        public static void main(String [] args){ 
        System.out.println("main fun running");
      StaticAreaDemo_1 p1 = new StaticAreaDemo_1();
    StaticAreaDemo_2 p2 = new StaticAreaDemo_2();
      
    }
  static { 
        System.out.println("this static area run auto"); 
    } 
}

class StaticAreaDemo_1{
static String siteName = "blog.mosang.net";
static{
System.out.println("来自"+siteName+"的静态代码块被执行");
}
}
class StaticAreaDemo_2{
static String siteName = "www.mosang.net";
static{ System.out.println("来自"+siteName+"的静态代码块被执行");
}
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
this static area run auto
main fun running
来自blog.mosang.net的静态代码块被执行
来自www.mosang.net的静态代码块被执行
this static area run auto main fun running 来自blog.mosang.net的静态代码块被执行 来自www.mosang.net的静态代码块被执行
this static area run auto
main fun running
来自blog.mosang.net的静态代码块被执行
来自www.mosang.net的静态代码块被执行

以上可看出,装载StaticAreaDemo_1和StaticAreaDemo_2,其中的代码块执行,但是并没有优先于main方法执行。

上述代码更改为同一个类创建两个对象:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public class StaticCodeTest {
public static void main(String [] args){
System.out.println("main fun running");
StaticAreaDemo_1 p1 = new StaticAreaDemo_1();
StaticAreaDemo_1 p2 = new StaticAreaDemo_1();
}
static {
System.out.println("this static area run auto");
}
}
class StaticAreaDemo_1{
static String siteName = "blog.mosang.net";
static{
System.out.println("来自"+siteName+"的静态代码块被执行");
}
}
class StaticAreaDemo_2{
static String siteName = "www.mosang.net";
static{ System.out.println("来自"+siteName+"的静态代码块被执行");
}
}
public class StaticCodeTest { public static void main(String [] args){ System.out.println("main fun running"); StaticAreaDemo_1 p1 = new StaticAreaDemo_1(); StaticAreaDemo_1 p2 = new StaticAreaDemo_1(); } static { System.out.println("this static area run auto"); } } class StaticAreaDemo_1{ static String siteName = "blog.mosang.net"; static{ System.out.println("来自"+siteName+"的静态代码块被执行"); } } class StaticAreaDemo_2{ static String siteName = "www.mosang.net"; static{ System.out.println("来自"+siteName+"的静态代码块被执行"); } }
public class StaticCodeTest { 
    
        public static void main(String [] args){ 
        System.out.println("main fun running");
      StaticAreaDemo_1 p1 = new StaticAreaDemo_1();
    StaticAreaDemo_1 p2 = new StaticAreaDemo_1();
      
    }
  static { 
        System.out.println("this static area run auto"); 
    } 
}

class StaticAreaDemo_1{
static String siteName = "blog.mosang.net";
static{
System.out.println("来自"+siteName+"的静态代码块被执行");
}
}
class StaticAreaDemo_2{
static String siteName = "www.mosang.net";
static{ System.out.println("来自"+siteName+"的静态代码块被执行");
}
}

运行结果:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
this static area run auto
main fun running
来自blog.mosang.net的静态代码块被执行
this static area run auto main fun running 来自blog.mosang.net的静态代码块被执行
this static area run auto
main fun running
来自blog.mosang.net的静态代码块被执行

可见,尽管创建了两个对象,静态代码块只执行了一次。

 >>



© 2009-2024 MOSANG.NET DESIGNED BY HEIRY