今天来研究一下含继承、静态成员、非静态成员时Java程序的执行顺序:

一、不含继承,含有静态变量、静态代码块

创建一个子类,该类包含静态变量、静态代码块、静态方法、构造方法

  1. /**
  2. * @createtime 2017年3月17日 下午5:17:02
  3. * @description 创建一个子类
  4. */
  5. public class Son{
  6. public static String name = "子类name";
  7.  
  8. public static long date = new Date().getTime();
  9.  
  10. public String time = String.valueOf(System.currentTimeMillis());
  11. /**
  12. * 静态代码块
  13. */
  14. static{
  15. System.out.println("子类静态代码块");
  16. System.out.println("子类静态代码块日期是:"+String.valueOf(date));
  17. }
  18.  
  19. /**
  20. * 非静态代码块
  21. */
  22. {
  23. System.out.println("子类非静态代码块");
  24. System.out.println("子类非静态代码块执行时间是:"+time);
  25. }
  26.  
  27. /**
  28. * 静态方法
  29. * @param names
  30. */
  31. public static void getName(String names){
  32. Son.name = names;
  33. System.out.println(name);
  34. }
  35.  
  36. /**
  37. * 默认构造方法
  38. */
  39. public Son(){
  40. this("构造son");
  41. System.out.println("子类默认构造方法");
  42. }
  43.  
  44. public Son(String names){
  45. System.out.println("子类含参构造方法");
  46. this.name = names;
  47. }
  48.  
  49. public static void main(String[] args) {
  50. getName("son-name");
  51. new Son();
  52. }
  53. }
  54.  
  55. /*不继承父类时--执行结果如下:
  56. 子类静态代码块
  57. 子类静态代码块日期是:1489742299514
  58. son-name
  59. 子类非静态代码块
  60. 子类非静态代码块执行时间是:1489742299514
  61. 子类含参构造方法
  62. 子类默认构造方法
  63. */

根据执行结果可以很直观的看出,执行顺序是:

静态代码块->调用的静态方法->非静态代码块->构造方法

这都是有明显输出情况下看到的顺序,还有一些变量的输出也是有顺序的,只是从结果不太容易看出,但是可以通过断点来调试,在调试之前一定要在所有变量、

方法及代码块前打上断点,这样看执行顺序就很明了,我打断点之后发现这个程序的整个执行过程是这样的:

静态变量赋值-->执行静态代码块-->非静态变量赋值-->执行非静态代码块-->调用静态方法-->调用构造方法

二、含继承、且父类也有静态变量、静态代码块和构造函数

1、创建一个子类,该类包含静态变量、静态代码块、构造方法

  1. /**
  2. * @createtime 2017年3月17日 下午4:25:26
  3. * @description 定义一个父类
  4. */
  5. public class Father {
  6.  
  7. public static String name = "变量father";
  8.  
  9. public static long date = new Date().getTime();
  10.  
  11. public String time = String.valueOf(System.currentTimeMillis());
  12. /**
  13. * 静态代码块
  14. */
  15. static{
  16. System.out.println("父类静态代码块");
  17. System.out.println("父类静态代码块日期是:"+String.valueOf(date));
  18. }
  19.  
  20. /**
  21. * 非静态代码块
  22. */
  23. {
  24. System.out.println("父类非静态代码块");
  25. System.out.println("父类非静态代码块执行时间是:"+time);
  26. }
  27.  
  28. /**
  29. * 默认构造方法
  30. */
  31. public Father(){
  32. this("构造father");
  33. System.out.println("父类默认构造方法");
  34. }
  35.  
  36. public Father(String name){
  37. System.out.println("父类含参构造方法");
  38. this.name = name;
  39. }
  40.  
  41. }
  42. /*继承父类时-执行结果如下:
  43. 父类静态代码块
  44. 父类静态代码块日期是:1489743876335
  45. 子类静态代码块
  46. 子类静态代码块日期是:1489743876336
  47. son-name
  48. 父类非静态代码块
  49. 父类非静态代码块执行时间是:1489743876336
  50. 父类含参构造方法
  51. 父类默认构造方法
  52. 子类非静态代码块
  53. 子类非静态代码块执行时间是:1489743876336
  54. 子类含参构造方法
  55. 子类默认构造方法*/

2、让子类Son继承父类Father

  1. /**
  2. * @createtime 2017年3月17日 下午5:17:02
  3. * @description 创建一个子类
  4. */
  5. public class Son extends Father{
  6. public static String name = "子类name";
  7.  
  8. public static long date = new Date().getTime();
  9.  
  10. public String time = String.valueOf(System.currentTimeMillis());
  11. /**
  12. * 静态代码块
  13. */
  14. static{
  15. System.out.println("子类静态代码块");
  16. System.out.println("子类静态代码块日期是:"+String.valueOf(date));
  17. }
  18.  
  19. /**
  20. * 非静态代码块
  21. */
  22. {
  23. System.out.println("子类非静态代码块");
  24. System.out.println("子类非静态代码块执行时间是:"+time);
  25. }
  26.  
  27. /**
  28. * 静态方法
  29. * @param names
  30. */
  31. public static void getName(String names){
  32. Son.name = names;
  33. System.out.println(name);
  34. }
  35.  
  36. /**
  37. * 默认构造方法
  38. */
  39. public Son(){
  40. this("构造son");
  41. System.out.println("子类默认构造方法");
  42. }
  43.  
  44. public Son(String names){
  45. System.out.println("子类含参构造方法");
  46. this.name = names;
  47. }
  48.  
  49. public static void main(String[] args) {
  50. getName("son-name");
  51. new Son();
  52. }
  53. }

同样打断点调试后发现详细的执行顺序是:

父类静态变量赋值-->执行父类静态代码块 -->子类静态变量赋值 -->执行子类静态代码块--> 调用子类静态方法--> 父类非静态变量赋值-->执行父类非静态代码块

-->执行父类构造方法-->子类非静态变量赋值-->执行子类非静态代码块-->执行子类构造函数

三、结论

根据以上分析,可以得出以下结论:

1、实例化一个子类时,优先实例化父类;

2、静态优先非静态执行;

3、静态变量优先,其次是静态代码块;

4、如果子类和父类都有静态成员,则优先执行父类中的静态成员;

Java问题解读系列之基础相关---含继承时的执行顺序的更多相关文章

  1. Java问题解读系列之基础相关---抽象类和接口

    今天来说一波自己对Java中抽象类和接口的理解,含参考内容: 一.抽象类 1.定义: public abstract class 类名{} Java语言中所有的对象都是用类来进行描述,但是并不是所有的 ...

  2. Java问题解读系列之String相关---String类为什么是final的?

    今天看到一篇名为<Java开发岗位面试题归类汇总>的博客,戳进去看了一下题目,觉得有必要夯实一下基本功了,所以打算边学边以博客的形式归纳总结,每天一道题, 并将该计划称为java问题解读系 ...

  3. Java问题解读系列之IO相关---Java深拷贝和浅拷贝

    前几天和棒棒童鞋讨论Java(TA学的是C++)的时候,他提到一个浅拷贝和深拷贝的问题,当时的我一脸懵圈,感觉自己学Java居然不知道这个知识点,于是今天研究了一番Java中的浅拷贝和深拷贝,下面来做 ...

  4. Java问题解读系列之String相关---String、StringBuffer、StringBuilder的区别

    今天的题目是String.StringBuffer和StringBuilder的区别: 首先还是去官方的API看看对这三种类型的介绍吧,Go...... 一.继承类和实现接口情况 1.String类 ...

  5. Java问题解读系列之String相关---String类的常用方法?

    今天的题目是:String类的常用方法? 首先,我们在eclipse中定义一个字符串,然后使用alt+/就会出现String类的所有方法,如下图所示: 下面我就挑选一些常用的方法进行介绍: 首先定义两 ...

  6. try,catch,finally含return时的执行顺序及丢失的伪例

    最近面试遇到一个之前也看到过但没去看一下的问题.就是有return情况下的try,catch,finally的执行顺序. 今天写了下. 先看顺序问题.总结如下: 一:finally中没有写return ...

  7. java中子类继承父类程序执行顺序

    java中子类继承父类程序执行顺序 FatherTest.java public class FatherTest { private String name; public FatherTest() ...

  8. Java 基础:继承中的执行顺序

    1.单独的父类测试 Java中,new一个类的对象,类里面的静态代码块.非静态代码.无参构造方法.有参构造方法.类的一般方法等部分, 它们的执行顺序相对来说比较简单,用程序也很容易验证. 比如新建一个 ...

  9. Java的初始化块、静态初始化块、构造函数的执行顺序及用途探究

    Java与C++有一个不同之处在于,Java不但有构造函数,还有一个”初始化块“(Initialization Block)的概念.下面探究一下它的执行顺序与可能的用途. 执行顺序 首先定义A, B, ...

随机推荐

  1. vim的个性化配置(方便编程)

    在用户主目录下新建vimrc即可.例如: vim ~/.vimrc 然后复制进去即可.   配置如下: "关闭vim一致性原则 set nocompatible "显示行号 set ...

  2. Vue.js项目部署到服务器

    1.申请服务器 2.配置Xshell 3.在服务器手动建自己的根目录,把根目录的文件名复制给项目里面config下面的index.js 4.项目开始打包 npm run build 5.打包完成之后把 ...

  3. 杂项-公司:Facebook

    ylbtech-杂项-公司:Facebook Facebook(脸书)是美国的一个社交网络服务网站 ,创立于2004年2月4日,总部位于美国加利福尼亚州帕拉阿图,2012年3月6日发布Windows版 ...

  4. Mac下使用Pecl安装PHP的Swoole扩展实践

    一.背景 前段时间把Mac系统重装了,PHP的一些扩展都没了,昨天需要调试一个swoole开发的项目,发现命令行中的PHP是系统自带的,如果安装swoole扩展很不方便:需要自己手动去下载swoole ...

  5. Activiti 接收任务活动

    流程中往往需要特定人接受任务并进行一定操作才能继续进行下去. 代码如下 import java.io.InputStream; import org.activiti.engine.ProcessEn ...

  6. elasticsearch river 从数据库中导入数据

    Elasticsearch中使用reiver-jdbc导入数据 2014-05-13 15:10 本站整理 浏览(3384)     Elasticsearch中使用reiver-jdbc导入数据,有 ...

  7. 动态规划——DP算法(Dynamic Programing)

    一.斐波那契数列(递归VS动态规划) 1.斐波那契数列——递归实现(python语言)——自顶向下 递归调用是非常耗费内存的,程序虽然简洁可是算法复杂度为O(2^n),当n很大时,程序运行很慢,甚至内 ...

  8. virtualbox 启动虚拟机提示Cannot load R0 module

    Cannot load R0 module C:\Program Files\Oracle\VirtualBox/VBoxDDR0.r0: SUPR3LoadModule: supLoadModule ...

  9. tp5.1 swoole 实现异步处理

    客户端请求:<?phpnamespace app\index\controller; class Index{ public function index() { $client = new \ ...

  10. List--使用List作为堆栈和队列

    1,List作为堆栈 堆栈“先进后出”.对此,可以使用append和pop来操作数据. 不指定下标时,pop会先操作最后一个数据. 例如: 2,队列 队列“先进先出”.当然也可以使用append和po ...