故事背景

有一天,老鼠小白发现了一个奇怪的问题,它的奶酪的生产日期被谁搞丢了,不知道奶酪是否过期,可怎么吃呀?

让我们来看看吧

import java.util.Date;public class Cheese { public static final Cheese cheese=new Cheese();  private final long produceTimes;  private static final long produceDate =new Date(119,8,1).getTime();

  private Cheese() {        produceTimes=new Date().getTime()-produceDate;   }

   public long produceTimes() {      return produceTimes;  }

   public static void main(String[] args) {      System.out.println("current time in day(from 1900:00:00) : "+new Date().getTime()/(1000*60*60*24L));

     System.out.println("cheese had produces : "+ cheese.produceTimes()/(1000*60*60*24L) +" days");

    }}

按照小白的预期,程序该跑出奶酪上市了多少天,可是打印出的结果确实奶酪不会过期

current time in day(from 1900:00:00) : 18153cheese had produces : 18153 days

这是怎么回事呢?

破案

查看代码提交记录,发现老鼠小蓝有修改记录,仅仅调整了两行程序的顺序,小白原来的代码如下:

import java.util.Date;public class Cheese {

   private final long produceTimes;  private static final long produceDate =new Date(119,8,1).getTime();  public static final Cheese cheese=new Cheese();

    private Cheese() {        produceTimes=new Date().getTime()-produceDate;   }

   public long produceTimes() {      return produceTimes;  }

   public static void main(String[] args) {      System.out.println("current time in day(from 1900:00:00) : "+new Date().getTime()/(1000*60*60*24L));

     System.out.println("cheese had produces : "+ cheese.produceTimes()/(1000*60*60*24L) +" days");

    }}

仅仅修改了两个变量的顺序,输出的结果就大相径庭了

current time in day(from 1900:00:00) : 18153cheese had produces : 13 days

这才是小白鼠想要的结果!

于是小白鼠去请教java的创造者java之父

原来,实例的初始化也是有讲究的。

1.static字段先设置默认值,其中cheese被设置为null,produceDate被设置为0

2.然后static初始器执行,按照声明出现的顺序执行:

如果先执行cheese的话,调用Cheese()构造方法,此时用produceDate=0为值。

如果先执行produceDate的话,producteDate被设置为2019-09-01,再调用cheese()构造方法。

3 最后从构造器返回cheese类的初始化。

说明

Date设置日期为2019-09-01 为何设置为

new Date(119,8,1)

大家可以进去源码看说明情况

 /*** Allocates a <code>Date</code> object and initializes it so that* it represents midnight, local time, at the beginning of the day* specified by the <code>year</code>, <code>month</code>, and* <code>date</code> arguments.** @param year the year minus 1900.* @param month the month between 0-11.* @param date the day of the month between 1-31.* @see java.util.Calendar* @deprecated As of JDK version 1.1,* replaced by <code>Calendar.set(year + 1900, month, date)</code>* or <code>GregorianCalendar(year + 1900, month, date)</code>.*/@Deprecatedpublic Date(int year, int month, int date) {this(year, month, date, 0, 0, 0);}

其中,year份是从1900年开始的年数,即2019-1900=119

month是0~11计数的,需要实际月份减1,即9-1=8

date 是1~31计数的,实际天就可以 即1

参考资料

【1】https://docs.oracle.com/javase/specs/jls/se12/html/jls-12.html#jls-12.4

转载于:https://www.cnblogs.com/davidwang456/p/11518296.html

谁动了我的奶酪?--java实例初始化的顺序问题相关推荐

  1. 什么是Java实例初始化块

    在本篇文章,我将会使用一个例子展示什么是实例变量初始化块,实例初始化块和静态初始化块,然后说明在Java中实例初始化块是如何工作的. 执行顺序 查看下面的代码,你知道哪个先执行吗? package s ...

  2. java中初始化的顺序_Java中 初始化的先后顺序?

    我们在java中 Java中初始化的顺寻? java代码: package sru.love.c; class Person { String name = "Person"; s ...

  3. Java顺序栈的初始化_java - Java类变量初始化的顺序是什么? - 堆栈内存溢出

    在Java中,类变量按以下顺序初始化: 超类的静态变量 此类的所有静态变量都设置为其默认值 . 静态变量和静态初始化块,按声明顺序排列. 超类的实例变量 此类的所有实例变量都设置为其默认值 . 声明顺 ...

  4. Java对象初始化执行顺序

    Java是面向对象的语言,需要把一个大的项目细化成相应的类,在通过一个个类实例化对象,实例化一般都要初始化属性,常见初始化属性的方式有以下几种 定义时初始化 class Person{String n ...

  5. java程序初始化的顺序

    基本原则: 1)静态对象(变量)优先于非静态变量对象初始化,其中,静态对象(变量)只初始化一次,非静态对象可能多次初始化: 2)父类优先于子类进行初始化: 3)按照成员变量定义顺序进行初始化.即使变量 ...

  6. 百无聊赖时对java类初始化先后顺序的测试

    public   class  Test ... {     //属性     private String str = "123";              //域初始化    ...

  7. java中的实例初始化

    实例初始化有:实例变量初始化.实例初始化和静态初始化 1.执行顺序 下面这块代码,其执行顺序是怎么样的? public class Main {String s = "abc";p ...

  8. java程序初始化_Java程序初始化顺序

    今天在课上复习了Java的初始化顺序,一直有点疑惑,搞不明白,所以打算写下来,记录一下. 先说一下Java程序初始化的顺序:父类静态变量>父类静态代码块>子类静态变量>子类静态代码块 ...

  9. 面试题:Java类初始化顺序

    1. 问题来源 你遇到过哪些质量很高的 Java 面试? - ZO01的回答 - 知乎 https://www.zhihu.com/question/60949531/answer/579002882 ...

最新文章

  1. Python控制流---while循环
  2. PMP-【第15章 PMP考试的难点与易点】2021-2-17(304页-312页)【完】
  3. 使用ssh-keygen和ssh-copy-id三步实现SSH无密码登录
  4. HttpHandler动态生成图片
  5. iis worker process内存占用大_安卓模拟器磁盘空间占用大/内存空间不足
  6. linux修改可用的最大进程数量和可打开的最大文件数
  7. es的doc_value对排序字段的作用
  8. C# 类型转换问题一
  9. Python3——使用exec和eval执行字符串及计算其结果
  10. log4j.xml配置示例
  11. anaconda 导入cv2
  12. OSChina 周六乱弹 ——程序员想让对象一辈子跟你的秘籍
  13. MQL5 COOKBOOK - 以 MQL5 编写的多币种 EA,利用限价订单工作
  14. springboot整合规则引擎URule
  15. word应用:快速删除页眉横线
  16. [解决方法] 连接深信服Easyconnect之后无法代理抓包
  17. SpringBoot电商项目之购物车下单(沙箱支付)
  18. 2020李宏毅学习笔记——8. Convolution Netural Network
  19. 计算机网络第一章笔记呕心沥血之作 值得收藏
  20. OaisimWithS1搭建笔记(2019.5)

热门文章

  1. 专科生文科生学计算机有前途吗,我是一个双非大专生,感觉前途一片迷茫
  2. 配置oracle 11g环境,oracle 11g 的安装环境的配置
  3. docker 镜像重命名_Docker镜像管理(二)
  4. java实现自动收红包功能_Java实现抢红包功能
  5. 图形界面不卡的linux,图形化界面linux(linaro)的安装小结
  6. 再谈编程范式-程序语言背后的思想
  7. tensorflow 进阶(二),BP神经网络
  8. python3数字全排列怎么搞_python3实现字符串的全排列的方法(无重复字符)
  9. 168. Leetcode 134. 加油站 (贪心算法-模拟题目)
  10. 错误处理:one of the variables needed for gradient computation has been modified by inplace operation