以前没注意过这个,这个还被楼主说中了
看源码吧    /**
     * Cache to hold the DateTimePatterns of a Locale.
     */
    private static final ConcurrentMap<Locale, String[]> cachedLocaleData
        = new ConcurrentHashMap<Locale, String[]>(3);    /**
     * Cache NumberFormat instances with Locale key.
     */
    private static final ConcurrentMap<Locale, NumberFormat> cachedNumberFormatData
        = new ConcurrentHashMap<Locale, NumberFormat>(3);
/* Package-private, called by DateFormat factory methods */
    SimpleDateFormat(int timeStyle, int dateStyle, Locale loc) {
        if (loc == null) {
            throw new NullPointerException();
        }        this.locale = loc;
        // initialize calendar and related fields
        initializeCalendar(loc);        /* try the cache first */
        String[] dateTimePatterns = cachedLocaleData.get(loc);
        if (dateTimePatterns == null) { /* cache miss */
            ResourceBundle r = LocaleData.getDateFormatData(loc);
            if (!isGregorianCalendar()) {
                try {
                    dateTimePatterns = r.getStringArray(getCalendarName() + ".DateTimePatterns");
                } catch (MissingResourceException e) {
                }
            }
            if (dateTimePatterns == null) {
                dateTimePatterns = r.getStringArray("DateTimePatterns");
            }
            /* update cache */
            cachedLocaleData.putIfAbsent(loc, dateTimePatterns);
        }
        formatData = DateFormatSymbols.getInstanceRef(loc);
        if ((timeStyle >= 0) && (dateStyle >= 0)) {
            Object[] dateTimeArgs = {dateTimePatterns[timeStyle],
                                     dateTimePatterns[dateStyle + 4]};
            pattern = MessageFormat.format(dateTimePatterns[8], dateTimeArgs);
        }
        else if (timeStyle >= 0) {
            pattern = dateTimePatterns[timeStyle];
        }
        else if (dateStyle >= 0) {
            pattern = dateTimePatterns[dateStyle + 4];
        }
        else {
            throw new IllegalArgumentException("No date or time style specified");
        }        initialize(loc);
    }这个实在缓存中缓存的,如果已经有了,后面就不再实例化对象了,就用已有的了

解决方案 »

  1.   

    System.out.println("aa的内存地址:"+aa);
     System.out.println("sdf的内存地址:"+sdf);
    你确定这输出的是对象的地址?它是调用对象的toString()方法,Object toString()源码:
    public String toString() {
            return getClass().getName() + "@" + Integer.toHexString(hashCode());
        }
    hashCode()函数声明:
    public native int hashCode();
    是一个本地方法。
      

  2.   

    源代码没有看太明白,哪个地方是缓存代码。
    刚才试了好几个类比如string,File这一些类。都是输出的一个地址。是否都用缓存了??
    是不是可以这样理解,jdk提供的类都提供了缓存机制,所以才输出一个地址。自己定义的类没有实现缓存机制。所以就是创建了多个对象。。
      

  3.   

    SimpleDateFoemat中hashCode的源码:
     public int hashCode()
        {
            return pattern.hashCode();
            // just enough fields for a reasonable distribution
        }
    其中pattern就是你这里的"yyyy-MM-dd HH:mm:ss",而且这个类没有重写toString()方法。所以只要采用同一个pattern,输出结果就是一样的。
      

  4.   

    不好意思,我说错了,是不同的对象
    打印的是哈希码,
        /**
         * Returns the hash code value for this <code>SimpleDateFormat</code> object.
         *
         * @return the hash code value for this <code>SimpleDateFormat</code> object.
         */
        public int hashCode()
        {
            return pattern.hashCode();
            // just enough fields for a reasonable distribution
        }继续跟进去,这个hashCode 方法是String 类的hashCode 方法
    字符串相同,导致得到相同的hash码
    public int hashCode() {
            int h = hash;
            if (h == 0 && value.length > 0) {
                char val[] = value;            for (int i = 0; i < value.length; i++) {
                    h = 31 * h + val[i];
                }
                hash = h;
            }
            return h;
        }
      

  5.   

    我知道了,其实我打印的都是哈希码。。
    我想问一下,在for循环里。SimpledateFormat创建了多少个对象。是一个,还是多个??
      

  6.   

    刚才我测试了一下         SimpleDateFormat sdf = new SimpleDateFormat();
    System.out.println(sdf);
    SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-mm-dd");
    System.out.println(sdf2);这2个输出的就不一样了。其实输出的是hash码。
    如果是这样         SimpleDateFormat sdf = new SimpleDateFormat();
    System.out.println(sdf);
    SimpleDateFormat sdf2 = new SimpleDateFormat();
    System.out.println(sdf2);输出的一样,那是创建了几个对象。还是2个么??
      

  7.   

      SimpleDateFoemat同一个pattern,输出结果就是一样的。
      /**
         * Returns the hash code value for this <code>SimpleDateFormat</code> object.
         *
         * @return the hash code value for this <code>SimpleDateFormat</code> object.
         */
        public int hashCode()
        {
            return pattern.hashCode();
            // just enough fields for a reasonable distribution
        }
    Object 的默认实现是This is typically implemented by converting the internal address of the object into an integer. 但是这个地址( internal address of the object )也不是内存地址,是虚拟机的内部地址。java出于安全不允许获取内存地址。
      

  8.   

    我有点明白了,因为传的参数一样。导致的hashcode是一样的。
    打印的hash码一样,不代表是同一个对象。
    所以,我的例子里.。for循环里的sdf应该是不同的对象。对吧。只要有new就是创建了对象。。
      

  9.   

    new 出来的都是不同的对象
    参考 java hashcode
    实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)   
    相同的对象必须返回同样的哈希码,但相同的哈希码不一定就是同一个对象
      

  10.   

    多谢了,我把代码修改了一下。。
    package com.sun.demo;import java.text.*;
    import java.util.*;
     
    class A {
        private int a;
      
        public A(int a) {
            this.a = a;
        }
        public int getA(){
            return this.a;
        }
    };
      
    public class Test03 {
        public static void main(String args[]) {
             
            A aa = null;
            for (int i = 1; i <= 10; i++) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                aa = new A(i);
                System.out.println("aa的内存地址:"+System.identityHashCode(aa));
                System.out.println("sdf的内存地址:"+System.identityHashCode(sdf));
            }
            System.gc();
        }
    }这样输出就都不一样了。。也就是说sdf和aa都是生成了多个对象。。对么?
      

  11.   

    都是多个对象,不同的是aa 是只有一个变量,每次指向不同的内存地址引用
    sdf 是每次新建的局部变量,指向自己new 返回的内存地址引用
    aa 变量只有一个,sdf 变量有多个