1. 我在 类 A中实现 Serializable 接口,做了个 static 块,里面 print 出 信息,我在把该A对象序列化到文件之后,在另一个 JVM实例中反序列化回来,这时 static 块也得到执行了,而我把 A.class 文件删除调,那么执行到 readObjct() 的时候就报错: ClassNotFoundException 了,看来在 readObject() 的时候就去找A的 class 文件了,而不是按 thinking in java 里说的,反序列化的时候不需要 class文件,只有之后进一步操作 如 getClass 的时候才去加载 class 文件 ? 2. 集合类基本都自己实现了 writeObject() 和 readObject(),而不是依靠默认的实现机制。 LinkedList 中实现这2个 序列化方法是为了避免时间和空间不必要的开销和防止栈溢出。那么 HashMap 呢 ? 《effective java》里说因为 hash 的计算依赖于 jvm 的一次执行,所以不同次或者不同的jvm根据hash算法最后计算出来的hashcode可能不一致,如果按默认的序列化将key与value存在entry数组中时,到时算出来的key就定位不到value了,所以必须在自己实现的readObject()中重新计算key和重新组织 Entry[] 。但是我不解的是我们的 key对象只要都按规则重写了 hashcode()方法,那么就不管里在哪个jvm上执行,key.hashcode() 返回的值都是相同的,虽然 hash算法将 key.hashcode() 进行了 移位等操作得到最后的hash值,但是移位等操作难道和不同的JVM平台相关吗 ? 所以我一直不能理解为什么 hash算法得到的hash值依赖与JVM一次执行这句话。以下贴上HashMap中计算hash的源码供参考:     public V get(Object key) { 
        Object k = maskNull(key); 
        int hash = hash(k); 
        int i = indexFor(hash, table.length); 
        Entry<K,V> e = table[i]; 
        while (true) { 
            if (e == null) 
                return null; 
            if (e.hash == hash && eq(k, e.key)) 
                return e.value; 
            e = e.next; 
        } 
    }   static int hash(Object x) { 
        int h = x.hashCode();         h += ~(h << 9); 
        h ^=  (h >>> 14); 
        h +=  (h << 4); 
        h ^=  (h >>> 10); 
        return h; 
    }   static int indexFor(int h, int length) { 
        return h & (length-1); 
    }    以上2个问题请知道的朋友解惑,谢谢 

解决方案 »

  1.   

    这主要是说没有自己实现hashCode的类,  采用了Object的默认hashCode方法, 那么hashCode肯定是不一样的
      

  2.   

    任何对象都得有类,  没有例外,  不可能在 getClass 的时候才报 ClassNotFoundException
      

  3.   

    1.这就要看readObjct()的定义是需要序列化文件还是类文件了,我觉得这个问题thinking in java不太会说错,可能是你理解错了,原文是什么呢2.“hash算法得到的hash值依赖与JVM一次执行” 
    这句话是什么意思呢,感觉不太通顺啊
    hash值要通过jvm计算出来?可能就是hash算法是一致的,结果依赖随机执行,也就是某次具体的jvm运算,是这个意思吗,但hash算法中有随机量因素吗,也许这里就是int h = x.hashCode(); effective java中原文有吗
      

  4.   

    1可能是楼主理解错了意思,发原文来看看。2.java类都有自己的hashcode实现方法,如果你自己的类没有hashcode方法,就会调用object的本地hashcode方法跟jvm有关。个人理解。
      

  5.   

      针对第2点,自己的类肯定要实现hashcode的,否则不要说这里的序列化,连 get(key)都会出现错误的