Java 中static 块作用及何时执行
2016-01-20 15:06
423 查看
在逛论坛的看到很多的朋友在讨论staic块,进去瞧瞧,感觉有点雾里看花。我也不知道static块到底有什么用,何时用。学习下吧,好象JDBC就用到这些东西。
一般情况下,如果有些代码必须在项目启动的时候就要被执行,这种情况上就需要使用静态代码块,这种代码是主动执行的,写个例子看看static块什么时候被执行
1.StaticTest
Java代码
package com.test.statictest;
public class StaticTest {
/** 构造方法*/
public StaticTest() {
System.out.println("构造函数被执行了!");
}
/** 静态代码快*/
static {
System.out.println("静态代码块被执行了!");
//show();
}
/** 静态方法*/
public static void show(){
System.out.println("静态方法被执行了!");
}
}
2.Main
Java代码
package com.test.statictest;
public class Main {
public static void main(String[] args) throws ClassNotFoundException {
Main main = new Main();
//加载类
Class.forName("com.test.statictest.StaticTest");
Class.forName("com.test.statictest.StaticTest");
}
}
结果输出
静态代码块被执行了!
在测试类里我加载了2次StaticTest类,按理说"静态代码块被执行了!"这句话应执行二次,但只输出了一次。
再看看别的
Java代码
package com.test.statictest;
public class Main {
public static void main(String[] args) throws ClassNotFoundException {
Main main = new Main();
//加载类
Class.forName("com.test.statictest.StaticTest",true,Main.class.getClassLoader());
//Class.forName("com.test.statictest.StaticTest");
}
}
结果:
静态代码块被执行了!
这两个语句是等价的,执行的结果相同。
把Class.forName("com.test.statictest.StaticTest",true,Main.class.getClassLoader())中的true改为false,代表加载类的时候不初始化静态代码块的内容,只能在这个类被实例化的时候才能初始化
Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码块.
看看JDBC是怎么对Class.forName解释的:
we just want to load the driver to jvm only, but not need to user the instance of driver, so call Class.forName(xxx.xx.xx)
is enough, if you call Class.forName(xxx.xx.xx).newInstance(), the result will same as calling Class.forName(xxx.xx.xx),
becauseClass.forName(xxx.xx.xx).newInstance() will load driver first, and then create instance, but the
instacne you will never use in usual, so you need not to create it.
翻译:
我们只是想加载这个驱动到JVM,并不需要实例化这个驱动,因此调用Class.forName(xxx.xxx.xx) 足够,如果你调用Class.forName(xxx.xxx.xxx).newInstance(),结果和调用Class.forName(xxx.xxx.xxx)是一样的,因为Class.forName(xxx.xxx.xxx).newInstance() 会首先加载驱动并创建实例,但是这个实例通常你决不会用到,所有你不需要创建它。
Java代码
public static Class<?> forName(String className) throws ClassNotFoundException {
return forName0(className, true, lassLoader.getCallerClassLoader());
}
这是java源码。
1 楼 sunnylocus 2008-08-28
一个类的运行,JVM做会以下几件事情 1、类装载 2、链接 3、初始化 4、实例化。初始化阶段做的工作就是是初始化静态变量,静态代码快和执行静态方法的工作。所以,当Class.forName(类名,true,类对象.getClass().getClassLoader())中的true为false的时候,就是告诉JVM不需再load class之后进行初始化的工作。这样,将初始化的工作放到newInstance的时候进行。所以,static块被执行的时机是在类被初始化的时候,无论这个类你加载多少次,static块仅仅只是被调用一次。
一般情况下,如果有些代码必须在项目启动的时候就要被执行,这种情况上就需要使用静态代码块,这种代码是主动执行的,写个例子看看static块什么时候被执行
1.StaticTest
Java代码
package com.test.statictest;
public class StaticTest {
/** 构造方法*/
public StaticTest() {
System.out.println("构造函数被执行了!");
}
/** 静态代码快*/
static {
System.out.println("静态代码块被执行了!");
//show();
}
/** 静态方法*/
public static void show(){
System.out.println("静态方法被执行了!");
}
}
2.Main
Java代码
package com.test.statictest;
public class Main {
public static void main(String[] args) throws ClassNotFoundException {
Main main = new Main();
//加载类
Class.forName("com.test.statictest.StaticTest");
Class.forName("com.test.statictest.StaticTest");
}
}
结果输出
静态代码块被执行了!
在测试类里我加载了2次StaticTest类,按理说"静态代码块被执行了!"这句话应执行二次,但只输出了一次。
再看看别的
Java代码
package com.test.statictest;
public class Main {
public static void main(String[] args) throws ClassNotFoundException {
Main main = new Main();
//加载类
Class.forName("com.test.statictest.StaticTest",true,Main.class.getClassLoader());
//Class.forName("com.test.statictest.StaticTest");
}
}
结果:
静态代码块被执行了!
这两个语句是等价的,执行的结果相同。
把Class.forName("com.test.statictest.StaticTest",true,Main.class.getClassLoader())中的true改为false,代表加载类的时候不初始化静态代码块的内容,只能在这个类被实例化的时候才能初始化
Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码块.
看看JDBC是怎么对Class.forName解释的:
we just want to load the driver to jvm only, but not need to user the instance of driver, so call Class.forName(xxx.xx.xx)
is enough, if you call Class.forName(xxx.xx.xx).newInstance(), the result will same as calling Class.forName(xxx.xx.xx),
becauseClass.forName(xxx.xx.xx).newInstance() will load driver first, and then create instance, but the
instacne you will never use in usual, so you need not to create it.
翻译:
我们只是想加载这个驱动到JVM,并不需要实例化这个驱动,因此调用Class.forName(xxx.xxx.xx) 足够,如果你调用Class.forName(xxx.xxx.xxx).newInstance(),结果和调用Class.forName(xxx.xxx.xxx)是一样的,因为Class.forName(xxx.xxx.xxx).newInstance() 会首先加载驱动并创建实例,但是这个实例通常你决不会用到,所有你不需要创建它。
Java代码
public static Class<?> forName(String className) throws ClassNotFoundException {
return forName0(className, true, lassLoader.getCallerClassLoader());
}
这是java源码。
1 楼 sunnylocus 2008-08-28
一个类的运行,JVM做会以下几件事情 1、类装载 2、链接 3、初始化 4、实例化。初始化阶段做的工作就是是初始化静态变量,静态代码快和执行静态方法的工作。所以,当Class.forName(类名,true,类对象.getClass().getClassLoader())中的true为false的时候,就是告诉JVM不需再load class之后进行初始化的工作。这样,将初始化的工作放到newInstance的时候进行。所以,static块被执行的时机是在类被初始化的时候,无论这个类你加载多少次,static块仅仅只是被调用一次。
相关文章推荐
- 导入时如何定制spring-boot依赖项的版本
- 深入浅出设计模式(九):12.装饰模式(Decorator) 13.桥模式(Bridge)14.策略模式(Strategy)
- spring---定时任务(quartz定时器)
- 如何使用 Java 构建微服务?
- 如何使用 Java 构建微服务?
- java基础之字符串转日期
- spring InitializingBean接口
- 怎么在MyEclipse编辑区左边显示行号
- java获取本机ip和mac地址
- 深入Java集合学习系列:HashMap的实现原理
- Leetcode@jump Game
- Java_并发线程_CompletionService
- Java实现数据库连接池简易教程
- Java正则表达式的语法与示例
- java语言概述
- Eclipse中创建Maven web项目
- JAVA虚拟机的生命周期
- 谈谈Java中try-catch-finally中的return语句
- Eclipse中安装Subversive (Subversion的对应模块)
- Leetcode @ Gas Station