>  기사  >  类库下载  >  Java 직렬화 및 역직렬화

Java 직렬화 및 역직렬화

高洛峰
高洛峰원래의
2016-10-29 10:56:571615검색

1. 연재란? 직렬화하는 이유는 무엇입니까?

 Java 직렬화는 객체를 바이트 시퀀스로 변환하는 프로세스인 반면, 역직렬화는 바이트 시퀀스만 대상 객체로 변환하는 프로세스입니다.

브라우저에 접속할 때 우리가 보는 텍스트, 그림, 오디오, 비디오 등이 바이너리 시퀀스를 통해 전송된다는 것을 우리 모두 알고 있는데, Java 객체를 전송해야 한다면 객체를 먼저 직렬화해야 할까요? 대답은 '예'입니다. 먼저 Java 개체를 직렬화한 다음 네트워크와 IO를 통해 전송해야 합니다. 대상에 도달하면 역직렬화하여 원하는 개체를 얻은 다음 마지막으로 통신을 완료합니다.

2. 직렬화 구현 방법

2.1. JDK의 ObjectOutputStream 및 ObjectInputStream 사용

ObjectOutputStream 클래스에서 writeObject(Object 객체) 메서드 사용 , 개체는 바이너리 형식으로 작성됩니다.

ObjectInputStream 클래스: 입력 스트림에서 바이너리 스트림을 읽고 readObject() 메서드를 사용하여 객체로 변환합니다.

2.2. 대상 객체는 먼저 Serialable 인터페이스를 구현해야 합니다.

Student 클래스를 만듭니다.

public class Student implements Serializable {
    private static final long serialVersionUID = 3404072173323892464L;
    private String name;
    private transient String id;
    private String age;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", id='" + id + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public Student(String name, String id) {
        System.out.println("args Constructor");
        this.name = name;
        this.id = id;
    }

    public Student() {
        System.out.println("none-arg Constructor");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

}

코드의 Student 클래스는 직렬화 가능 인터페이스를 구현하고 버전 번호를 생성합니다.

private static final long serialVersionUID = 3404072173323892464L;

우선:

1. 직렬화 가능 인터페이스의 기능은 다음과 같습니다. 우리 클래스가 직렬화되어야 하는지 여부를 식별하고 직렬화 가능 인터페이스는 어떤 메서드도 제공하지 않습니다.

2. serialVersionUid 직렬화 버전 번호는 우리가 작성하는 클래스의 버전을 구별하고 역직렬화 중에 클래스의 버전이 일치하는지 확인하는 데 사용됩니다. 일치하지 않는 경우 버전 불일치 예외가 발생합니다.

3. Transient 키워드는 직렬화하고 싶지 않은 변수를 무시하는 데 주로 사용됩니다.

2.3 객체 직렬화 또는 역직렬화

  2.3.1 첫 번째 쓰기 방법:

public static  void main(String[] args){
        File file = new File("D:/test.txt");
        Student student = new Student("孙悟空","12");
        try {
            ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
            outputStream.writeObject(student);
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file));
            Student s = (Student) objectInputStream.readObject();
            System.out.println(s.toString());
            System.out.println(s.equals(student));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

   Student 객체를 생성한 후, ObjectOutputStream 클래스의 writeObject() 메소드를 통해 해당 객체를 파일에 출력합니다.

그런 다음 ObjectinputStream 클래스의 readObject() 메서드를 통해 객체를 역직렬화하고 가져옵니다.

   2.3.2 두 번째 쓰기 방법:

Student 클래스에 writeObject() 및 readObject() 메서드 구현:

private void writeObject(ObjectOutputStream objectOutputStream) throws IOException {
        objectOutputStream.defaultWriteObject();
        objectOutputStream.writeUTF(id);

    }

    private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
        objectInputStream.defaultReadObject();
        id = objectInputStream.readUTF();
    }

이러한 방식으로 직렬화함으로써 직렬화하려는 변수를 사용자 정의하고 입력 스트림과 출력 스트림을 라인 인스턴스에 전달한 다음 직렬화 및 역직렬화할 수 있습니다.

 

   2.3.3 세 번째 작성 방법:

학생이 외부화 가능 인터페이스를 구현하지만 직렬화 가능 인터페이스는 구현하지 않습니다.

외부화 가능 인터페이스는 하위 클래스입니다. Serialize의 는 Serialize 인터페이스와 동일한 기능을 가지고 있습니다:

public class Student implements Externalizable {
    private static final long serialVersionUID = 3404072173323892464L;
    private String name;
    private transient String id;
    private String age;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", id='" + id + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public Student(String name, String id) {
        System.out.println("args Constructor");
        this.name = name;
        this.id = id;
    }

    public Student() {
        System.out.println("none-arg Constructor");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }


    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(name);
        out.writeObject(id);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        name = (String) in.readObject();
        id = (String) in .readObject();
    }

}

이전의 두 번째 작성 방법과 비교하면 구현 원리가 매우 유사하지만 외부화 가능 인터페이스의 구현은 그렇지 않다는 것을 알 수 있습니다. 지원됨 첫 번째 직렬화 메서드는 인터페이스에서 writeExternal() 및 readExternal() 메서드를 구현해야만 객체를 직렬화할 수 있습니다.

3. 직렬화에 대한 인터뷰 질문 :

1. 직렬화란 무엇이며 어떻게 구현하는가

직렬화 Java에서 객체의 직렬화는 객체를 바이너리 시퀀스로 변환하는 것이고, deserialization은 바이너리 시퀀스를 객체로 변환하는 것입니다

 Java에서 직렬화를 구현하는 방법은 여러 가지가 있습니다

1. 먼저 Two IO가 필요합니다. ObjectInputStream 및 ObjectOutputStream 클래스가 사용됩니다. 2. 직렬화 가능 인터페이스 구현:

두 가지 특정 직렬화 방법이 있습니다.

2.1 ObjectOutputStream 및 ObjectInputStream 클래스를 통해 직접 writeObject() 및 readObject()

    2.2 직렬화된 개체에 writeObject() 및 readObject() 메서드를 구현하고 ObjectOutputStream 및 ObjectInputStream 개체를 전달하여 직렬화를 완료합니다.

  3 , 외부화 가능 인터페이스를 구현합니다.

     객체 직렬화는 인터페이스의 writeExternal() 및 readExternal() 메소드를 구현해야만 달성할 수 있습니다.


2. 임시 키워드? 과도 수정자로 수정된 변수를 직렬화하는 방법은 무엇입니까?
일시적 기능은 직렬화하고 싶지 않은 변수를 보호하는 것입니다. 객체는 직렬화 및 역직렬화 프로세스 중에 변수를 무시합니다.
위의 직렬화 메서드에서 writeObject 및 readObject 메서드를 구현하고 해당 메서드에서 출력 스트림 또는 입력 스트림의 writeUTF() 및 readUTF() 메서드를 호출할 수 있습니다.
또는 외부화 가능 인터페이스를 구현하고 writeExternal() 및 readExternal() 메소드를 구현한 다음 시퀀스 객체를 사용자 정의합니다.

3. 직렬화 및 역직렬화 후 객체의 일관성을 어떻게 보장할 수 있나요? (이의가 있는 경우 정정해 주시기 바랍니다.)
이 문제에 대해 몇 가지 정보를 살펴본 후 직렬화 및 역직렬화 이후의 개체가 일관적이라는 보장이 없다는 것을 알게 되었습니다. 왜냐하면 역직렬화 프로세스 중에 먼저 개체를 생성하고, > 문제가 발생합니다. 새 개체를 만든 후 개체 참조와 원본 개체가 동일한 대상을 가리키지 않습니다.
따라서 데이터와 버전의 일관성만 보장할 수 있지만 개체의 일관성은 보장할 수 없습니다.


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.