1

In an assignment that I have to do, I have to write a Student object which comprises of a name, social security number, number of courses passed, and the grades for each of those courses. I made a gpa method to calculate the gpa based on and also made overrides of the writeObject and readObject methods with my own methods. Here is the complete source code- http://pastebin.com/dNMrc1zK

This is what it looks like without the getter and setter methods for each instance:

import java.io.*;

public class Student implements Serializable{
        private String name;
        private int ssNum;
        private int coursesCompleted;
        private char[] grades;

        public Student(String n, int num, int c){
                n = name;
                num = ssNum;
                c = coursesCompleted;
        }

        public String getName() {
                return name;
        }

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

        public int getSsNum() {
                return ssNum;
        }

        public void setSsNum(int ssNum) {
                this.ssNum = ssNum;
        }

        public int getCoursesCompleted() {
                return coursesCompleted;
        }

        public void setCoursesCompleted(int coursesCompleted) {
                this.coursesCompleted = coursesCompleted;
        }

        public char[] getGrades() {
                return grades;
        }

        public void setGrades(char[] grades) {
                this.grades = grades;
        }
        public double gpa(char[] grades){

                double gpa = 0;

                for (int i = 0; i < grades.length; i++){
                        if (grades[i] == 'A'){
                                gpa += 4.0;
                        }
                        else if (grades[i] == 'B'){
                                gpa += 3.0;
                        }
                        else if (grades[i] == 'C'){
                                gpa += 2.0;
                        }
                        else if (grades[i] == 'D'){
                                gpa += 1.0;
                        }
                        else if (grades[i] == 'F'){
                                gpa += 0.0;
                        }
                }

                return gpa / grades.length;

        }

        public void ReadObject(ObjectInputStream in) throws IOException{
                String readTitle = "";

                for(int i = 0; i < name.length(); i++){
                        readTitle += in.readChar();
                }
                ssNum = in.readInt();
                coursesCompleted = in.readInt();

                for (int i = 0; i < grades.length; i++){
                        grades[i] = in.readChar();
                }
        }
        public void WriteObjectOverride(ObjectOutputStream out) throws IOException, ClassNotFoundException{

                out.writeChars(name);
                out.writeInt(ssNum);
                out.writeInt(coursesCompleted);

                for (int i = 0; i < grades.length; i++){
                        out.writeChar(grades[i]);
                }
                gpa(grades);
        }
        public String toString(){
                   String student = name + " " +  "\nGPA: " + gpa(grades);
                   return student;
                }
}


public void ReadObject(ObjectInputStream in) throws IOException{
    String readTitle = "";

    for(int i = 0; i < name.length(); i++){
        readTitle += in.readChar();
    }
    ssNum = in.readInt();
    coursesCompleted = in.readInt();

    for (int i = 0; i < grades.length; i++){
        grades[i] = in.readChar();
    }
}
public void WriteObjectOverride(ObjectOutputStream out) throws IOException, ClassNotFoundException{

    out.writeChars(name);
    out.writeInt(ssNum);
    out.writeInt(coursesCompleted);

    for (int i = 0; i < grades.length; i++){
        out.writeChar(grades[i]);
    }
    gpa(grades);
}
public String toString(){
       String student = name + " " +  "\nGPA: " + gpa(grades);
       return student;
    }
}

I then have to write a separate program which writes the object to a file. I made a constructor so that it gives the name, ss number, and courses completed a value and then I used a setter method to set the grades array value. I then used the values I had to use writeObject and wrote the object like this:

            Student john = new Student("John Doe", 123456, 4);
    Student jane = new Student("Jane Doe", 987654, 3);
    Student jack = new Student("Jack Doe", 528491, 4);

    ObjectOutputStream out;

    john.setGrades(student1);
    jane.setGrades(student2);
    jack.setGrades(student3);

    try {
        out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("students.bin")));

        out.writeObject(john);
        out.writeObject(jane);
        out.writeObject(jack);

        out.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

The problem I'm having is that when I use another program to execute the readObject() method, like this:

    public static void main (String[] args)throws FileNotFoundException, IOException, ClassNotFoundException{
    Student student = null;
    try(ObjectInputStream in = new ObjectInputStream(new FileInputStream("students.bin"));){

        student = (Student)in.readObject();
        System.out.println(student);
    }

It prints a line which not something I expected:

UnitSeven.Student@70dea4e

Does anyone know how to fix this problem so that it shows the actual object? Any help would be appreciated.

Kumar Abhinav
  • 6,565
  • 2
  • 24
  • 35
Foxwood211
  • 25
  • 3
  • possible duplicate of [How do I print my Java object without getting "SomeType@2f92e0f4"?](http://stackoverflow.com/questions/29140402/how-do-i-print-my-java-object-without-getting-sometype2f92e0f4) – resueman Aug 15 '15 at 13:50
  • 1
    As a side note: your gpa method could be refactored to add the numbers to gpa as you go and divide by grades.length, thereby eliminating the need for a second array. – D. Ben Knoble Aug 15 '15 at 13:53
  • It also looks like your read and write object overrides are going to need some work. – Jim Rhodes Aug 15 '15 at 14:44

3 Answers3

1

In addition to your overrides having the wrong names as Kumar Abhinav pointed out, you have several issues.

Your readObject is using names.length and grades.length but neither has been initialized. You will probably need to modifiy writeObject to output the length of the name and then read that length before reading the name or just write and read the name as a String object. You can use coursesCompleted to determine how many grades to read. You also don't do anything with the readTitle variable.

Your writeObject method calls the gpa method but does not use the return value.

Jim Rhodes
  • 5,021
  • 4
  • 25
  • 38
  • There is no need to call gpa from writeObject and you should put back the loop that writes the grade letters – Jim Rhodes Aug 15 '15 at 18:52
0

The code you are using is completely wrong. You are using ReadObject with capital R, use readObject and you have not implemented writeObject. These two private methods must have an exact signature as defined as they are call-back methods. The way your code currently works, it's calling the default way of serializing/deserializing Objects.

  1. The method signature of your ReadObject method is not matching the one required.

    public void ReadObject(ObjectInputStream in) throws IOException { ... }
    

    should be

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { ... }
    
  2. The same applies for your attempt at the writeObject method.

    public void WriteObjectOverride(ObjectOutputStream out) throws IOException, ClassNotFoundException {
    

    should be

    private void writeObject(ObjectOutputStream out) throws IOException { ... }
    

Also note: All String Objects and primitives are themselves serializble, so you may as well change the logic of writing data to your stream

To prevent your method from printing out a hashcode next to the class name, implement your own toString() method in the Student class. Please consult this question for more details:

To print something different when you call System.out.println(myObject), you must override the toString() method in your own class. Here's a simple example:

public class Person {

    private String name;

    // constructors and other methods omitted

    @Override   public String toString() {
     return name;
    }
}

Now if we print a Person, we see their name rather than com.foo.Person@12345678.

Community
  • 1
  • 1
Kumar Abhinav
  • 6,565
  • 2
  • 24
  • 35
  • Thanks, that helped. But I'm encountering another problem. It seems that the object keeps returning null. I can't figure out why it's doing that. Could you help me with that? – Foxwood211 Aug 15 '15 at 14:14
  • @Foxwood211 Could you post the results ,object which is returning null because UnitSeven.Student@70dea4e would not have been returned in the first place – Kumar Abhinav Aug 15 '15 at 14:18
  • These are the results: `null GPA: 3.25` The GPA method and the array seems to have a value but for some reason the object itself is null. – Foxwood211 Aug 15 '15 at 14:23
  • Can you please post the entire code for Class you are serializing – Kumar Abhinav Aug 15 '15 at 14:28
  • Code was too long to post in the comments, but here's a link to the class. http://pastebin.com/dNMrc1zK – Foxwood211 Aug 15 '15 at 14:31
  • The code yo uare using is compltely wrong.You are using ReadObject with capital R ,use readObject and you have not implemented writeObject... These two private methods must have exact signature as defined as they are call back methods.Your program is calling default readObject and default writeObject – Kumar Abhinav Aug 15 '15 at 14:46
  • @Foxwood211 Check my answer now – Kumar Abhinav Aug 15 '15 at 14:55
  • 1
    @KumarAbhinav did you really mean that ReadObject should be writeObject and vice versa? – Jim Rhodes Aug 15 '15 at 15:01
  • @JimRhodes Typo error.Let me correct it.Thanks for pointing it out – Kumar Abhinav Aug 15 '15 at 15:03
  • @KumarAbhinav Is it ok if my writeObject looks like this? http://pastebin.com/hfKaruZm – Foxwood211 Aug 15 '15 at 16:15
0

When you execute:

System.out.println(student);

what actually happens is that student object's toString() method is called. Since you did not override toString() method for student's class what you run is Object class's, which is the parent of all classes in java, toString() method. This Object class's toString() returns the student's class name and a hashcode. Hashcode is the mumbo jumbo number that you are seeing. This hashcode is the standard identifier in java.

What you should do is override Object class's toString() method in your Student class in order to print your desired output.

Shababb Karim
  • 3,614
  • 1
  • 22
  • 35
  • He defines a `toString()` method in `Student`: `public String toString() { return name + " \nGPA:" + gpa(grades); }` (I simplified it a bit) – randers Aug 15 '15 at 15:30