import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.EOFException;

public class MyObjects {

	private static FileOutputStream fos = null;
	private static ObjectOutputStream oos = null;
	private static FileInputStream fis = null;
	private static ObjectInputStream ois = null;

	public static void main(String args[]) {
		// Creating Serialized Objects those we will write to file
		Student student = new Student();
		student.setStudent_id(100);
		student.setName("Faisal");
		student.setTemp("This field will not be serialized");

		Teacher teacher = new Teacher();
		teacher.setTeacher_id(99);
		teacher.setName("Tahir");
		teacher.setTemp("This field will not be serialized");

		Subject subject = new Subject();
		subject.setBook_id(999);
		subject.setBook_name("Thinking in Java");
		subject.setTemp("This field will not be serialized");

		// Specifing the path of file. Its relative to java source file
		File file = new File("Object.txt");
		try {
			// Writing Objects to file
			fos = new FileOutputStream(file);
			oos = new ObjectOutputStream(fos);
			oos.writeObject(student);
			oos.writeObject(teacher);
			oos.writeObject(subject);

			oos.flush();// Pushing the data into the file
			oos.close();// Closing the output stream
			// Opening input stream from the file
			fis = new FileInputStream(file);
			ois = new ObjectInputStream(fis);
			Object obj = null;
			// Reading & Iterating the object from file
			while ((obj = ois.readObject()) != null) {
				if (obj instanceof Student) {
					student = (Student) obj;
					System.out.println(student.toString());
				} else if (obj instanceof Teacher) {
					teacher = (Teacher) obj;
					System.out.println(teacher.toString());
				} else if (obj instanceof Subject) {
					subject = (Subject) obj;
					System.out.println(subject.toString());
				}
			}
			ois.close();// Closing the Input streams
			student = null;
			teacher = null;
			subject = null;
			file = null;
			obj = null;
		} catch (NotSerializableException e) {
			System.out.println(e.getMessage());
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (EOFException e) {
			System.out.println("Finished File Reading");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
			if (ois != null) {
				ois = null;
			}
			if (oos != null) {
				oos = null;
			}
		}
	}
}

class Student implements Serializable {
	private int student_id;
	private String name;
	private transient String temp;

	// Getters & Setters Methods
	public int getStudent_id() {
		return student_id;
	}

	public void setStudent_id(int student_id) {
		this.student_id = student_id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getTemp() {
		if (this.temp == null)
			return "Transient & Can't be serialzied";
		return temp;
	}

	public void setTemp(String temp) {
		this.temp = temp;
	}

	// toString() method for returning the current object's concatinated values
	public String toString() {
		return "[Student -> ID: " + getStudent_id() + " , Name: " + getName()
				+ " , " + getTemp() + " ]";
	}
}

class Teacher implements Serializable {
	private int teacher_id;
	private String name;
	private transient String temp;

	// Getters & Setters Methods
	public int getTeacher_id() {
		return teacher_id;
	}

	public void setTeacher_id(int teacher_id) {
		this.teacher_id = teacher_id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	// toString() method for returning the current object's concatinated values
	public String toString() {
		return "[Teacher -> ID: " + getTeacher_id() + " , Name: " + getName()
				+ " , " + getTemp() + " ]";
	}

	public String getTemp() {
		if (this.temp == null)
			return "Transient & Can't be serialzied";
		return temp;
	}

	public void setTemp(String temp) {
		this.temp = temp;
	}
}

class Subject implements Serializable {
	private int book_id;
	private String book_name;
	private transient String temp;

	// Getters & Setters Methods
	public int getBook_id() {
		return book_id;
	}

	public void setBook_id(int book_id) {
		this.book_id = book_id;
	}

	public String getBook_name() {
		return book_name;
	}

	public void setBook_name(String book_name) {
		this.book_name = book_name;
	}

	// toString() method for returning the current object's concatinated values
	public String toString() {
		return "[Book -> ID: " + getBook_id() + " , Name: " + getBook_name()
				+ " , " + getTemp() + " ]";
	}

	public String getTemp() {
		if (this.temp == null)
			return "Transient & Can't be serialzied";
		return temp;
	}

	public void setTemp(String temp) {
		this.temp = temp;
	}
}