假设我有以下课程:
public class MyClass {
/* Note: Timestamp extends date */
public doSomething(java.sql.Timestamp timestamp){
System.out.println("Timestamp");
...
}
public doSomething(java.util.Date date){
System.out.println("Date");
...
}
}
假设我现在像这样执行我的代码:
MyClass myClass = new MyClass();
Date realDate = new Date();
Timestamp timestamp = new Timestamp(0);
Date casted = new Timestamp(0);
myClass.doSomething(realDate); // prints Date
myClass.doSomething(timestamp); // prints Timestamp
myClass.doSomething(casted); // prints Date!!!!! What?!
我遇到的问题是,由于casted
实际上不是日期,因此在我使用它时不起作用。
撇开:通常,不起作用的子类应该不是问题,但是Timestamp的javadoc说:
由于上述Timestamp类和java.util.Date类之间的差异,建议代码不要以java.util.Date的实例的形式一般性地查看Timestamp值。Timestamp和java.util.Date之间的继承关系实际上表示实现继承,而不是类型继承。
我知道我可以做这样的事情:
public doSomething(java.util.Date date){
if(date instanceof type){
System.out.println("Timestamp");
...
}
System.out.println("Date");
...
}
但这似乎令人讨厌。
有没有一种方法可以使子类的方法重载在不使用巨型switch语句的情况下起作用?
编辑:总而言之,这似乎Timestamp
违反了Liskov替换原则-如@Mick Mnemonic所指出的。
是的。不是你的虫子。它的设计怪癖java.util.Date
,java.sql.Date
和Timestamp
。(不要太在乎他们。java.util.Date
现在已经20岁了;他们在设计API时仍在弄清楚这些内容。)如果直接使用这些类型,则没有很好的解决方法。
一种方法是避免使用这些类,除非您必须在需要它们的API的边界处使用它们,而在其他地方使用一组设计更好的日期时间类型。在数据访问层中,必要时Timestamp
使用特殊情况等instanceof
。并将所有内容转换java.time
为内部代码的Joda-Time(对于Java 7)或/ JSR-310(对于Java 8)类型。(如果您实际上需要Java 7中的纳秒精度,则需要滚动自己的Timestamp对象以使用Joda-Time类型。不难;只需确保使用合成而不是像java.util
人们那样实现继承!:) )您可能会更快乐。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句