协变参数类型如何在java中工作

s_t*_*v_e 6 java overloading

鉴于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());
    }
Run Code Online (Sandbox Code Playgroud)

结果

one: 1266873627200
two: 1266873627000
1266873627200 not after 1266873627000
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 10

在编译时考虑过载; 在执行时考虑覆盖.

时间戳重载 after,它不会覆盖现有方法 - 因此您oneDate.after(twoDate)只考虑方法java.util.Date; 而且即使你使用one.after(twoDate)它会仍然只使用after(Date)因为编译时类型twoDateDate不是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之间的继承关系实际上表示实现继承,而不是类型继承.

对我来说听起来像是一个非常糟糕的继承使用,说实话 - 然后Java有很多这些:(