Как ковариантные типы параметров работают в Java - PullRequest
6 голосов
/ 10 марта 2010

Учитывая, что у Date есть метод с именем "after (Date)", а у Timestamp есть метод с переопределением, который он назвал "after (Timestamp)", почему метод после в Date вызывается в следующем коде

Был задан вопрос о неожиданных результатах здесь .

    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

1 Ответ

10 голосов
/ 10 марта 2010

Перегрузки учитываются во время компиляции; переопределения учитываются во время выполнения.

Метка времени перегружает 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, хотя:

Из-за различий между Класс отметки времени и java.util.Date класс, упомянутый выше, это Рекомендуется, чтобы код не просматривать Значения отметки времени в общем виде экземпляр java.util.Date. наследственные отношения между Отметка времени и java.util. Дата действительно обозначает наследование реализации, а не наследование типов.

Для меня это звучит как довольно плохое использование наследования, если честно - но тогда у Java их много: (

...