Java 中静态方法内部的这种奇怪的动态方法调度行为是什么
What is this weird dynamic method dispatch behavior inside a static method in Java
以下示例中的实用方法仅用于说明目的。
在下面的示例中,instance method
调用被分派给引用类型,但没有分派给 运行-time 对象。
import java.sql.Timestamp;
import java.util.Date;
public class DynamicMethodDispatchEx {
public static void main(String[] args) {
Timestamp now = new Timestamp(System.currentTimeMillis());
Timestamp beforeNow = new Timestamp(now.getTime() - 1);
System.out.println("Finding newest in " + now + " and " + beforeNow);
System.out.println("Attempt 1: " + staticFindNewer(beforeNow, now));
System.out.println("Attempt 2: " + staticFindNewer(now, beforeNow));
}
public static Date staticFindNewer(Date one, Date two) {
if (one.after(two)) {
return one;
} else {
return two;
}
}
}
下面是我得到的输出
Finding newest in 2016-08-23 17:56:36.375 and 2016-08-23 17:56:36.374
Attempt 1: 2016-08-23 17:56:36.375
Attempt 2: 2016-08-23 17:56:36.374 // <---
经过一些调查,我发现 java.util.Date.after(Date)
在 staticFindNewer()
中被调用,并且尝试 1 和 2 中的差异是由于使用 Date 的方法造成的精度损失。
但是,我对动态调度感到困惑。 我希望 Timestamp#after(Timestamp)
被调用,但 Date#after(Date)
被调用了。 我认为实例方法调度总是基于 运行time 对象。我是否遗漏了一些愚蠢的东西(很可能)?
I expected Timestamp#after(Timestamp)
to be invoked but Date#after(Date)
was getting invoked. I thought the instance-method dispatch was always based on runtime object.
动态分派只发生在被调用的对象上,而不发生在参数上。
所以调用会转到Timestamp#after(Date)
(因为参数的编译时类型是Date
,而被调用者的运行时类型是Timestamp
)。
不幸的是,Timestamp
没有覆盖这个方法,所以它默认返回到 Date#after(Date)
(这里不太好用)。
所以你必须确保直接调用 Timestamp#after(Timestamp)
,或者使用正确实现的 Date#compareTo(Date)
方法(并在 Timestamp
中覆盖)。
以下示例中的实用方法仅用于说明目的。
在下面的示例中,instance method
调用被分派给引用类型,但没有分派给 运行-time 对象。
import java.sql.Timestamp;
import java.util.Date;
public class DynamicMethodDispatchEx {
public static void main(String[] args) {
Timestamp now = new Timestamp(System.currentTimeMillis());
Timestamp beforeNow = new Timestamp(now.getTime() - 1);
System.out.println("Finding newest in " + now + " and " + beforeNow);
System.out.println("Attempt 1: " + staticFindNewer(beforeNow, now));
System.out.println("Attempt 2: " + staticFindNewer(now, beforeNow));
}
public static Date staticFindNewer(Date one, Date two) {
if (one.after(two)) {
return one;
} else {
return two;
}
}
}
下面是我得到的输出
Finding newest in 2016-08-23 17:56:36.375 and 2016-08-23 17:56:36.374
Attempt 1: 2016-08-23 17:56:36.375
Attempt 2: 2016-08-23 17:56:36.374 // <---
经过一些调查,我发现 java.util.Date.after(Date)
在 staticFindNewer()
中被调用,并且尝试 1 和 2 中的差异是由于使用 Date 的方法造成的精度损失。
但是,我对动态调度感到困惑。 我希望 Timestamp#after(Timestamp)
被调用,但 Date#after(Date)
被调用了。 我认为实例方法调度总是基于 运行time 对象。我是否遗漏了一些愚蠢的东西(很可能)?
I expected
Timestamp#after(Timestamp)
to be invoked butDate#after(Date)
was getting invoked. I thought the instance-method dispatch was always based on runtime object.
动态分派只发生在被调用的对象上,而不发生在参数上。
所以调用会转到Timestamp#after(Date)
(因为参数的编译时类型是Date
,而被调用者的运行时类型是Timestamp
)。
不幸的是,Timestamp
没有覆盖这个方法,所以它默认返回到 Date#after(Date)
(这里不太好用)。
所以你必须确保直接调用 Timestamp#after(Timestamp)
,或者使用正确实现的 Date#compareTo(Date)
方法(并在 Timestamp
中覆盖)。