zoukankan      html  css  js  c++  java
  • 谁动了我的奶酪?--java实例初始化的顺序问题

    故事背景

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

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

     

    让我们来看看吧

    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

    这是怎么回事呢?

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

     

    破案

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

    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之父

    谁动了我的奶酪?--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
     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

    参考资料

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

  • 相关阅读:
    有关创造力的书籍推荐
    如何做好组织管理?
    EMBA方面的经典自学教材、书籍推荐
    人力资源管理书单推荐
    创新创业类书籍推荐
    企业如何进行组织变革?
    VMS(VELO) tips[转载]
    SAP R/3系统的概念与介绍
    Project Record: RCM Program–Change Delivery Date in VMS Action[转载]
    SQL Server触发器创建、删除、修改、查看示例步骤
  • 原文地址:https://www.cnblogs.com/davidwang456/p/11518296.html
Copyright © 2011-2022 走看看