绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
谁动了我的奶酪?--java实例初始化的顺序问题
2019-12-27 10:24:36

故事背景

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

 

让我们来看看吧

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) : 18153

cheese 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) : 18153

cheese 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>.

*/ @Deprecated

publicDate(intyear,intmonth,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

分享好友

分享这个小栈给你的朋友们,一起进步吧。

JAVA玩具小屋
创建时间:2019-08-16 16:54:49
分享程序开发方面的小经验,思考一些比较简单易懂的技术问题
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

栈主、嘉宾

查看更多
  • Yios5092
    栈主

小栈成员

查看更多
  • 栈栈
  • coyan
  • 25minutes
  • ?
戳我,来吐槽~