>Java >java지도 시간 >Java 직렬화 및 역직렬화를 적용하는 방법

Java 직렬화 및 역직렬화를 적용하는 방법

PHPz
PHPz앞으로
2023-04-29 17:37:141387검색

    Java 직렬화 및 역직렬화

    Java 직렬화는 Java Object 객체를 이진 바이트 시퀀스 byte[]Java Object变为一个二进制字节序列byte[]

    Java反序列化就是把一个二进制字节序列byte[] 变为Java对象Java Object

    序列化API

    ObjectOutputStream

    字节输出流对象,将对象的输出流写到文件中(结合FileOutputStream使用)

    实例:

    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("1.txt"));
    或
    FileOutputStream fout = new FileOutputStream("1.txt");
    ObjectOutputStream out = new ObjectOutputStream(fout);

    此外ObjectOutputStream还提供了writeObject()方法来序列化一个对象,并将它发送到输出流。

    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("1.txt"));
    out.writeObject(new Test("Sentiment",10));        //对Test类中的构造方法进行传参

    ObjectInputStream

    字节输入流对象,将文件中的二进制字节序列进行反序列化操作(结合FileInputStream)

    实例:

    ObjectInputStream in = new ObjectInputStream(new FileInputStream("1.txt"));
    或
    FileInputStream fin = new FileInputStream("1.txt");
    ObjectInputStream oin = new ObjectInputStream(fin);

    此外ObjectInputStream还提供readObject()方法从流中取出下一个对象,并将对象反序列化。它的返回值为Object,因此,需要将它转换成合适的数据类型。

    ObjectInputStream In = new ObjectInputStream(new FileInputStream("1.txt"));
    Test o = (Test)In.readObject();
    System.out.println(o);        //读取后输出实例理解

    实例理解

    Test.java(类想要进行序列化操作,必须实现Serializable接口继承)

    package Sentiment.unserialize.demo01;
    
    import java.io.Serializable;
    
    public class Test implements Serializable {
        private String name;
        private int age;
    
        public Test() {
        }
    
        public Test(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Test{" + "name='" + name + '\'' + ", age=" + age + '}';
        }
    
    }

    Serializable.java

    package Sentiment.unserialize.demo01;
    
    import java.io.*;
    
    public class Serializable {
        public static void main(String[] args) throws IOException {
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("1.txt"));
            out.writeObject(new Test("Sentiment",10));
            out.close();
        }
    }

     UnSerializable.java

    package Sentiment.unserialize.demo01;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    
    public class UnSerializable {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            ObjectInputStream In = new ObjectInputStream(new FileInputStream("1.txt"));
            Test o = (Test)In.readObject();
            System.out.println(o);
        }
    }

    运行Serializable.java后便得到二进制字节码文件内容

    Java 직렬화 및 역직렬화를 적용하는 방법

    此时在运行UnSerializable.java便得到了二进制字节码反序列化后的内容

    Java 직렬화 및 역직렬화를 적용하는 방법

    serialVersionUID

    • 每个可序列化的类在序列化时都会关联一个版本号 , 这个版本号就是 serialVersionUID 属性

    • serialVersionUID 属性必须通过 static final long 修饰符来修饰 。

    • 如果可序列化的类未声明 serialVersionUID 属性 , 则 Java 序列化时会根据类的各种信息来计算默认的 serialVersionUID 值 . 但是 Oracle 官方文档强烈建议所有可序列化的类都显示声明 serialVersionUID 值 .

    实例理解

    在Test.java中定义serialVersionUID 其值为1

    package Sentiment.unserialize.demo01;
    
    import java.io.Serializable;
    
    public class Test implements Serializable {
        public static final long serialVersionUID = 1L;   //定义serialVersionUID 
    
        private  String name;
        private  int age;
    
        public Test() {
        }
    
        public Test(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Test{" + "name='" + name + '\'' + ", age=" + age + '}';
        }
    
    }

    此时运行Serializable.java进行序列化操作

    运行完毕后将serialVersionUID的值定义为2—>public static final long serialVersionUID = 2L;,在运行UnSerializable.java会报错

    Java 직렬화 및 역직렬화를 적용하는 방법

    Transient (瞬态变量)

    Transient( 瞬态变量 )是一个 Java 关键词 , 它用于标记类的成员变量在持久化到字节流时不要被序列化 ; 在通过网络套接字流传输字节流时 , transient 关键词标记的成员变量不会被序列化 。此为被static修饰的静态变量也不参与序列化操作。

    实例理解

    将Test.java中的nameage变量前分别加上transientstatic

    Java 역직렬화는 이진수로 바꾸는 것입니다. 바이트 시퀀스 byte[]를 Java 객체 Java Object

    Serialization API

    Java 직렬화 및 역직렬화를 적용하는 방법ObjectOutputStream

    byte 출력 스트림 객체로 변환하고 객체를 변환합니다. 출력 스트림은 파일(FileOutputStream과 함께 사용됨)

    예:

    package Sentiment.unserialize.demo01;
    
    import java.io.Serializable;
    
    public class Test implements Serializable {
        public static final long serialVersionUID = 1L;  //定义serialVersionUID 
        private transient String name;                     //加上transient
        private static int age;                             //加上static
    
        public Test() {
        }
    
        public Test(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Test{" + "name='" + name + '\'' + ", age=" + age + '}';
        }
    
    }

    또한 ObjectOutputStream은 객체를 직렬화하고 이를 출력 스트림으로 보내는 writeObject() 메서드도 제공합니다.

    private void readObject(java.io.ObjectInputStream a) throws IOException, ClassNotFoundException{
        a.defaultReadObject();
        Runtime.getRuntime().exec("calc.exe");
    }

    ObjectInputStream

    바이트 입력 스트림 개체는 파일의 이진 바이트 시퀀스를 역직렬화합니다(FileInputStream과 결합)Java 직렬화 및 역직렬화를 적용하는 방법

    예: 🎜rrreee🎜또한 ObjectInputStream은 readObject() 메서드를 제공합니다. 스트림의 다음 개체를 제거하고 개체를 역직렬화합니다. 반환 값은 Object이므로 적절한 데이터 유형으로 변환해야 합니다. 🎜rrreee🎜이해의 예🎜🎜Test.java(클래스가 직렬화 작업을 수행하려면 직렬화 가능 인터페이스 상속을 구현해야 함)🎜rrreee🎜Serialized.java🎜rrreee🎜 UnSerialized.java🎜rrreee🎜Serialized.java를 실행한 후 바이너리 바이트 코드 파일 내용 가져오기🎜🎜Java 직렬화 및 역직렬화 적용 방법🎜 🎜이때 UnSerialized.java를 실행하면 바이너리 바이트코드의 역직렬화된 내용을 얻을 수 있습니다🎜🎜Java 직렬화 및 역직렬화 적용 방법🎜🎜serialVersionUID🎜
    • 🎜직렬화 가능한 각 클래스는 직렬화 중에 연결됩니다. 버전 번호, 이 버전 번호는 다음과 같습니다. serialVersionUID 속성🎜
    • 🎜serialVersionUID 속성은 static final long 수정자로 수정되어야 합니다. 🎜
    • 🎜직렬화 가능 클래스가 serialVersionUID 속성을 선언하지 않으면 Java는 직렬화 중에 클래스에 대한 다양한 정보를 기반으로 기본 serialVersionUID 값을 계산합니다. 그러나 Oracle 공식 문서에서는 모든 직렬화 가능 클래스가 모두 선언할 것을 강력히 권장합니다. serialVersionUID 값 🎜
    • 🎜🎜예시 이해🎜🎜Test.java에서 serialVersionUID를 정의하고 그 값은 1🎜rrreee🎜직렬화 작업을 위해 현재 Serialized.java를 실행합니다🎜 🎜실행 후 , serialVersionUID 값을 2—>public static final long serialVersionUID = 2L;로 정의하면 UnSerialized.java🎜🎜Java 직렬화 및 역직렬화 적용 방법🎜🎜Transient(일시적 변수)🎜🎜Transient(일시적 변수)는 Java 키워드입니다. 바이트 스트림에 지속될 때 직렬화되지 않는 클래스의 멤버 변수를 표시하는 데 사용됩니다. 네트워크 소켓 스트림을 통해 바이트 스트림을 전송할 때 임시 키워드로 표시된 멤버 변수는 직렬화되지 않습니다. 이는 static으로 수정되는 정적 변수이며 직렬화 작업에 참여하지 않습니다. 🎜🎜이해 예🎜🎜Test.java의 nameage 변수 앞에 각각 transientstatic를 추가하세요. >🎜rrreee🎜이때 Serialized.java, UnSerialized.java가 실행되고 출력결과는 Sentiment—>null, 10—>0🎜🎜🎜🎜🎜readObject() 메소드 재작성🎜🎜사용자에게 공식적으로 허용됩니다. 클래스의 readObject() 메서드를 재정의하면 재정의된 메서드는 역직렬화 중에 현재 클래스 객체를 재구성합니다. 사용자는 재정의된 readObject() 메서드에서 defaultReadObject() 메서드만 구현하면 됩니다. reverse 직렬화 프로세스는 정상적으로 실행됩니다. 🎜🎜예시 이해🎜🎜 defaultReadObject() 메서드 호출을 구현하고 Test 클래스에서 메서드를 다시 작성합니다. 직렬화 및 역직렬화 작업 후에 명령을 실행할 수 있습니다.🎜rrreee🎜🎜🎜

    위 내용은 Java 직렬화 및 역직렬화를 적용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제