Why does Java complain about "No Valid Constructor" even with a default constructor?
public class ExternalizableClass implements Externalizable
{
public static ExternalizableClass CACHE = new ExternalizableClass(-1);
int id;
public ExternalizableClass()
{
id = (int)(Math.random() * 1000);
}
public ExternalizableClass(int i)
{
id = i;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException
{
out.writeInt(id);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
//id = in.readInt();
id = in.readInt();
}
public Object writeReplace() throws ObjectStreamException
{
return new Write(0);
}
private class Write extends ExternalizableClass
{
int value;
public Write()
{
}
public Write(int i)
{
value = i;
}
public Object readResolve() throws ObjectStreamException
{
return ExternalizableClass.CACHE;
}
}
@Override
public String toString()
{
return "id: " + id;
}
public static void main(String[] argv)
{
try
{
ExternalizableClass ex = ExternalizableClass.CACHE;
System.out.println(ex);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("temp.txt"));
oos.writeObject(ex);
oos.close();
}
catch (Exception e)
{
e.printStackTrace();
}
ExternalizableClass ex;
try
{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("temp.txt"));
ex = (ExternalizableClass) ois.readObject();
System.out.println(ex);
ois.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Both classes ExternalizableClass
and ExternalizableClass.Write
have default (non-arg) constructors. But when deserializing it, Java complains:
java.io.InvalidClassException: SeralizableTest.ExternalizableClass$Write; no valid constructor
at java.io.ObjectStreamClass$ExceptionInfo.newInvalidClassException(ObjectStreamClass.java:150)
at java.io.ObjectStreamClass.checkDeserialize(ObjectStreamClass.java:768)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1772)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at SeralizableTest.ExternalizableClass.main(ExternalizableClass.java:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Can anyone please explain what the problem is?
source to share
I suspect the problem is that this is an inner class ... so it doesn't actually have a parameterless constructor. Instead, it has two constructors, one of which refers to an instance of the enclosing class, and one of them refers to an instance of the enclosing class and int
.
If you make it just a nested class by adding a modifier static
to the class declaration (for Write
) then I suspect it will be fine, because then it won't have an implicit additional parameter on every constructor.
source to share