import java.io.*;public class User implements Serializable {
private String name;
private transient String password;
public User(String name,String password){
this.name =name;
this.password =password;
}
public String toString(){
return name+" "+password;
}
private byte[] change(byte[] buff){
//加密数组
}
private void writeObject(ObjectOutputStream stream)throws IOException{
stream.defaultWriteObject();
stream.writeObject(change(password.getBytes()));
}
private void readObject(ObjectInputStream stream)throws IOException,ClassNotFoundException{
stream.defaultReadObject();
byte[] buff=(byte[])stream.readObject();
password=new String(change(buff));
}
public static void main(String[] args)throws Exception {
User user=new User("Tom","12345");
System.out.println("Before Serialization:"+user);
ByteArrayOutputStream buf=new ByteArrayOutputStream();
ObjectOutputStream o=new ObjectOutputStream(buf);
o.writeObject(user);
ObjectInputStream in=new ObjectInputStream(
new ByteArrayInputStream(buf.toByteArray()));
user=(User)in.readObject();
System.out.println("After Serialization:"+user);
}
}上述代码中o.writeObject(user),为什么o能调用User类中定义的方法,而且参数也不对应
private String name;
private transient String password;
public User(String name,String password){
this.name =name;
this.password =password;
}
public String toString(){
return name+" "+password;
}
private byte[] change(byte[] buff){
//加密数组
}
private void writeObject(ObjectOutputStream stream)throws IOException{
stream.defaultWriteObject();
stream.writeObject(change(password.getBytes()));
}
private void readObject(ObjectInputStream stream)throws IOException,ClassNotFoundException{
stream.defaultReadObject();
byte[] buff=(byte[])stream.readObject();
password=new String(change(buff));
}
public static void main(String[] args)throws Exception {
User user=new User("Tom","12345");
System.out.println("Before Serialization:"+user);
ByteArrayOutputStream buf=new ByteArrayOutputStream();
ObjectOutputStream o=new ObjectOutputStream(buf);
o.writeObject(user);
ObjectInputStream in=new ObjectInputStream(
new ByteArrayInputStream(buf.toByteArray()));
user=(User)in.readObject();
System.out.println("After Serialization:"+user);
}
}上述代码中o.writeObject(user),为什么o能调用User类中定义的方法,而且参数也不对应
public final void writeObject(Object obj) throws IOException
将指定的对象写入 ObjectOutputStream。对象的类、类的签名,以及类及其所有超类型的非瞬态和非静态字段的值都将被写入。可以使用 writeObject 和 readObject 方法重写类的默认序列化。由此对象引用的对象是以可变迁的方式写入的,这样,可以通过 ObjectInputStream 重新构造这些对象的完全等价的图形。
当 OutputStream 中出现问题或者遇到不应序列化的类时,将抛出异常。所有异常对于 OutputStream 而言都是致命的,使其处于不确定状态;并由调用者来忽略或恢复流的状态。 指定者:
接口 ObjectOutput 中的 writeObject
参数:
obj - 要写入的对象
抛出:
InvalidClassException - 序列化操作使用的类出了问题。
NotSerializableException - 某个要序列化的对象不能实现 java.io.Serializable 接口。
IOException - 由底层 OutputStream 抛出的任何异常。那个可能是重写类的默认序列化吧.
我查了api帮助文档,serializable序列化接口没有方法或字段,仅用于标识可序列化的语义。
而且User类没有继承ObjectOutputStream类,
代码中writeObject方法应该就是User类定义的方法
现在问题是在User类中,ObjectOutputStream类对象可以调用User类中的方法吗??
User类中writeObject()方法:
private void writeObject(ObjectOutputStream stream)throws IOException{
stream.defaultWriteObject();
stream.writeObject(change(password.getBytes()));
}
与main()函数中调用的方法完全是两个不同的方法:
o.writeObject(user); // The param is Object
User类中writeObject()方法传递的参数是ObjectOutputStream,而main()函数中的writeObject()传递的是OBJECT对象,是两个完全不同的参数。
所以main()函数中调用的是ObjectOutputStream中的writeObject()方法。
这个程序就是先把USER存进去,用的是ObjectOutpubStream的writeObject方法
然后在把它读出来,用的是ObjectInputStream的readObject方法,
这个User类里定义了两个private方法writeObjec和readObject都没有用上
如果正如两位所说,是调用ObjectOutputStream的writeObject方法的话,那么下面这段代码就可以注释起来了private byte[] change(byte[] buff){
//加密数组
}
private void writeObject(ObjectOutputStream stream)throws IOException{
stream.defaultWriteObject();
stream.writeObject(change(password.getBytes()));
}
private void readObject(ObjectInputStream stream)throws IOException,ClassNotFoundException{
stream.defaultReadObject();
byte[] buff=(byte[])stream.readObject();
password=new String(change(buff));
} 那么这样的话,我调试了下,它就不能实现本程序的功能了,最后打印
Before Serialization:Tom 12345
After Serialization:Tom null而不去注释的话,它打印的是
Before Serialization:Tom 12345
After Serialization:Tom 12345显然它是调用了代码中定义的这两个方法因为我看的那本书上在这之前的一个程序就是两位所说的那样调用ObjectOutputStream自己的writeObject和readObject方法
由于有那个关键字transient,可以成功保证密码的安全,返回null
这段代码正是通过重定义了这两个方法又可以将密码成功返回
在执行到o.writeObject(user);这句时,调用了User中的writeObject()方法
在user=(User)in.readObject(); 这句时,调用了User中readObject()方法
通过看API,我觉得唯一能解释的就是这句话:writeObject()可以使用 writeObject 和 readObject 方法重写类的默认序列化。所以对象引用的对象是以可变迁的方式写入的。
程序中执行到o.writeObject(user)这句时,由于在User中对writeObject传入的参数做了重写(原本是Obejct,重写后为ObjectOutputStream),因此就执行了User.writeObject()方法。
下面是我的猜测:
在执行o.writeObejct(user)时,先执行了ObjectOutputStream.writeObeject()方法,然后再执行了User.writeObject()方法,因为User.writeObject()方法传入的是ObjectOutputStream引用对象,也可以说是o本身。
不知道这样解释是否正确