static语句块的执行时间
package utfTest;
public class Test01 {
public static void main(String[] args) {
//Person.show();
System.out.println("p还没有初始化");
Class cls=Person.class;
System.out.println("执行了语句:Class cls=Person.class;不知道static语句在这条语句之前是否有输出");
Person p = new Person();
System.out.println("p刚刚被初始化,这里输出是用来验证static语句块是在哪里被输出的");
p.setName("小明");
p.setAge(18);
Person p1 = p;
p1.setAge(10);
p.setName("小邹");
System.out.println("p1创建了");
System.out.println(p.getName()+" "+p.getAge());
System.out.println(p1.getName()+" "+p1.getAge());
}
}
class Person{
int age;
String name;
static int id=0;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
static{
System.out.println("这里输出的是静态代码块");//这条语句在编译阶段执行,只会被执行一次
System.out.println("id="+id);
}
static public void show(){
System.out.println("这是static方法,我是在什么时候被输出的呢?");
}
}
运行结果是:

static语句块是在初始化阶段被执行的,而不是类加载阶段。
如果在main方法的开头添加了代码块:Person.show();那么运行结果是:

以下转载自:https://blog.csdn.net/berber78/article/details/46472789
一、误区:简单认为JAVA静态代码块在类被加载时就会自动执行。证错如下:
- class MyClass1 {
- static {//静态块
- System.out.println("static block ");
- }
- }
- public class Main {
- Class[] classArray = {
- MyClass1.class//这样引用该类,必然需要将该类加载到虚拟机中
- };
- public static void main(String[] args){
- System.out.println("hello word");
- }
- }
执行结果:并没有输出" static bolck"
二、正解:static块真正的执行时机。如果了解JVM原理,我们知道,一个类的运行分为以下步骤:
- 装载
- 连接
- 初始化
其中装载阶段又三个基本动作组成:
- 通过类型的完全限定名,产生一个代表该类型的二进制数据流
- 解析这个二进制数据流为方法区内的内部数据结
- 构创建一个表示该类型的java.lang.Class类的实例
另外如果一个类装载器在预先装载的时遇到缺失或错误的class文件,它需要等到程序首次主动使用该类时才报告错误。
连接阶段又分为三部分:
- 验证,确认类型符合Java语言的语义,检查各个类之间的二进制兼容性(比如final的类不用拥有子类等),另外还需要进行符号引用的验证。
- 准备,Java虚拟机为类变量分配内存,设置默认初始值。
- 解析(可选的) ,在类型的常量池中寻找类,接口,字段和方法的符号引用,把这些符号引用替换成直接引用的过程。
当一个类被主动使用时,Java虚拟就会对其初始化,如下六种情况为主动使用:
- 当创建某个类的新实例时(如通过new或者反射,克隆,反序列化等)
- 当调用某个类的静态方法时
- 当使用某个类或接口的静态字段时
- 当调用Java API中的某些反射方法时,比如类Class中的方法,或者java.lang.reflect中的类的方法时
- 当初始化某个子类时
- 当虚拟机启动某个被标明为启动类的类(即包含main方法的那个类)
Java编译器会收集所有的类变量初始化语句和类型的静态初始化器,将这些放到一个特殊的方法中:clinit。
实际上,static块的执行发生在“初始化”的阶段。初始化阶段,jvm主要完成对静态变量的初始化,静态块执行等工作。
下面我们看看执行static块的几种情况:
1、第一次new A()的过程会打印"";因为这个过程包括了初始化
2、第一次Class.forName("A")的过程会打印"";因为这个过程相当于Class.forName("A",true,this.getClass().getClassLoader());
3、第一次Class.forName("A",false,this.getClass().getClassLoader())的过程则不会打印""。因为false指明了装载类的过程中,不进行初始化。不初始化则不会执行static块。
参考资料:《深入Java虚拟机》
---------------------
本文来自 berber78 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/berber78/article/details/46472789?utm_source=copy
static语句块的执行时间的更多相关文章
- static{ }语句块详解
static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法.举ge例子: public class Test { public static i ...
- 转 java中static{}语句块详解
原文地址:http://blog.csdn.net/lubiaopan/article/details/4802430 感谢原作者! static{}(即static块),会在类被加载的时候执 ...
- java中static{}语句块详解
static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法,下面我们详细的讨论一下该语句块的特性及应用. 一.在程序的一次执行过程中,stati ...
- 关于java的static语句块
声明:转载请注明出处 static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法,下面我们详细的讨论一下该语句块的特性及应用. 一.在程序的一次 ...
- Static语句块和初始语句块的使用---2015年10月恒生电子笔试试卷
package lhm.test; /** * @author lenovo * */public class Person { private int id; private static int ...
- Java static{}语句块详解
[转自] http://blog.csdn.net/lubiaopan/article/details/4802430 static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一 ...
- static 语句块
static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法,下面我们详细的讨论一下该语句块的特性及应用. 一.在程序的一次执行过程中,stati ...
- Java中关于static语句块的理解
Java中关于static语句块的理解 一.static块会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法. 实例一 public class A{ String name ...
- Java static 语句块
总结前一天学习,参考原文http://www.cnblogs.com/dolphin0520/p/3799052.html1: 对Static有了进一步的认识 这个地方重点是初始化各个变量顺序, ...
随机推荐
- linux暴力密码破解工具hydra安装与使用
说明:hydra是著名黑客组织thc的一款开源的暴力密码破解工具,可以在线破解多种密码.官网:http://www.thc.org/thc-hydra,可支持AFP, Cisco AAA, Cisco ...
- 我的IT之路
在写这篇文章的时候内心是无比激动,因为这辈子是注定和IT打交道了. 都说大学时光是美好的,但却只有到了大四才知道时间是短暂的,也许和许多人一样,我的大学主要时光是在游戏中度过,1000多把的寒冰算是同 ...
- ubuntu下编译原生ffmpeg
本文主要介绍Linux 系统下如何编译Ffmpeg,编译环境是Ubuntu 16.04,Ffmpeg版本是3.4.2.Windows环境 下如何编译ffmpeg前面有博文介绍,也录有视频,感兴趣的同学 ...
- VueJS字符串反转:String.reverse()
HTML <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <titl ...
- URL Handle in Swift (二) — 响应链处理 URL
最后更新: Swift4时候的博客,以前在 CMD markdown 上编辑的,现在搬到这里 在上篇文章-URL Handle in Swift (一) -- URL 分解中,我们已经将URL进行了分 ...
- 看完这篇还不会自定义 View ,我跪搓衣板
自定义 View 在实际使用的过程中,我们经常会接到这样一些需求,比如环形计步器,柱状图表,圆形头像等等,这时我们通常的思路是去Google 一下,看看 github 上是否有我们需要的这些控件,但是 ...
- linux查看磁盘挂载的三种方法
第一种方法:使用df命令,例如: orientalson:/home # df Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda ...
- 线程池 API (转)
文档原始地址 目录 线程池概述 线程池对象 回调环境对象 工作对象 等待对象 计时器对象 I/O 完成对象 使用清理组简化清理 回调实例 API 随着 Windows Vista® 的发布 ...
- Python中类方法、__new__方法和__init__方法解析
在编程语言中创建一个类,有构造方法这样的一个术语.而在Python中,通常大家都认为__init__是构造方法,其实并不完全等同.在构建类中,有一个特殊的方法__new__,这个才能等同为构造方法. ...
- Vue设置导航栏为公共模块并在登录页不显示
1.公共模块的内容可以放在App.vue中但是通常登录页面是不需要导航的,那么就需要规避登录页这时,就可以采用keep-alive结合$route.meta来实现这个功能.keep-alive 是 V ...