Java 为什么在使用遗留API时,日期比日历更适合属性键入?
首先,请注意,此问题不是此问题的重复: . 我的问题要具体得多。引用的问题问“什么”(或“哪个”),但我已经知道“什么”,并且正在问“为什么” 我所在的团队正在为客户机改进现有Java项目。这个Java项目使用Java6,并且没有Joda时间作为依赖项。询问之后,似乎添加Joda时间或升级到Java8都不是选项Java 为什么在使用遗留API时,日期比日历更适合属性键入?,java,date,calendar,Java,Date,Calendar,首先,请注意,此问题不是此问题的重复: . 我的问题要具体得多。引用的问题问“什么”(或“哪个”),但我已经知道“什么”,并且正在问“为什么” 我所在的团队正在为客户机改进现有Java项目。这个Java项目使用Java6,并且没有Joda时间作为依赖项。询问之后,似乎添加Joda时间或升级到Java8都不是选项 因此,在将日期/时间表示为对象中的字段时,我们必须使用日历或日期来键入属性。这个项目的遗留代码中充斥着使用日历来表示日期/时间字段的对象,这些字段是我们永远无法处理的(比如在添加或减去
因此,在将日期/时间表示为对象中的字段时,我们必须使用日历或日期来键入属性。这个项目的遗留代码中充斥着使用日历来表示日期/时间字段的对象,这些字段是我们永远无法处理的(比如在添加或减去时间单位时,等等)。我知道这是一种不好的做法,因为日历是一个更复杂的对象,而日期更简单,也同样有效。(当然,我知道这两个都是很长一段时间内的基本包装,都是可变的,设计也很差,但这也是我们仅有的两个选择。) 换句话说,像这样的对象:
public class Reservation {
private Guest guest;
// Set only once, never used for calculations
private Calendar dateReserved;
...
}
应该是这样的:
public class Reservation {
private Guest guest;
// Set only once, never used for calculations
private Date dateReserved;
...
}
然后我注意到,当为新功能添加新对象时,我的团队遵循同样的惯例,使用日历而不是日期。当我提出这个问题时,我的回答是最好使用Calendar,因为它可以做更多的事情,并且不像Date那样有所有这些不推荐的方法
我知道这个理由过于简单化了。我还看到对于更广泛的使用问题表达了相同的观点,即日历不应用于属性键入。然而,答案并没有包含太多关于为什么不应该首选日历的解释
所以我已经知道“什么”了。但我想向我的团队说明情况,所以我的问题是,“为什么”?为什么在键入属性时,日期应优先于日历?使用日历而不是日期键入属性有什么缺点?日期对象比日历对象具有更少的字段和占用更少的内存,并且实例化速度更快 我同意Jon Skeet关于日历系统和时区的评论,我认为你的前提存在根本性缺陷。日期并不比日历好。如果你从来没有比较过时间,或者从来没有在不同的时区有过两个日期,那么当然,我想更小的内存占用可能会更好,但在这一点上,只需要使用long和Unix时间戳。日历是迄今为止更好的对象模型,毕竟,如果您确实需要它,您可以从中获取日期对象。如果您在属性键入时不得不在日期和日历之间进行选择,请: 如果以下任一项为真,则使用日历:
- 初始设置日期/时间后,您需要能够调整日期/时间 (例如更改月份,同时保持日期和时间不变)
- 你需要知道时区
public class Reservation {
private Guest guest;
private Calendar dateReserved;
@Override
public String toString() {
return String.format("Reservation{guest=%s,dateReserved=\"%s\"}",
guest, dateReserved);
}
}
现在,如果您打印出这个类的一个实例,您将得到一些可怕的结果:
Reservation{guest=guest{id=17,name=“John Smith”},dateReserved=“java.util.GregorianCalendar[time=1426707020619,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id=“America/LosèAngeles”,offset=-28800;=3600000,dstaving=true,transitions=185,lastRule=java.util.SimpleTimeZone[id=America/Los_Angeles,offset=-2880000,dstSaves=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDayOfWeek=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],周的第一天=1,周的第一天=1,纪元=1,年=2015,月=2,年的周=12,月的周=3,月的日=18,年的日=77,周的日=4,月的周的日=3,上午下午=1,小时=0,日的小时=12,分钟=30,秒=20,毫秒=619,分区偏移量=-288000000,DST偏移量=3600000
然而,如果您使用Date,则会得到以下结果:
预订{guest=guest{id=17,name=“John Smith”},dateReserved=“Wed Mar 18 12:34:26 PDT 2015”}
因此,如果您使用Calendar并且希望toString()可用,则需要调用dateReserved.getTime()--这意味着您需要添加一个空检查。这涉及到是否最终使用DateFormat对象
“我知道两者基本上是同一个概念”-嗯,不,它们不是。日期是一个时间点,没有相关的日历系统或时区。
日历有一个日历系统,根据其具体类别(例如Gregorianalendar)并且可以设置为任何时区。你对哪个时区感兴趣,你希望如何向Date
解释这一点?@JonSkeet你是对的,我应该澄清一下——我的意思是,我知道他们都是通过包装一个很长的历元毫秒来完成任务的。