协变参数类型如何在java中工作
鉴于Date有一个名为“after(Date)”的方法,而Timestamp有一个覆盖它的方法叫做“after(Timestamp)”,为什么Date中的after方法在下面的代码中被调用?
这里提出了关于意外结果的问题。
java.sql.Timestamp one = new java.sql.Timestamp(1266873627200L); java.sql.Timestamp two = new java.sql.Timestamp(1266873627000L); java.util.Date oneDate = (java.util.Date) one; java.util.Date twoDate = (java.util.Date) two; System.out.println("one: " + oneDate.getTime()); System.out.println("two: " + twoDate.getTime()); if (oneDate.after(twoDate)) { System.out.println(oneDate.getTime() + " after " + twoDate.getTime()); } else { System.out.println(oneDate.getTime() + " not after " + twoDate.getTime()); }
结果
one: 1266873627200 two: 1266873627000 1266873627200 not after 1266873627000
在编译时考虑过载; 在执行时考虑覆盖。
时间戳重载 after
,它不会覆盖现有方法 – 所以你的oneDate.after(twoDate)
只考虑java.util.Date
的方法; 此外,即使你使用one.after(twoDate)
它仍然只会使用after(Date)
因为twoDate
的编译时类型是Date
而不是Timestamp
。
如果你调用one.after(two)
那么将使用Timestamp.after(Timestamp)
。
Date.after(Date)
仅考虑毫秒 – 但Timestamp
仅向Date
的构造函数传递整数秒,因此即使您向构造函数传递了不同的值, oneDate
和twoDate
在Date
也具有相等的毫秒值。
值得注意的是Timestamp
的文档中的这一点:
由于Timestamp类和上面提到的java.util.Date类之间存在差异,因此建议代码不要将Timestamp值一般视为java.util.Date的实例。 Timestamp和java.util.Date之间的inheritance关系实际上表示实现inheritance,而不是类型inheritance。
对我来说听起来像是一个非常糟糕的inheritance使用,说实话 – 但是Java有很多那些:(