java 静态块不执行_java中静态块,静态属性,方法的加载顺序(网友反映有问题,请仔细验证,不想误人子弟,有空再改改)...

这两天遇到几个类似的问题,就是一个程序到底是怎么运行的,而且这些问题很具有迷惑性,这里两个例子做分析( 实际上一切都在黑马的免费视频中有体现 ) !

问题一:如下代码的执行顺序是什么样的!一定理解:是执行的顺序(后面会给大家说一个误区)!

class Test{

int a = 5; static int num = 4;                     //这是一个很简单的代码,但是你了解他的运行顺序吗Test(){

}static {                                   // 那么可能你会有疑问,我该如何来去测试一下他们的执行顺序呢?}public static void main(String[] args){}        }

实际上你现在根本看不出来执行顺序,也很容易搞混淆,我们必须找出一种方便的手段去测试一下:

测试的方法:比如

static int num = 4; 这句代码,我们怎么知道他是不是执行了,可以这样写

static int num = 4; {

system.out.println("执行了静态变量语句"); } 这样的话这段代码加载的时候,在控制台就能看到,是不是很方便!

接下来我们出发!--------->>

// 注意看,这里仅仅是一个普遍情况,特殊情况下面有总结:在下面的A ,B两种情况的总结非常的重要,一定要好好的看看!

public classExten

{

static int num = 4; // 静态变量第二个

{

num += 3;

System.out.println("b");

}

int a = 5;{ // 成员变量第三个

System.out.println("c");

}

Exten()

{ // 类的构造函数,第四个加载

System.out.println("d");

}

static

{ // 静态块,第一个加载

System.out.println("a");

}

static void run() // 静态方法,调用的时候才加载// 注意看,e没有加载

{

System.out.println("e");

}

public static void main(String[] args)

{

new Exten();

}

一般顺序:静态块——>静态变量——>成员变量——>构造方法——>静态方法1、静态代码块(只加载一次)2、构造方法(创建一个实例就加载一次)3、静态方法需要调用才会执行,所以最后结果没有e想知道顺序看看控制台!是不是一目了然了,

问题二:那么到这是不是已经完善了呢!请看下面问题很具有迷惑性!

public class StaticInitTest {

static int count = 2;      //定义静态变量(类变量)count,这个不是比较对象,下面的name是

static String name = "我的黑马之路";     //定义静态变量

static {              //通过静态初始化块为name变量初始化

System.out.println("StaticInitTest的静态初始化块!");

name = "黑马编程";

}

public static void main(String[] args) {

System.out.println("count的值:"+StaticInitTest.count);

System.out.println("name的值:"+StaticInitTest.name);

}

}

这是测试截图,请认真看看

116810158_1_20171121083404254.jpg

116810158_2_20171121083404910.jpg

你一看会发现就是啊,name的值改变了啊,这说明代码的执行改变了啊!

实际上:刚才说了执行,什么是执行,什么是编译看明白自己就明白了!

说实话,笔者研究这个问题一下午时间,为什么这么长时间,因为也没注意到这个问题,所以一直在深究内核的运作.....!

下面我们看看为什么会出现这种问题把,为什么name的值会改变,是执行的顺序改变了吗!

main方法中是什么,是不是只有打印语句,有没有操作上面的代码,没有把,其实是在不断的打印name这个静态对象的值

下面按前后顺序,分析谁在前,谁在后的执行结果

static

{

System.out.println("a静态块");

s = "我被编译了"; // 这里为什么不报错我们要理解Eclipse的编译顺序,从上到下依次编译,编译的时候就把所有的静态属性全部加载!

System.out.println(s);} // 这里你能获取到s吗? 系统会提示你,s还没有创创建,因为这里是第6行,你的对象在第8行才创建,编译不通过;

static String s = "你只是在打印我"; //这里才创建的String对象,按编译顺序s是多少?是不是变成了 "你只是在打印我"最终main函数中只是打印了s ,打印就是"你只是在打印我"

现在换位置:

static String s = "你只是在打印我" ; //编译通过先创建了String类型的s; s是多少?是不是"你只 是在打印我"

static

{

s = "我被编译了" ;

System.out.println(s); //Eclipse从上到下依次编译,,不是执行,是编译,编译到这,这里s是谁 ?是不是"我被编译了"

}

然后到这又把这个s直接打印了出来,打印结果肯定会变成,"我被编译了" !!

问题:有值就是执行过了吗?

总结:因为main方法中都是打印语句,只是在-----打印编译后加载的值-----而已;

打印不打印,name和s的值都在那里!注意不注意,name和s都是静态的!编译加载而已!

static String s = "静态String";

{

System.out.println("静态String"+s);

}

static int a = 5;

{

s  = "非静态int";

System.out.println("静态int变量");

}//还要注意的问题就是,在a中到底有没有给s赋值,很显然s的值此时未变,new的时候才执行到,为什么,请看下面的大总结!

实际上,以上的所有问题加起来就得到的完整的答案,你如果看到了这里恭喜你,笔者费劲总结的最终的正确的结果就在下面:

先把内在的执行规律简述:

静态变量这个问题是最不容易搞明白的问题,静态变量只加载一次,以后不论你怎么new不会再加载

而且注意:静态块也是仅加载一次,

静态变量后大括号内有代码的话,new一次执行一次。

静态块加载的时候大括号内的语句就执行完毕,以后不会执行。

是不是比较复杂,光看特性就已经复杂了,这里有些的同学可能就会想了,那这两个的执行顺序是怎么样的呢,这里非常的迷惑人,因为各种情况你得到的测试结果可能都不一样

不过他们还是有顺序的,只不过分情况对待!

大补充:

A、类的初始化顺序如下:

->1、为静态属性分配内存并赋值(后面大括号语句不执行,这里是初始化,只是添加变量和值)

或  执行静态代码块(立刻执行大括号里面的语句)

为什么这样说呢,因为谁在前先加载谁,包括静态属性之间,和静态块之间的顺序,

但是注意,虽然顺序都可以当第一,但是静态块、静态属性执行的东西完全不一样,怎么不一样,已经写上去了自己看

(笔者注:这个问题,在花了很多时间的推敲后,最终有了答案,前后花了不少的时间去运行代码,修改各种情况,也有同学参与了进来,所以大家对我们付出的努力应该尊重啊)

->2、为非静态属性分配内存并赋值

->3、构造方法(实际上这个先于非静态属性调用到,只是构造方法里面的语句暂停执行,等到非静态属性加载完才执行)

->4、执行非静态代码块 或 静态方法(都是调用了才加载)。

B、类的代码(大括号内的语句)执行顺序:   当你创建了对象的时候才会用到各个属性和变量对不对,这里就是这个顺序

->1、执行静态代码块(大括号包含的语句立刻执行,绝对是第一位的执行,没有能和它平级的)

->2、静态属性 (第二位执行)

->3、为非静态属性分配内存并赋值(大括号内语句第三位执行)

->4、构造函数

->执行非静态代码块 或 静态方法(都是调用了才加载)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值