import java.io.*;
class Student implements Externalizable
{
   private String name;
   private int age;
   
   public Student()
   {
      System.out.println("调用Student无参数的构造方法");
   }
   public Student(String name,int age)
   {
      this.name=name;
      this.age=age;
      System.out.println("调用Student带参的构造方法");
   }
   public String toString()
   {
      return "姓名:"+name+" 年龄:"+age;
   }
   //序列化对象中的属性
   public void writeExternal(ObjectOutput out) throws IOException
   {
     out.writeObject(name);
     out.writeObject(age);
   }
   //反序列化对象中的属性
   public void readExternal(ObjectInput in) throws IOException,ClassNotFoundException
   {
      name=(String)in.readObject();
      age=(Integer)in.readObject();
   }
   
}
public class ObjExternalSer
{
public static void main(String args[])
{
try{

    FileOutputStream fileOut=new FileOutputStream("test.obj");
ObjectOutputStream oos=new ObjectOutputStream(fileOut);

Student s1=new Student("张三",40);
oos.writeObject(s1);
    
oos.close();


        FileInputStream fileIn=new FileInputStream("test.obj");
ObjectInputStream ois=new ObjectInputStream(fileIn);

Student s3=(Student)ois.readObject();

System.out.println("是否为同一个对象:"+(s1==s3));
    System.out.println(s3);
    
    ois.close();
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e1)
{
e1.printStackTrace();
}
}
}红色代码部分输出为false,为什么不是true(书上说是true)。 同一个对象序列化再反序列化后,就不是同一段内存空间了吗? 请高手明示,谢谢了

解决方案 »

  1.   

    问题太多了
    1) 比较两个对象是否相等,不能用==,只能用equals
    2) 你可能还不知道怎么正确的写一个equals。
    3) 没关系,很多Javaer都不知道Object的equals都干了什么。
    4) 你写好了equals,其实还没有完事呢
      

  2.   

    我知道==和equals()的区别,  我现在想问的是序列化与反序列化的问题, 感觉书上错误很多 而且是孙卫琴的书 呵呵
      

  3.   

    再student类里面 ,添加 public static final long serializableUID = 42L;
    然后再运行,应该就ok了LZ给分吧
      

  4.   


    那是控制序列化版本的兼容性问题,还是false。刚才在百度上找到一段话:
    反序列化后知识状态和以前一致,即各个属性的值一样。但并不是同一个对象。
    就像是对任意一个简单的对象进行序列化,再反序列化得到的对象也和之前的对象不是同一个。
      

  5.   

    serializableUID只是个版本标识~4楼和6楼 你俩看书去吧~ 等成为了像我们一样的半吊子水平,再来学我们吹水~
      

  6.   

    要想返回同一个对象,得实现单例模式。并且还要写readResolve方法,下面代码:
    /**
     * 用来序列化和反序列化的单例类
     * 
     * @author <a href="mailto:[email protected]">Administrator</a>
     * @version 1.0
     * @since 2012-7-31
     */
    public class Alien implements Serializable { /**
     * 
     */
    private static final long serialVersionUID = 2862048673777473868L; private Alien() { } private static Alien alien; public synchronized static Alien getInstance() {
    if (alien == null) {
    alien = new Alien();
    }
    return alien;
    } /**
     * 反序列化单例需要 ,在反序列化时会被调用,若不加此方法 则反序列化的类不是单例的
     */
    private Object readResolve() throws ObjectStreamException {
    return getInstance();
    }
    }/**
     * 序列化Alien类
     * 
     * @author <a href="mailto:[email protected]">Administrator</a>
     * @version 1.0
     * @since 2012-7-31
     */
    public class SerializeAlien {
    public static void main(String[] args) throws FileNotFoundException, IOException {
    ObjectOutput out = new ObjectOutputStream(new FileOutputStream("X.file"));
    Alien alien = Alien.getInstance();
    out.writeObject(alien);
    }
    }
    /**
     * 反序列化
     * 
     * @author <a href="mailto:[email protected]">Administrator</a>
     * @version 1.0
     * @since 2012-7-31
     */
    public class DeserializeAlien {
    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
    ObjectInput input = new ObjectInputStream(new FileInputStream("X.file"));
    Alien alien1 = (Alien) input.readObject();
    Alien alien2 = Alien.getInstance();
    System.out.println(alien1 == alien2);
    }
    }至于你实现的为什么不相等,这个比较复杂了,看看readObject源码吧,这个是根据字节码生成的对象,不是调用原方法的构造函数。有点难解释了,因为我也理解不深入。
      

  7.   

    java还真不是太懂,。net的话肯定是false了,两个对象属性都相等也不行,除非是同一个对象
      

  8.   

    ==比较他们的地址,你重新赋值给了s3对象,他们不是存在一个内存地址里边。
    你如果直接像我下边一样改动,他们都是s1对象,你看我下边改动的代码public class ObjExternalSer
    {
    public static void main(String args[])
    {
    try{FileOutputStream fileOut=new FileOutputStream("test.obj");
    ObjectOutputStream oos=new ObjectOutputStream(fileOut);Student11 s1=new Student11("张三",40);
    oos.writeObject(s1);
    oos.close();
    s1=null;
    FileInputStream fileIn=new FileInputStream("test.obj");
    ObjectInputStream ois=new ObjectInputStream(fileIn);
    //Student11 s3=(Student11)ois.readObject();
    s1=(Student11)ois.readObject();
    //System.out.println(s1==s3));
    System.out.println(s1);
      
    ois.close();
    }
    catch(IOException e)
    {
    e.printStackTrace();
    }
    catch(ClassNotFoundException e1)
    {
    e1.printStackTrace();
    }
    }
    }
      

  9.   

    重写equals方法。 默认equal是比较地址,显然你反序列化后是生成的一个新的对象。