如果一个java类中静态变量同时有多个静态代码块,那它们的执行顺序是怎样的?

(一)java 静态代码块 静态方法区别
一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序来调用的时候,需要使用静态方法,这种代码是被动执行的. 静态方法在类加载的时候 就已经加载 可以用类名直接调用比如main方法就必须是静态的 这是程序入口两者的区别就是:静态代码块是自动执行的;静态方法是被调用的时候才执行的.
静态代码块执行顺序
package com.smiling.
class Parent {
static String name = "hello";
System.out.println("parent block3");//3
System.out.println("parent static block1");//1
public Parent() {
System.out.println("parent constructor4");//4
class Child extends Parent {
static String childName = "hello";
System.out.println("child block5");//5
System.out.println("child static block2");//2
public Child() {
System.out.println("child constructor6");//6
public class StaticBlock {
public static void main(String[] args) {
new Child();// 语句(*)
对象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。
(一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序来调用的时候,需要使用静态方法,这种代码是被动执行的. 静态方法在类加载的时候 就已经加载 可以用类名直接调用比如main方法就必须是静态的 这是程序入口两者的区别就是:静态代码块是自动执行的;静态方法是被调用的时候才执行的.
静态方法(1)在Java里,可以定义一个不需要创建对象的方法,这种方法就是静态方法。要实现这样的效果,只需要在类中定义的方法前加上static关键字。例如:
public static int maximum(int n1,int n2)
使用类的静态方法时,注意:a在静态方法里只能直接调用同类中其他的静态成员(包括变量和方法),而不能直接访问类中的非静态成员。这是因为,对于非静态的方法和变量,需要先创建类的实例对象后才可使用,而静态方法在使用前不用创建任何对象。
b 静态方法不能以任何方式引用this和super关键字,因为静态方法在使用前不用创建任何实例对象,当静态方法调用时,this所引用的对象根本没有产生。
(2)静态变量是属于整个类的变量而不是属于某个对象的。注意不能把任何方法体内的变量声明为静态,例如:fun(){static int i=0;//非法。}
(3)一个类可以使用不包含在任何方法体中的静态代码块,当类被载入时,静态代码块被执行,且只被执行一次,静态块常用来执行类属性的初始化。例如:static{}
类装载步骤在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,其中链接又可以分成校验、准备和解析三步,除了解析外,其它步骤是严格按照顺序完成的,各个步骤的主要工作如下:
装载:查找和导入类或接口的二进制数据;链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的;校验:检查导入类或接口的二进制数据的正确性;准备:给类的静态变量分配并初始化存储空间;解析:将符号引用转成直接引用;初始化:激活类的静态变量的初始化Java代码和静态Java代码块。初始化类中属性是静态代码块的常用用途,但只能使用一次。
(二)静态代码块的初始化顺序
&class Parent{&static String name = "hello";&{&System.out.println("parent block");&}&static {&System.out.println("parent static block");&}&public Parent(){&System.out.println("parent constructor");&}&}&class Child extends Parent{&static String childName = "hello";&{&System.out.println("child block");&}&static {&System.out.println("child static block");&}&public Child(){&System.out.println("child constructor");&}&}&public class StaticIniBlockOrderTest {&public static void main(String[] args) {&new Child();//语句(*)&}&}
问题:当执行完语句(*)时,打印结果是什么顺序?为什么?解答:当执行完语句(*)时,打印结果是这样一个顺序 :
&parent static blockchild static blockparent blockparent constructorchild blockchild constructor
分析:当执行new Child()时,它首先去看父类里面有没有静态代码块,如果有,它先去执行父类里面静态代码块里面的内容,当父类的静态代码块里面的内容执行完毕之后,接着去执行子类(自己这个类)里面的静态代码块,当子类的静态代码块执行完毕之后,它接着又去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法,这个就是一个对象的初始化顺序。
总结:对象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。
注意:子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过。
阅读(...) 评论()我们知道类的生命周期分为装载、连接、初始化、使用和卸载的五个过程。其中静态代码在类的初始化阶段被初始化。
而非静态代码则在类的使用阶段(也就是实例化一个类的时候)才会被初始化。
可以将静态变量理解为类变量(与对象无关),而实例变量则属于一个特定的对象。
静态变量有两种情况:
静态变量是基本数据类型,这种情况下在类的外部不必创建该类的实例就可以直接使用
静态变量是一个引用。这种情况比较特殊,主要问题是由于静态变量是一个对象的引用,那么必须初始化这个对象之后才能将引用指向它。
因此如果要把一个引用定义成static的,就必须在定义的时候就对其对象进行初始化。
public&class&TestForStaticObject{&&
static&testObject&o&=&new&testObject&();&
public&static&void&main(String&args[]){&&
与类变量不同,方法(静态方法与实例方法)在内存中只有一份,无论该类有多少个实例,都共用一个方法。
静态方法与实例方法的不同主要有:
静态方法可以直接使用,而实例方法必须在类实例化之后通过对象来调用。
在外部调用静态方法时,可以使用&类名.方法名&或者&对象名.方法名&的形式。
实例方法只能使用这种方式对象名.方法名。
静态方法只允许访问静态成员。而实例方法中可以访问静态成员和实例成员。
静态方法中不能使用this(因为this是与实例相关的)。
静态代码块
在java类中,可以将某一块代码声明为静态的。
static&{&&
静态代码块主要用于类的初始化。它只执行一次,并且在同属于一个类的main函数之前执行。
静态代码块的特点主要有:
静态代码块会在类被加载时自动执行。
静态代码块只能定义在类里面,不能定义在方法里面。
静态代码块里的变量都是局部变量,只在块内有效。
一个类中可以定义多个静态代码块,按顺序执行。
静态代码块只能访问类的静态成员,而不允许访问实例成员。
&静态代码块和静态函数的区别
java 静态代码块:
一般情况下,如果有些代码必须在项目启动前就执行的时候,需要使用静态代码块,这种代码是主动执行的,它只执行一次,并且在同属于一个类的main函数之前执行。
静态函数:
需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序来调用的时候,需要使用静态方法,这种代码是被动执行的.
(1)静态变量是属于整个类的变量而不是属于某个对象的。注意不能把任何方法体内的变量声明为静态,例如:fun(){static int i=0;//非法。}
(2)一个类可以使用不包含在任何方法体中的静态代码块,当类被载入时,静态代码块被执行,且只被执行一次,静态块常用来执行类属性的初始化。例如:static{}
主程序类中的的静态变量先于静态代码块初始化,其后进入主函数类(程序入口处),其后根据静态函数的调用情况,才能选择性的初始化。
阅读(...) 评论()博客分类:
不忙的时候看了一下java基础,初始化顺序这里以前不太清楚,现在明白好多,如果你也和我一样,相信通过这段代码能给你帮助
public class TestCodeExecOrder extends TestCodeExecOrderHost {
static {System.out.println("TestCodeExecOrder static代码块");}//(3)静态代码块
//(1)和(2)的顺序决定了输出顺序,也就是说哪个在前,先走哪个代码
private int x = print("TestCodeExecOrderHost xx变量");//(2)普通成员变量
{System.out.println(xx2+"TestCodeExecOrderHost
动态代码块");}//(1)动态代码块
//private int x = print("TestCodeExecOrderHost xx变量");//(2)普通成员变量
//(3)和(4)的顺序决定了输出顺序,也就是说哪个在前,先走哪个代码
private static int xx2 = print("static TestCodeExecOrder.xx2 init");//(4)static成员变量
public TestCodeExecOrder(){
System.out.println("TestCodeExecOrder
System.out.println("TestCodeExecOrder
public static void main(String[] args) {
System.out.println("TestCodeExecOrder main");
TestCodeExecOrder t = new TestCodeExecOrder();
class TestCodeExecOrderHost{
private int i = 9;
private static int xx = print("static TestCodeExecOrderHost.xx init");
{System.out.println(xx+"TestCodeExecOrderHost 动态代码块");}
static {System.out.println("TestCodeExecOrderHost static代码块");}
public TestCodeExecOrderHost(){
System.out.println("TestCodeExecOrderHost
i="+i+" j="+j);
public static int print(String s){
System.out.println(s);
return 20;
//output结果
static TestCodeExecOrderHost.xx init
TestCodeExecOrderHost static代码块
TestCodeExecOrder static代码块
static TestCodeExecOrder.xx2 init
TestCodeExecOrder main
20TestCodeExecOrderHost 动态代码块
TestCodeExecOrderHost
TestCodeExecOrderHost xx变量
20TestCodeExecOrderHost
动态代码块
TestCodeExecOrder
TestCodeExecOrder
主线:如果有父类先走父类部分,再走子类部分
(0)在其他任何事情发生之前,将分配给对象的存储空间初始化成二进制的的零(先是父类的成员变量初始为默认值,再是子类的成员变量初始为默认值)
(1)程序运行时第一件事就是试图访问TestCodeExecOrder .main方法(他是static的),这是加载器加载TestCodeExecOrder的编译代码,对他加载过程中如果发现他有一个父类TestCodeExecOrderHost,接着对父类进行加载;
(2)接着,父类中的static初始化被立刻进行,然后是子类的static初始化(此处的static包括:static变量和static代码块,谁在前,谁就先执行),此时必要的类加载完毕,就可以创建对象了
(3)此时,对对象中的普通成员变量初始化(有值得赋值,没值的赋默认值)(普通成员变量包括:普通成员变量和动态代码块,谁在前,谁就先执行),接着父类的构造方法被执行,然后是子类的构造方法
本人看书之后的理解,如果有不对的地方欢迎大家指正,这些基本的执行顺序在分析实际项目的bug感觉很有用
浏览: 19556 次
来自: 北京
你说的很对,但是在项目中内部类用的多吗,你会在项目中定义内部类 ...
我觉得java编程思想,写的很好,如果你的基础可以,读起来不会 ...
,也对,机器没有明显的差别
测试下,记录下时间不就OK了。
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'||百姓网公众号微信扫码关注百姓网小程序微信扫扫立即体验扫码下载手机客户端免费抢油卡、红包、电影票您正在浏览信息,点击查看更多服务 100元4月12日 10:11 &...次浏览 &&课程学费:100元培训类型:学校名称:疯狂软件教育中心联系人:李老师地址:&-&&联系:(江门)联系时,请一定说明在百姓网看到的,谢谢!见面最安全,发现问题请举报其他联系:  
Java之静态代码块、构造代&&码块的用法
  本文主要是详解Java之静态代码块、构造代码块的用法,更多Java技术知识,请登陆疯狂软件教育官网。微信搜索微信号:疯狂软件,参加2015年优惠活动,有机会获得优惠劵和代金劵。
  构造函数、构造代码块和静态代码块容易混淆,它们的执行条件和执行顺序也常常容易犯迷。这里就针对这些问题说一下我个人的一些理解,顺便对这部分内容做个小结。
  构造函数
  格式:类名(参数1,参数2,&){构造函数执行语句};
  关于构造函数,以下几点要注意:
  1.对象一建立,就会调用与之相应的构造函数,也就是说,不建立对象...  
Java之静态代码块、构造代&&码块的用法
  本文主要是详解Java之静态代码块、构造代码块的用法,更多Java技术知识,请登陆疯狂软件教育官网。微信搜索微信号:疯狂软件,参加2015年优惠活动,有机会获得优惠劵和代金劵。
  构造函数、构造代码块和静态代码块容易混淆,它们的执行条件和执行顺序也常常容易犯迷。这里就针对这些问题说一下我个人的一些理解,顺便对这部分内容做个小结。
  构造函数
  格式:类名(参数1,参数2,&){构造函数执行语句};
  关于构造函数,以下几点要注意:
  1.对象一建立,就会调用与之相应的构造函数,也就是说,不建立对象,构造函数时不会运行的。
  2.构造函数的作用是用于给对象进行初始化。
  3.构造函数笼统来说也是函数,它具备函数的一些特性,也不具备一些特性,可以把它看成是特殊的函数。它可以重载(重载时参数类型与参数个数有一项不同即可,但仅仅函数返回值类型不同是不行的),可以被权限修饰符修饰,但是它没有返回值(注意:这与平常所说的函数返回值类型是void不同)。
  4.当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造方法。但是当在类中自定义构造函数后,默认的构造函数就没有了,即使是自定义的构造函数也是空参数的也是这样,因为那毕竟是你&自定义&的!
  5.构造函数和一般函数不仅在写法上有不同,在运行上也有不同。构造函数是在对象一建立就运行,给对象初始化,而一般函数是对象调用时才执行,给对象添加对象具备的功能。
  一个对象建立,构造函数只运行一次,而一般方法可以被该对象调用多次。
  6.定义构造函数的需求性:当分析事物时,该事物存在具备一些特性或者行为,那么将这些内容定义在构造函数中。
  构造代码块
  格式:{构造代码块执行语句};
  关于构造代码块,以下几点要注意:
  1.构造代码块的作用是给对象进行初始化。
  2.对象一建立就运行构造代码块了,而且优先于构造函数执行。这里要强调一下,有对象建立,才会运行构造代码块,类不能调用构造代码块的,而且构造代码块与构造函数的执行顺序是前者先于后者执行。
  3.构造代码块与构造函数的区别是:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。
  静态代码块
  格式:static{静态代码块执行语句};
  关于静态代码块,要注意的是:
  1.它是随着类的加载而执行,只执行一次,并优先于主函数。具体说,静态代码块是由类调用的,当然,建立对象的时候,它也会执行,但是建立多个对象,它也是只会执行一次,并不是说每次建立对象它都要执行,因为它是由类调用的,且只执行一次!就它优先于主函数而执行这点来说,因为主函数也是由类调用的,所以类可以控制着执行的顺序,而实际上,类调用时,先执行静态代码块,然后才执行主函数的。
  2.静态代码块其实就是给类初始化的,而构造代码块是给对象初始化的。区分着理解比较容易记牢。
  下面结合一个小例子来具体分析三者的用法。
  classStaticCode{
  int num=9;
  StaticCode(){
  System.out.println(&b&);
  static{
  System.out.println(&a&);
  System.out.println(&c&);
  StaticCode(int x){
  System.out.println(&d&);
  public classStaticCodeDemo {
  public static voidmain(String[] args){
  newStaticCode(1);
  运行结果是
  这是因为,主函数中的执行语句是new StaticCode(1);因为这个语句调用了StaticCode类并调用StaticCode的一个构造函数建立对象,那么在StaticCode类中,先执行的是静态代码块
  static{
  System.out.println(&a&);
  它是在调用类时立即执行,但此时还没有建立对象。然后执行的是构造代码块,
  System.out.println(&c&);
  这是在建立对象时执行,但它的执行是优先于构造函数的。接着执行的是对应的构造函数
  StaticCode(intx){
  System.out.println(&d&);
  ,这个构造函数与new StaticCode(1);有着相同的参数个数和对应的参数类型,执行语句自动匹配寻找对应的构造函数。
  另外,StaticCode类中有个成员变量num,如果将静态代码块改为
  static{
  System.out.println(&a&+this.num);
  则编译不通过,因为静态代码块只能调用静态变量,非静态成员变量在对象没有建立前是不存在的,这也帮助理解了静态代码块是在对象建立前执行的。
  如果将构造代码块改为
  System.out.println(&c,num=&+this.num);
  那么将编译无误,运行正确,因为构造代码块是在对象建立后才运行的,是由对象调用的,对象建立后,成员变量num已经存在了,所以不会出错。
  运行结果如下
  c,num=9
  疯狂软件Java培训紧跟最新的Java潮流技术,国内首家讲解Java 8新特征,根据企业工作中需要的开发技术,让学员学习的课程是企业最需要的实用技术,而且也保障学员能把这些技能点学会、学好,并且疯狂软件教育的课程实时更新,在信息技术快速发展的情况下,可以保证学员学到更新更主流的技术。师资雄厚,教师均拥有8年以上的项目实践经验,疯狂软件Java课程是理论与实践相结合,这样保障了学员很好的掌握理论知识同时,也能根据理论的指导做好实际的工作。为了培养学生的实践能力,设置了很多项目实战课程,在这些课程中,学生可以体验真正的项目实战过程,从而更深刻地掌握知识。如需了解更多,请咨询QQ:抢座热线:020- 咨询QQ:可登陆疯狂软件教育官网查询。微信搜索微信号:疯狂软件,参加2015年优惠活动,有机会获得优惠劵和代金劵。百姓网提醒您:1)夸大的宣传和承诺不要轻信,谨防上当受骗。
2)提供免考、代考、办证的均是违法行为,请不要相信。
小贴士:本页信息由用户及第三方发布,真实性、合法性由发布人负责。详情请阅读
(window.slotbydup = window.slotbydup || []).push({
container: s,
id: cpro_id,
scale: '20.3',
display: 'inlay-fix'
信息设置为“搞定了!”状态后,其他用户将无法查看您的联系方式。您确认搞定了这条信息吗?重新发布后可使用“刷新”将发布时间更新为最新时间,并将信息排到第一页。商户推广合作加盟服务支持合作伙伴|&| 沪公网安备16号4&G:141&GM:188
描述:请填写描述手机号:请填写手机号请填写手机号上传图片:打开微信,扫一扫右侧二维码,即可完成绑定 -->绑定后,您可以:1. 立即在手机上收到用户给您的留言2. 使用手机快速完成付费推广的续费动作3. 第一时间了解到百姓网付费推广最新的促销活动,以及享受微信端独特的促销活动4. 更快速地将信息通过微信分享给好友、同事、朋友圈5. 如果您是招聘类目用户,还能够第一时间接收到新简历通知下载APP无需登录实时接受私信提醒,联系更便捷!或点击下方先登录再进入私信联系

我要回帖

更多关于 java类中静态变量 的文章

 

随机推荐