欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Calender不是单例

程序员文章站 2022-07-12 18:48:08
...

         在我们使用Calender的时候,使用过Calendar.getInstance()来获取一个日期类的对象,这种方式跟单例的获取方式一样,那么它到底是不是单例呢,如果是单例的话,一个对象修改内容之后,另外一个线程中的数据不久乱套了吗?从试验以及源码中可以得出,Calendar不是单例。

测试:

  Calendar c1 = Calendar.getInstance();
  Calendar c2 = Calendar.getInstance();
  //输出true
  System.out.println("c1.equals(c2) is : "+c1.equals(c2));
  //输出false
  System.out.println("c1 == c2 is : "+ (c1 == c2));

 可以看出,两个实例的值相等,但是引用却不相等。

下面看看jdk的源码中的写法:

 

 
 public static Calendar getInstance()
    {
        Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault());
 cal.sharedZone = true;
 return cal;
    }


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);
    }

 

       可以看出,根据不同的语言环境,创建了不同的日期对象实例,低版本的JDK中,只对泰语做了特殊处于,高版本中又增加了日本的,具体实现有何不同,可以去看一下具体不同日期类的实现。

      而至于Calendar为什么用Calendar.getInstance()来获取实例对象,是因为它本身是个抽象类,是各种日期类实现类的父类,提供了Calendar.getInstance()给我们方便调用,根据不同的语言环境采取不同的实现,JDK帮我们封装了这些细节,所以直接使用

GregorianCalendar c1 = new GregorianCalendar();

 

来创建日期类的实例,其实也是可以的,但无疑破坏了封装性,多态性,我们也得像getInstance()方法里面处理的一样,根据不同的语言环境做不同的处理,所以我们还是不要破坏的好。