java基础知识分析

java基础知识分析一 问题代码示例 代码本身没有任何语法错误 费解的是它执行的结果 true true false 输出的前两行很正常 显然 d1 和 d3 分别早于 d2 和 d4 但 d5 却是晚于 d6 二 复习 Java 基础知识 Java 中子类向父类转型 向上转型 时 以下三点规则很重要 无论是方法还是变量 default protected 都是调用的子类的 如果子类没有或已重载某个方法时

大家好,我是讯享网,很高兴认识大家。



(一). 问题代码示例

代码本身没有任何语法错误,费解的是它执行的结果:

true

true

false 输出的前两行很正常,显然d1和d3分别早于d2和d4,但d5却是晚于d6!?

(二). 复习 Java 基础知识

Java中子类向父类转型(向上转型)时,以下三点规则很重要:

无论是方法还是变量(default、protected)都是调用的子类的;

如果子类没有或已重载某个方法时,则调用的是父类的方法;

如果子类有而父类没有则编译报错,总之是向父类看齐。

2. 关于构造方法:

子类的构造方法执行过程中会先自动调用父类的无参构造方法;

如果显式调用 super([args...]),则不会再自动调用父类的无参构造方法;

super([args...]java基础知识分析) 必须写在子类构造函数的第一行,以在语法上申明一种从属关系;

如果父类的无参构造方法为 private,则子类必须显式调用父类的其他公共有参构造方法。

(三). 分析执行过程

Date 类中的方法是:

讯享网

因此代码中实际调用的是Date 类的 before方法,而非子类(Timestamp)的 before方法。

Date类中的 before方法实际上是调用的 getMillisOf方法来判断,并且Timestamp类中并没有重写该方法。

既然如此,那么getMillisOf 方法也是使用的父类Date 中的实现了:

 

Date 中的有个内部变量 cdate,Timestamp中同样没有,这个变量在何时初始化呢?

显然d5、d6的Date类实际上在d1、d2声明时就已初始化好(调用父类构造函数):

讯享网

在来看看Timestamp 类的这个带参构造方法:

 

其中显示调用了父类Date 类的带参构造方法,并且没有传入nanos(毫秒),而是将其保存在私有变量中,

因此,Timestamp向父类Date转型时丢失了毫秒,导致后面调用Date类的before方法时出现错误的结果。

(四). 后记

几年前写过一篇与Timestamp类相关的文章:java.sql.Date 时分秒去哪了?

没想到几年后又遇到类似的问题,虽然没有造成携程宕机事件的严重后果,但也足以警醒世猿。

解决方法是:

在任何场合关于时间类型的比较都比较其数字时间戳,使用 getTime() 方法,防止此类隐藏问题。

至于Date类的实现中为何要加入一个BaseCalendar.Date 类型的cdate,以及fastTime 就不得而知,还望相告;

小讯
上一篇 2024-12-24 08:35
下一篇 2025-01-01 23:49

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/8668.html