JAVA程序执行顺序

一。JAVA中执行顺序

  1. 静态块
  2. 构造器
  3. 父类构造器

二。JAVA中赋值顺序

  1. 静态块直接赋值
  2. 块直接赋值
  3. 父类继承的属性已赋值
  4. 静态变量声明时赋值
  5. 成员变量声明时赋值
  6. 构造器赋值

第一部分很好测试,我们只需要写一个子类,类中定义一个静态块,一个普通块,一个构造器,它的父类构造器,都打印一条语句,即可明白它们直接的执行顺序

Mastiff类

Java代码

  1. <SPANstyle="FONT-SIZE:medium">/**
  2. *子类藏獒
  3. */
  4. publicclassMastiffextendsDog{
  5. publicMastiff(){
  6. System.out.println("Mastiff");
  7. }
  8. {
  9. System.out.println("block");
  10. }
  11. static{
  12. System.out.println("staticblock");
  13. }
  14. publicstaticvoidmain(String[]args){
  15. Mastiffmastiff=newMastiff();
  16. }
  17. }
  18. </SPAN>

/**

* 子类藏獒

*/

public class Mastiff extends Dog {

public Mastiff() {

System.out.println("Mastiff");

}

{

System.out.println("block");

}

static {

System.out.println("static block");

}

public static void main(String[] args){

Mastiff mastiff=new Mastiff();

}

}

DOG类

Java代码

  1. <SPANstyle="FONT-SIZE:medium">/**
  2. *DOG父类
  3. */
  4. publicclassDog{
  5. publicDog(){
  6. System.out.println("Dog");
  7. }
  8. }
  9. </SPAN>

/**

*DOG父类

*/

public class Dog {

public Dog() {

System.out.println("Dog");

}

}

运行结果为:

static block
Dog
block
Mastiff

也就是说,在我们的程序中,实例化一个类对象的时候,运行顺序为:

  1. 静态块
  2. 父类构造器
  3. 本类中的块
  4. 本类的构造器

我们可以更进一步,如果在父类中也有块和静态块呢?

DOG类改进后源码

Java代码

  1. <SPANstyle="FONT-SIZE:medium">/**
  2. *DOG父类
  3. */
  4. publicclassDog{
  5. publicDog(){
  6. System.out.println("Dog");
  7. }
  8. static{
  9. System.out.println("superstaticblock");
  10. }
  11. {
  12. System.out.println("superblock");
  13. }
  14. }
  15. </SPAN>

/**

*DOG父类

*/

public class Dog {

public Dog() {

System.out.println("Dog");

}

static{

System.out.println("super static block");

}

{

System.out.println("super block");

}

}

Mastiff改进后源码

Java代码

  1. <SPANstyle="FONT-SIZE:medium">/**
  2. *子类藏獒
  3. */
  4. publicclassMastiffextendsDog{
  5. publicMastiff(){
  6. System.out.println("Mastiff");
  7. }
  8. {
  9. System.out.println("block");
  10. }
  11. static{
  12. System.out.println("staticblock");
  13. }
  14. publicstaticvoidmain(String[]args){
  15. Mastiffmastiff=newMastiff();
  16. }
  17. }
  18. </SPAN>

/**

* 子类藏獒

*/

public class Mastiff extends Dog {

public Mastiff() {

System.out.println("Mastiff");

}

{

System.out.println("block");

}

static {

System.out.println("static block");

}

public static void main(String[] args){

Mastiff mastiff=new Mastiff();

}

}

运行的结果为:

super static block
static block
super block
Dog
block
Mastiff

也就是说此时的运行顺序为:

  1. 父类静态块
  2. 自身静态块
  3. 父类块
  4. 父类构造器
  5. 自身块
  6. 自身构造器

好了,知道了运行的顺序,那么这是为什么呢?

这就要从JVM中类的装载机制和实例化机制开始说起,这里因为主题原因,先不讨论,有兴趣的同学可以自己查资料。

我们再来讨论第二个问题,一个变量的值,它有可能在哪些地方确定呢??

  1. 从父类继承该值(包括:1.作为父类的成员变量已经赋值 2.在父类的块中赋值 3.在父类的构造器中赋值)
  2. 在构造器中对其进行赋值
  3. 在块中进行赋值
  4. 在方法调用中进行赋值

现在假设在我们刚刚的例子中,有一个变量type,表示狗的品种

Java代码

  1. <SPANstyle="FONT-SIZE:medium">/**
  2. *DOG父类
  3. */
  4. publicclassDog{
  5. publicStringtype="父类成员变量赋的值";
  6. publicDog(){
  7. System.out.println("父类构造器--type-->"+type);
  8. type="父类构造器赋的值";
  9. System.out.println("父类构造器----type--->"+type);
  10. }
  11. {
  12. System.out.println("block---type--->"+type);
  13. type="父类块赋的值";
  14. }
  15. }
  16. </SPAN>

/**

*DOG父类

*/

public class Dog {

public String type="父类成员变量赋的值";

public Dog() {

System.out.println("父类构造器--type-->"+type);

type="父类构造器赋的值";

System.out.println("父类构造器----type--->"+type);

}

{

System.out.println("block---type--->"+type);

type="父类块赋的值";

}

}

Java代码

  1. <SPANstyle="FONT-SIZE:medium">/**
  2. *子类藏獒
  3. */
  4. publicclassMastiffextendsDog{
  5. publicStringtype="成员变量赋的值";
  6. publicMastiff(){
  7. System.out.println("构造器---type--->"+type);
  8. type="构造器赋的值";
  9. }
  10. publicvoidsay(){
  11. System.out.println("say---type---->"+type);
  12. }
  13. {
  14. System.out.println("block---type--->"+type);
  15. type="块赋的值";
  16. }
  17. publicstaticvoidmain(String[]args){
  18. Mastiffmastiff=newMastiff();
  19. mastiff.say()</SPAN><SPANstyle="FONT-SIZE:medium">;</SPAN><SPANstyle="FONT-SIZE:medium">
  20. }
  21. }
  22. </SPAN>

/**

* 子类藏獒

*/

public class Mastiff extends Dog {

public String type="成员变量赋的值";

public Mastiff() {

System.out.println("构造器---type--->"+type);

type="构造器赋的值";

}

public void say(){

System.out.println("say---type---->"+type);

}

{

System.out.println("block---type--->"+type);

type="块赋的值";

}

public static void main(String[] args){

Mastiff mastiff=new Mastiff();

mastiff.say();

}

}

执行结果如下:

block---type--->父类成员变量赋的值
父类构造器--type-->父类块赋的值
父类构造器----type--->父类构造器赋的值
block---type--->成员变量赋的值
构造器---type--->块赋的值
say---type---->构造器赋的值

答案很明显,赋值顺序为:

  1. 父类成员变量赋值
  2. 父类块赋值
  3. 父类构造器赋值
  4. 自身成员变量赋值
  5. 自身块赋值
  6. 自身构造器赋值

结合我们前面说的程序中的执行顺序,这个显然是很好理解的:

1.成员变量赋值>>>块赋值>>>构造器赋值

2.父类的块>>父类构造器>>自身块>>自身构造器

又因为一个成员变量是不可能在静态变量中赋值的,而且又前面程序执行顺序可知

静态块>>块

所以,程序的赋值步骤为

  1. 父类的静态变量赋值
  2. 自身的静态变量赋值
  3. 父类成员变量赋值
  4. 父类块赋值
  5. 父类构造器赋值
  6. 自身成员变量赋值
  7. 自身块赋值
  8. 自身构造器赋值

无原文地址

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值