日期:2014-05-20  浏览次数:20724 次

求教,Java里的Calendar类问题
请问Calendar获取时间最终是调用的系统API还是由java自己实现的功能?请高人指教

------解决方案--------------------
调用系统的API
------解决方案--------------------
Calendar的getTime()方法是获取你当前操作系统的时间。
你可以这样试试。
 Calendar cal=new GregorianCalendar();
 System.out.println(cal.getTime());
把这两句。分别在当前时间和改完系统日期之后执行。看输入的时间就可以了。
------解决方案--------------------
NND,我刚才回复的又丢了?还好我复制了。。。


楼主这种问题,最重要的是需要掌握分析问题的方法。

那么这种问题,其实直接看看源码就知道了:

首先:Calendar 本身是 abstract 的,也即是抽象类,是无法实例化的。

那么研究下它的getInstance()函数吧:
public static Calendar getInstance(){
  Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault());
  cal.sharedZone = true;
  return cal;
}

继续跟踪createCalendar()函数:
private static Calendar createCalendar(TimeZone zone,
Locale aLocale) {
  // If the specified locale is a Thai locale, returns a BuddhistCalendar
  // instance.
  if ("th".equals(aLocale.getLanguage()) && ("TH".equals(aLocale.getCountry()))) {
  return new sun.util.BuddhistCalendar(zone, aLocale);
  } else if ("JP".equals(aLocale.getVariant()) && "JP".equals(aLocale.getCountry())
  && "ja".equals(aLocale.getLanguage())) {
  return new JapaneseImperialCalendar(zone, aLocale);
  }    

  // else create the default calendar
  return new GregorianCalendar(zone, aLocale);
}



所以最终就是:GregorianCalendar,再看看其构造函数:
public GregorianCalendar(TimeZone zone, Locale aLocale) {
  super(zone, aLocale);
  gdate = (BaseCalendar.Date) gcal.newCalendarDate(zone);
  setTimeInMillis(System.currentTimeMillis());
}

所以很清楚了,最终其实就是靠 System.currentTimeMillis(),来计算当前时间的,就是系统时间了。
------解决方案--------------------
时间是系统的时间,但是,年月日什么的,是由java本身自己转换的,毕竟,系统时间只是一个长整形的数据。你向前向后推移几天几个时间段,这些都要程序来实现。
------解决方案--------------------
Calendar从实现逻辑上应该是没有调用操作系统api的。全是原来sun公司自己写的逻辑。
但比如用到的GregorianCalendar去创建一个Calendar对象的时候,取得时区的时候还是通过调用系统api去取的设置的当前系统的时区。所以应该可以这么说:实现逻辑是jdk的东西,个别用到地方调用系统api(它只是辅助作用的)。
楼主看下源码能了解个大概了。

------解决方案--------------------
补充一下,就像上面说的取得
Calendar.getInstance()取得Calendar对象的时候,调用到System.currentTimeMillis(),还是要系统的api支持。
java有平台无关性的特点,是对我们编码的一种方便,但java本身还是离不开操作系统。