37

以下のコードを記述したら、StudentDataのカスタムreadObject()およびwriteObject()オーバーライドメソッドを使用して、オブジェクトの変数を読み書きする必要があります。これを行うためにdefaultWriteObjectまたはdefaultReadObjectメソッドを使用せずに。

問題は、私が何を求められているのか完全に理解していないことです。シリアル化でのreadObject/writeObjectの使用法を読みましたが、頭を悩ませることができません。誰かが私を正しい方向に向けることができますか?

私のコード:

import java.io.*; //importing input-output files

class Student implements java.io.Serializable {

    String name; // declaration of variables
    String DOB;
    int id;

    Student(String naam, int idno, String dob) // Initialising variables to user
                                                // data
    {
        name = naam;
        id = idno;
        DOB = dob;
    }

    public String toString() {
        return name + "\t" + id + "\t" + DOB + "\t";
    }

}
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

class StudentData                     //main class
{
    public static void main(String args[]) throws IOException                  //exception handling
    {
        System.out.println("Enter the numbers of students:");
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(in.readLine());

        Student[]  students = new Student[n];

        //Student[]  S=new Student[n];                      // array of objects declared and defined
        for (int i = 0; i < students.length; i++) {
            System.out.println("Enter the Details of Student no: " + (i + 1));             //reading data form the user
            System.out.println("Name: ");
            String naam = in.readLine();
            System.out.println("ID no: ");
            int idno = Integer.parseInt(in.readLine());
            System.out.println("DOB: ");               
            String dob = (in.readLine());

            students[i] = new Student(naam, idno, dob);                          

            File studentFile = new File("StudentData.txt");
            try {
                FileOutputStream fileOutput = new FileOutputStream(studentFile);
                ObjectOutputStream objectOutput = new ObjectOutputStream(fileOutput);
                objectOutput.writeObject(students);

                students = null;

                FileInputStream fileInput = new FileInputStream(studentFile);
                ObjectInputStream objectInputStream = new ObjectInputStream(fileInput);

                students = (Student[]) objectInputStream.readObject();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

            for (Student student : students) {
                System.out.println(student);
            }
        }
    }
}
4

2 に答える 2

69

あなたはこのようにそれをしなければなりません:

import java.io.IOException;

class Student implements java.io.Serializable {

    String name;
    String DOB;
    int id;

    Student(String naam, int idno, String dob) {
        name = naam;
        id = idno;
        DOB = dob;
    }

    private void writeObject(java.io.ObjectOutputStream stream)
            throws IOException {
        stream.writeObject(name);
        stream.writeInt(id);
        stream.writeObject(DOB);
    }

    private void readObject(java.io.ObjectInputStream stream)
            throws IOException, ClassNotFoundException {
        name = (String) stream.readObject();
        id = stream.readInt();
        DOB = (String) stream.readObject();
    }

    public String toString() {
        return name + "\t" + id + "\t" + DOB + "\t";
    }

}

readObjectは、Studentのインスタンスを作成した直後に呼び出されます(通常のコンストラクターをバイパスします)。

于 2012-10-18T20:54:05.890 に答える
2

私はこの質問が古いことを知っています、後世のためにこれを考慮してください

通常、すべての「通常の」フィールドを自動的に逆シリアル化できるようにすることで、JVMにハードワークを実行させることができます。

private void readObject(ObjectInputStream serialized) throws ClassNotFoundException, IOException 
{
    serialized.defaultReadObject();
    // After this, you can handle transient fields or 
    // special initialization that happens in the constructor
}

のドキュメントdefaultReadObject()はこれについて非常に明確です:

このストリームから、現在のクラスの非静的フィールドと非一時フィールドを読み取ります。これは、逆シリアル化されるクラスのreadObjectメソッドからのみ呼び出すことができます。それ以外の場合は、NotActiveExceptionがスローされます。

于 2019-10-30T09:53:28.183 に答える