JAVA中代码顺序,静态块 静态变量,加载顺序! (转)
问题一:如下代码的执行顺序是什么样的!一定理解:是执行的顺序(后面会给大家说一个误区)!
classTest
{
int a =5;
staticint num =4; //这是一个很简单的代码,但是你了解他的运行顺序吗
Test(){
}
static{ // 那么可能你会有疑问,我该如何来去测试一下他们的执行顺序呢?
}
publicstaticvoid main(String[] args){
}
}
实际上你现在根本看不出来执行顺序,也很容易搞混淆,我们必须找出一种方便的手段去测试一下:
测试的方法:比如
staticint num =4;这句代码,我们怎么知道他是不是执行了,可以这样写
staticint num =4;{
system.out.println("执行了静态变量语句");}这样的话这段代码加载的时候,在控制台就能看到,是不是很方便!
public classExten
{
staticint 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");
}
staticvoid run()// 静态方法,调用的时候才加载// 注意看,e没有加载
{
System.out.println("e");
}
publicstaticvoid main(String[] args)
{
newExten();
}
一般顺序:静态块——>静态变量——>成员变量——>构造方法——>静态方法
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);
- }
- }
![黑马程序员:JAVA中代码顺序,静态块-静态变量-成员变量-构造方法-静态方法,是如何加载的! - Budier_GreatMan - 黑马空间](http://img0.ph.126.net/TCHA2UI_rVbShh_NRwPtJA==/1584422643921735190.jpg)
![黑马程序员:JAVA中代码顺序,静态块-静态变量-成员变量-构造方法-静态方法,是如何加载的! - Budier_GreatMan - 黑马空间](http://img2.ph.126.net/i8gPYZfgea7-ErMdyVmNFg==/3094817368951116712.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 ,打印就是"你只是在打印我"
现在换位置:
staticString s ="你只是在打印我";//编译通过先创建了String类型的s; s是多少?是不是"你只 是在打印我"
static
{
s ="我被编译了";
System.out.println(s);//Eclipse从上到下依次编译,,不是执行,是编译,编译到这,这里s是谁 ?是不是"我被编译了"
}
然后到这又把这个s直接打印了出来,打印结果肯定会变成,"我被编译了"!!
问题:有值就是执行过了吗?
打印不打印,name和s的值都在那里!注意不注意,name和s都是静态的!编译加载而已!
{
System.out.println("静态String"+s);
}
实际上,以上的所有问题加起来就得到的完整的答案,你如果看到了这里恭喜你,笔者费劲总结的最终的正确的结果就在下面:
先把内在的执行规律简述:
- 静态变量这个问题是最不容易搞明白的问题,静态变量只加载一次,以后不论你怎么new不会再加载
- 而且注意:静态块也是仅加载一次,
- 静态变量后大括号内有代码的话,new一次执行一次。
- 静态块加载的时候大括号内的语句就执行完毕,以后不会执行。
是不是比较复杂,光看特性就已经复杂了,这里有些的同学可能就会想了,那这两个的执行顺序是怎么样的呢,这里非常的迷惑人,因为各种情况你得到的测试结果可能都不一样
不过他们还是有顺序的,只不过分情况对待!
但是注意,虽然顺序都可以当第一,但是静态块、静态属性执行的东西完全不一样,怎么不一样,已经写上去了自己看
(笔者注:这个问题,在花了很多时间的推敲后,最终有了答案,前后花了不少的时间去运行代码,修改各种情况,也有同学参与了进来,所以大家对我们付出的努力应该尊重啊)
->2、为非静态属性分配内存并赋值
B、类的代码(大括号内的语句)执行顺序: 当你创建了对象的时候才会用到各个属性和变量对不对,这里就是这个顺序
这样的话是不是非常的清晰呢了!这才是所有代码加载的顺序啊,以后对于程序的执行就会有更深的理解了 !