1

I am trying to put an object into a file and then later on trying to read the same object using Externalizable interface and i am getting an Exception No valid constructor for Car class.

import java.io.*;
class Base
{
    int a;
}
class Car extends Base implements Externalizable
{
    static int b;
    String c="";

    Car(int d,int e,String f)
    {
        a=d;
        b=e;
        c=f;
    }
    Car()
{super();} 
        public void writeExternal(ObjectOutput oos)
        {
            try
            {
            oos.writeInt(a);
            oos.writeInt(b);
            oos.writeObject(c);
            }
            catch(Exception e){}
        }
        public void readExternal(ObjectInput ois)
        {
            try
            {
            a=ois.readInt();
            b=ois.readInt();
            c=(String)ois.readObject();
            }
            catch(Exception e){}
        }
    }
    class Main
    {
            public static void main(String args[])throws Exception
        {
            Car c1=new Car(1,2,"Manish");
            FileOutputStream fos=new FileOutputStream("man.txt");
            ObjectOutputStream oos=new ObjectOutputStream(fos);
            oos.writeObject(c1);
            FileInputStream fis=new FileInputStream("man.txt");
            ObjectInputStream ois=new ObjectInputStream(fis);
            Object o=ois.readObject();
            Car c2=(Car)o;
            System.out.println(c2.a+" "+c2.b+" "+c2.c);
        }
    }

can somebody explain what is the error?

2 Answers2

1

Java Serialization assumes you have a public default constructor.

Some libraries don't make this assumption, but the built in serialization does.

BTW You shouldn't ignore Exception(s) unless you are sure it is safe to do so. In your case, you don't need to catch them.

public void writeExternal(ObjectOutput oos) throws IOException {
    oos.writeInt(a);
    oos.writeInt(b);
    oos.writeObject(c);
}
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • But thats not the solution. I am getting exception can you explain why i'm getting it and how can i remove it. The exception is on this line Object o=ois.readObject(); – Manish Kumar Aug 29 '15 at 08:58
  • 1
    @ManishKumar `"Java Serialization assumes you have a public default constructor."` => you have to have a public constructor. Add `public` to your default constructor, and your class. This is failing on `readObject() ` because its is this method which detects it can't call your default constructor as it's not public. – Peter Lawrey Aug 29 '15 at 09:04
1

The main problem is a simple fact: Externalization interface works through the object itself to provide serialization.

This means that it's responsibility of the object itself to save and restore its state, and this implies that an object must exist to be able to deserialize a state inside itself (through readExternal).

What happens under the hood is that the serialization engine allocates an empty instance of the object to then call readExternal on it.

So basically what happens is something like:

Car emptyCar = Car.class.newInstance();
emptyCar.readExternal(state);

Since this happens from a package different from the one Car is residing and Car() has default visibility, the engine is unable to invoke the default constructor, hence the error.

You must provide a public default constructor.

Jack
  • 131,802
  • 30
  • 241
  • 343