没有任何东西的 Serializable 接口, 为什么实现这个接口就可以序列化

我们可以看一下 Serializable 接口

发现这个接口啥都没有 。

先写一个测试例子:


import java.io.Serializable;

public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    private String name;
    private String sex;
    private Integer age;

    public User() {
        this.name = "张三";
        this.sex = "男";
        this.age = 18;
    }
    
    public String toString() {
    	return "name:" + this.name + ",sex:" + this.sex + ",age:" +this.age;
    }
}
public static void main(String[] args) {
    User user = new User();
    try {
        // 序列化
        File file = new File("F:/file/user.txt");
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));
        out.writeObject(user);
        out.close();
        System.out.println("序列化完成");
            
        // 反序列化
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
        User u = (User) in.readObject();
        in.close();
        System.out.println("反序列化完成");
        System.out.println("--------------");
        System.out.println(u.toString());
    }catch (Exception e) {
        e.printStackTrace();
    }
}

 输出结果:

然后 User 不实现 Serializable  ,再运行一遍:

然后就报错了。

来看一下源码:

out.writeObject(user);

public final void writeObject(Object obj) throws IOException {
        if (enableOverride) {
            writeObjectOverride(obj);
            return;
        }
        try {
            writeObject0(obj, false);
        } catch (IOException ex) {
            if (depth == 0) {
                writeFatalException(ex);
            }
            throw ex;
        }
    }

writeObject0(obj, false);

private void writeObject0(Object obj, boolean unshared)
        throws IOException
    {
        boolean oldMode = bout.setBlockDataMode(false);
        depth++;
        try {
            // handle previously written and non-replaceable objects
            int h;
            if ((obj = subs.lookup(obj)) == null) {
                writeNull();
                return;
            } else if (!unshared && (h = handles.lookup(obj)) != -1) {
                writeHandle(h);
                return;
            } else if (obj instanceof Class) {
                writeClass((Class) obj, unshared);
                return;
            } else if (obj instanceof ObjectStreamClass) {
                writeClassDesc((ObjectStreamClass) obj, unshared);
                return;
            }

            // check for replacement object
            Object orig = obj;
            Class<?> cl = obj.getClass();
            ObjectStreamClass desc;
            for (;;) {
                // REMIND: skip this check for strings/arrays?
                Class<?> repCl;
                desc = ObjectStreamClass.lookup(cl, true);
                if (!desc.hasWriteReplaceMethod() ||
                    (obj = desc.invokeWriteReplace(obj)) == null ||
                    (repCl = obj.getClass()) == cl)
                {
                    break;
                }
                cl = repCl;
            }
            if (enableReplace) {
                Object rep = replaceObject(obj);
                if (rep != obj && rep != null) {
                    cl = rep.getClass();
                    desc = ObjectStreamClass.lookup(cl, true);
                }
                obj = rep;
            }

            // if object replaced, run through original checks a second time
            if (obj != orig) {
                subs.assign(orig, obj);
                if (obj == null) {
                    writeNull();
                    return;
                } else if (!unshared && (h = handles.lookup(obj)) != -1) {
                    writeHandle(h);
                    return;
                } else if (obj instanceof Class) {
                    writeClass((Class) obj, unshared);
                    return;
                } else if (obj instanceof ObjectStreamClass) {
                    writeClassDesc((ObjectStreamClass) obj, unshared);
                    return;
                }
            }

            // remaining cases
            if (obj instanceof String) {
                writeString((String) obj, unshared);
            } else if (cl.isArray()) {
                writeArray(obj, desc, unshared);
            } else if (obj instanceof Enum) {
                writeEnum((Enum<?>) obj, desc, unshared);
            } else if (obj instanceof Serializable) {
                writeOrdinaryObject(obj, desc, unshared);
            } else {
                if (extendedDebugInfo) {
                    throw new NotSerializableException(
                        cl.getName() + "\n" + debugInfoStack.toString());
                } else {
                    throw new NotSerializableException(cl.getName());
                }
            }
        } finally {
            depth--;
            bout.setBlockDataMode(oldMode);
        }
    }

重点代码:

看到没有,不属于以上类型就抛异常:throw new NotSerializableException(cl.getName());

再看看,上面判断的类型:

1、String 实现了 Serializable 接口

 2、是否为数组类

3、 枚举类型 实现了 Serializable 接口

总结:从中我们可以看出 虽然 Serializable  接口是一个空接口,但 实现 Serializable 接口的目的,主要是起一个标识作用。

猜你喜欢

转载自blog.csdn.net/m_crayon/article/details/106559096