正如问题所说,JVM为实现Marker接口的类提供了额外的处理。 例如,我使用Serializable测试它,如下所示:
import java.io。*;
public class SerialazationDemo {
public static void main(String[] args) {
//serialized object
/* Employee e = new Employee();
e.name = "Reyan Ali";
e.address = "Phokka Kuan, Ambehta Peer";
e.SSN = 11122333;
e.number = 101;
try {
FileOutputStream fileOut = new FileOutputStream("E:\\temp\\employee.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in /tmp/employee.ser");
} catch (IOException i) {
i.printStackTrace();
}*/
//deserialized object
Employee e = null;
try
{
FileInputStream fileIn = new FileInputStream("E:\\temp\\employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
in.close();
fileIn.close();
}catch(IOException i)
{
i.printStackTrace();
return;
}catch(ClassNotFoundException c)
{
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}
class Employee {
public String name;
public String address;
public transient int SSN;
public int number;
public void mailCheck() {
System.out.println("Mailing a check to " + name + " " + address);
}
}
我发现jvm给出异常为java.io.NotSerializableException但是FILES是在给定路径上创建的,反序列化的类似例外。那么为什么JVM要求它被序列化,它可以直接允许创建序列化。?
答案 0 :(得分:4)
问题说JVM为实现Marker接口的类提供了额外的处理
该问题的正确答案是没有。但它可能需要澄清,因为提问者可能会使用不完整的术语。
JRE 会在适当的地方特别对待它们。此操作位于Java类库中,而不是位于JVM中。例如:
Object.clone()
测试对象实现Cloneable.
ObjectOutputStream.writeObject()
测试正在编写的对象是否实现Serializable.
rmic
和部分RMI运行时测试远程对象实现远程接口,这意味着扩展Remote.
的接口这与JVM 本身无关。
我发现jvm给出异常为java.io.NotSerializableException
不,你没有。您发现ObjectOutputStream.writeObject()
引发了异常。它不是一回事。
但FILES是在给定路径上创建的
该文件由new FileOutputStream(...),
创建,该文件在您获得异常之前已经执行过。
那么为什么JVM要求它被序列化,它可以直接允许创建序列化。?
它没有。往上看。但是ObjectOutputStream.writeObject()
会这样做,而且这样做是因为让所有Serializable
都有许多缺点需要在建议之前加以考虑。例如,考虑一个您可能没有打算的可序列化密码字段的安全风险。
答案 1 :(得分:0)
您需要延长Serializable
(或Externalizable
)的原因是为了确保您仅序列化设计的类以进行序列化。你当然不想序列化那些没有为它设计的课程,因为那时它们的格式会非常脆弱;班级中最小的变化会破坏你的反序列化。
有人可能会认为同样的脆弱性适用于标记为Serializable
的类,但是在将类标记为Serializable
时,您应该考虑串行形式的稳定性(或者明确否定任何稳定性) ,就像番石榴那样。)
答案 2 :(得分:0)
如果对象不是Serializable
,则无法使用ObjectOutputStrem
保存其状态。
必须创建文件,因为这是使用FileInputStream
完成的,一旦关闭流,就会有一个新文件。但是如果尝试检查文件的内容,它应该是空的,因为不可序列化的状态将不会被保存。
答案 3 :(得分:0)
什么是标记界面?
当一个接口作为a提供时,它被称为标记接口 由java解释器处理以标记一个类,以便它可以提供 在运行时它的特殊行为,他们没有任何方法 声明
Marker接口只是将类标记为特定类型。
为什么需要标记界面?
标记接口用作标记以向java通知消息 编译器,以便它可以向类添加特殊行为 实现它。如果JVM看到Class是Serializable,它就完成了一些 特别行动
JVM对Serialiize Interface做了什么?
当一个类实现可序列化的接口时,它确保了JVM 这个班可能会提供一个特殊的 运行时的行为(序列化/反序列化)。
因此,当您尝试序列化对象时,JVM想要确认此类型的对象类是否已签订合同(实现Serialize接口)以在运行时显示此特殊行为(要序列化/反序列化)。如果有实现后,JVM可以确保它可以继续进行序列化。否则它会抛出异常,你正在尝试序列化一个不同意准备进行序列化或反序列化的条款和条件的对象。