`
chinagdvea
  • 浏览: 132554 次
  • 性别: Icon_minigender_1
  • 来自: 韶关
社区版块
存档分类
最新评论

[转]static语句块详解

阅读更多
static{}语句块详解

static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法,下面我们详细的讨论一下该语句块的特性及应用。

一、在程序的一次执行过程中,static{}语句块中的内容只被执行一次,看下面的示例:

示例一

view plaincopy to clipboardprint?
class Test{  
        public static int X=100;  
    public final static int Y;=200 
    public Test(){  
        System.out.println("Test构造函数执行");  
    }  
    static{  
        System.out.println("static语句块执行");  
    }  
    public static void display(){  
        System.out.println("静态方法被执行");  
    }  
    public void display_1(){  
        System.out.println("实例方法被执行");  
    }  
}  
public class StaticBlockTest{  
    public static void main(String args[]){  
        try{  
                Class.forName("Test");     
                    Class.forName("Test");   
        }catch(ClassNotFoundException e){  
            e.printStackTrace();  
        }  
            
    }     

class Test{
        public static int X=100;
public final static int Y;=200
public Test(){
  System.out.println("Test构造函数执行");
}
static{
  System.out.println("static语句块执行");
}
public static void display(){
  System.out.println("静态方法被执行");
}
public void display_1(){
  System.out.println("实例方法被执行");
}
}
public class StaticBlockTest{
public static void main(String args[]){
  try{
          Class.forName("Test");  
              Class.forName("Test");
  }catch(ClassNotFoundException e){
   e.printStackTrace();
  }
   
}


结果:你会发现虽然执行了两条Class.forName("Test")语句,但是,只输出了一条"静态方法被执行"语句;其实第二条Class.forName()语句已经无效了,因为在虚拟机的生命周期中一个类只被加载一次;又因为static{}是伴随类加载执行的,所以,不管你new多少次对象实例,static{}都只执行一次。 --关于类加载请看本文的附录。

二、static{}语句块执行的时机(其实就是附录中类加载的时机)

上面说到static{}会在类被加载的时候执行,我们必须准确理解类加载的准确含义,含义如下:

1、用Class.forName()显示加载的时候,如上面的示例一;

2、实例化一个类的时候,如将main()函数的内容改为:Test t=new Test();//这种形式其实和1相比,原理是相同的,都是显示的加载这个类,读者可以验证Test t=new Test();和Test t=(Test)Class.forName().newInstance();这两条语句效果相同。

3、调用类的静态方法的时候,如将main()函数的内容改为:Test.display();

4、调用类的静态变量的时候,如将main()函数的内容改为:System.out.println(Test.X);

总体来说就这四种情况,但是我们特别需要注意一下两点:

1、调用类的静态常量的时候,是不会加载类的,即不会执行static{}语句块,读者可以自己验证一下(将main()函数的内容改为System.out.println(Test.Y);),你会发现程序只输出了一个200;(这是java虚拟机的规定,当访问类的静态常量时,如果编译器可以计算出常量的值,则不会加载类,否则会加载类)

2、用Class.forName()形式的时候,我们也可以自己设定要不要加载类,如将Class.forName("Test")改为 Class.forName("Test",false,StaticBlockTest.class.getClassLoader()),你会发现程序什么都没有输出,即Test没有被加载,static{}没有被执行。

三、static{}语句块的执行次序




1、当一个类中有多个static{}的时候,按照static{}的定义顺序,从前往后执行;

2、先执行完static{}语句块的内容,才会执行调用语句;

示例二

public class TestStatic{
    static{
        System.out.println(1);
    }
    static {
        System.out.println(2);
    }
    static {
        System.out.println(3);
    }
    public static void main(String args[]){
        System.out.println(5);
    }
    static {
        System.out.println(4);
    }
}
结果:程序会输出1,2,3,4,5

3、如果静态变量在定义的时候就赋给了初值(如 static int X=100),那么赋值操作也是在类加载的时候完成的,并且当一个类中既有static{}又有static变量的时候,同样遵循“先定义先执行”的原则;

示例三

class Test{
public static int X=300;
static{
  System.out.println(X);
  X=200;
  System.out.println(X);
}
}

public class StaticBlockTest{
public static void main(String args[]){
  System.out.println(Test.X);
}
}

结果:程序会依次输出300,200,200,先执行完X=300,再执行static{}语句块。

四、static{}语句块应用

1、JDBC中的应用

熟悉JDBC的读者应该知道,java中有一个DriverManager类,用于管理各种数据库驱动程序、建立新的数据库连接。DriverManager类包含一些列Drivers类,这些Drivers类必须通过调用DriverManager的registerDriver()方法来对自己进行注册,那么注册是什么时候发生的呢?下面会给出答案:

所有Drivers类都必须包含有一个静态方法,利用这个静态方法可以创建该类的实例,然后在加载该实例时向DriverManage类进行注册。我们经常用Class.forName()对驱动程序进行加载,那么注册就发生在这条语句的执行过程中,前面说的Drivers的静态方法是放在static{}中的,当对驱动程序进行加载的时候,会执行该static{},便完成了注册。

2、hibernate中的应用

hibernate中的SessionFactory是一个重量级的类,创建该类的对象实例会耗费比较多的系统资源,如果每次需要时都创建一个该类的实例,显然会降低程序的执行效率,所以经常将对该类的实例化放在一个static{}中,只需第一次调用时执行,提高程序的执行效率,如下:

static {
     try {
   configuration.configure(configFile);
   sessionFactory = configuration.buildSessionFactory();
  } catch (Exception e) {
   System.err.println("%%%% Error Creating SessionFactory %%%%");
   e.printStackTrace();
  }
    }

分享到:
评论
1 楼 wlcxx98 2011-09-23  
1、调用类的静态常量的时候,是不会加载类的,即不会执行static{}语句块,读者可以自己验证一下(将main()函数的内容改为System.out.println(Test.Y);),你会发现程序只输出了一个200;(这是java虚拟机的规定,当访问类的静态常量时,如果编译器可以计算出常量的值,则不会加载类,否则会加载类)


这是不对的!!!

相关推荐

    static 关键字详解

    ### static关键字详解 在Java编程语言中,`static`关键字是一个非常重要的概念,它用于定义类成员(变量、方法和内部类)的行为属性。当一个类成员被声明为`static`时,它就成为了该类的静态成员,这意味着无论创建...

    java中的static{}块的实例详解

    `static`块,也称为静态初始化块,是包含一组初始化代码的特殊块,这些代码在类加载时仅执行一次,且在创建任何类实例之前执行。`static`块常用来初始化类级别的变量。 在第一个程序中,我们看到一个简单的`static`...

    java中switch选择语句代码详解

    Java 中 Switch 选择语句代码详解 Java 中的 Switch 选择语句是一种多路分支语句,用于根据不同的条件来执行不同的语句块。下面是 Switch 语句的基本结构: switch(表达式){ case 常量1: 语句块1; break; case...

    java中static作用详解

    - 静态代码块是一段在类加载时执行的静态语句序列。它们可以存在于类中任何位置,按出现顺序执行,且只执行一次。 - 静态代码块常用于初始化静态变量或执行一次性设置任务,例如设置日志记录器或数据库连接。 4. ...

    java static详解.doc

    - 静态代码块是一段在类加载时会被执行的静态语句。它们可以有多个,按照在类中出现的顺序执行,并且只执行一次。这些代码块常用于初始化静态变量或执行只在类加载时需要进行的设置操作。 4. **static与final结合...

    java中static属性学习

    ### Java中的Static属性详解 #### 一、引言 在Java编程语言中,`static`关键字扮演着重要的角色。它允许我们创建与类关联而非特定实例关联的数据成员和方法。本文将详细介绍`static`属性的基本概念、静态成员变量...

    java技术:java中static作用详解

    - 静态代码块是一组在类中定义的静态语句块,它在类加载时执行,且只会执行一次。 - 静态代码块可以用来初始化静态变量,执行一些类级别的初始化操作。 - 静态代码块按照它们在类中的出现顺序执行,每个块只执行...

    详解Java语言中的跳转语句 (1).pdf

    详解 Java 语言中的跳转语句 本文详细介绍了 Java 语言中的跳转语句,包括 break 语句和 continue 语句的使用方法和区别。跳转语句是 Java 语言中的重要组成部分,对程序的控制流程和可读性产生了重要的影响。本文...

    Java下static关键字用法详解

    语句块  2. 成员变量(但是不能修饰局部变量)  3. 方法  4. 接口(内部接口)  5. 类(只能修饰在类中的类, 即静态内部类)  6. jdk 1.5 中新增的静态导入  那么static 修饰的表示什么呢? 当创建一个类时,...

    Java复合语句的使用方法详解

    Java复合语句的使用方法详解 Java复合语句是一种重要的语句结构,在 Java 编程中占据着核心地位。本文将详细介绍 Java 复合语句的使用方法及其实例。 什么是 Java 复合语句 Java 复合语句是一种语句结构,它由开...

    Java实验-循环语句,for,while,do-while

    Java循环语句详解 Java中的循环语句是指在一个程序中,重复执行某些语句的语句。循环语句有三种基本形式:for循环、while循环和do-while循环。每种循环语句都有其特点和使用场景。在本实验中,我们将详细介绍这三种...

    继承与static精选例题

    ### 继承与Static知识点详解 #### 一、继承与Static的基本概念 在Java中,继承是一种类之间的关系,允许一个类(子类)继承另一个类(父类)的属性和方法。通过继承,可以实现代码复用,提高程序的可维护性。 `...

    Java中static作用详解

    静态代码块是一组被`static`修饰的语句,它们在类加载时执行,且只执行一次。这种代码块常用于初始化静态变量,或执行只应在类加载时进行的设置。例如,如果你需要在程序开始时对一些配置信息进行预处理,可以将其...

    java_synchronized详解

    ### Java synchronized 关键字详解 #### 一、synchronized关键字简介 `synchronized`是Java语言提供的关键字之一,用于实现线程间的同步控制。通过在方法或代码块上使用`synchronized`,可以确保同一时间只有一个...

    C语言中static用法大全

    ### C语言中static用法详解 #### 一、C程序存储空间布局 C语言程序的存储空间主要分为以下几个部分: 1. **正文段**: 包含CPU执行的机器指令部分,一个程序通常只有一个副本,这部分内容是只读的,以防止程序因...

    Java使用continue语句的实例详解

    Java 使用 continue 语句的实例详解 Java 中的 continue 语句是一种控制流语句,用于跳过当前循环的剩余部分,并继续执行下一次循环。下面将详细介绍 Java 中使用 continue 语句的实例详解。 一、基本概念 在 ...

    c语言中static使用方法

    ### C语言中Static使用方法详解 #### 一、C程序存储空间布局 C语言程序的存储空间主要由以下几个部分组成: 1. **正文段**:这部分存储的是CPU执行的机器指令,一个程序通常只有一个副本,并且是只读的,以防止...

    JAVA中static方法的用法实例详解

    - 静态代码块是一段包含静态语句的代码,它在类加载时执行,且只执行一次。 - 静态代码块通常用于初始化静态变量或执行类级别的设置操作。 - 如果有多个静态代码块,它们会按照在类文件中的顺序依次执行。 4. **...

    Java中static变量作用和用法详解

    静态代码块是一组在类加载时执行的语句,它们在类加载时只执行一次,无论创建了多少个类的实例。静态代码块可以用于初始化静态变量,如下例所示: ```java public class MyClass { static int a; static { ...

Global site tag (gtag.js) - Google Analytics