Calender不是单例

         在我们使用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()方法里面处理的一样,根据不同的语言环境做不同的处理,所以我们还是不要破坏的好。

你可能感兴趣的:(单例,Calender)