Java小白踩坑录 - 类执行顺序

小白要实现一个记录奶酪生产期限的程序,昨天自测完后,提交给测试 MM 进行测试,测试 MM 测试完后说没有问题后小白才下班。今天早上测试 MM 走自动回归测试时,发现了 bug。

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

难道昨天和测试 MM 都眼花了?不可能呀!肯定是代码的问题。拉出看历史提交记录,发现仅有小胖对程序做了改动,将两行代码的顺序做了调换。调换前的程序如下:

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

这才是小白想要的结果,也是测试 MM 期望看到的结果。

 

追根究底

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

  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
 public 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。

发布了952 篇原创文章 · 获赞 1820 · 访问量 89万+

猜你喜欢

转载自blog.csdn.net/Dream_Weave/article/details/105401255