Hi all,
I have come to a situation where I want to use the new binary format to save some inner class for some controllers, I always get InstantiationException when loading those classes, dispite that the class is public, and their is a none argument constructor.
Is their any way around that, or am I doing something wrong from the begning ?
thanks for the help.
Outrunner said:
I always get InstantiationException when loading those classes, dispite that the class is public, and their is a none argument constructor.
Have you marked the classes as static?
public class Outer {
public static class Inner {
public Inner () { ... }
}
}
Hi ey6es,
Thanks for the hint, I know that an inner class can't exist without an instnace of its parent, except in the static inner classes. But the problem is that I have some references to some fields, and methods, which I can't make static, so making it static won't solve my problem.
The best solution I can think of to move from inner classes to a reguler class.
Here is a simple use case of what I am facing.
import java.io.IOException;
import java.io.Serializable;
import com.jme.util.export.JMEExporter;
import com.jme.util.export.JMEImporter;
import com.jme.util.export.Savable;
public class Outer implements Serializable, Savable {
public class Inner implements Serializable, Savable {
public Class getClassTag() {
return Inner.this.getClass();
}
public void read(JMEImporter im) throws IOException {
}
public void write(JMEExporter ex) throws IOException {
}
}
public Class getClassTag() {
return this.getClass();
}
public void read(JMEImporter im) throws IOException {
}
public void write(JMEExporter ex) throws IOException {
}
}
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import com.jme.util.export.InputCapsule;
import com.jme.util.export.JMEExporter;
import com.jme.util.export.JMEImporter;
import com.jme.util.export.OutputCapsule;
import com.jme.util.export.Savable;
import com.jme.util.export.binary.BinaryExporter;
import com.jme.util.export.binary.BinaryImporter;
public class GlobalClass implements Serializable, Savable {
Outer outer;
Outer.Inner inner;
public GlobalClass() {
outer = new Outer();
inner = outer.new Inner();
}
public void saveInstances() {
try {
BinaryExporter.getInstance().save(this, new File("test.ttt"));
} catch (IOException e) {
e.printStackTrace();
}
}
public void loadInstnaces() {
try {
BinaryImporter.getInstance().load(new File("test.ttt"));
} catch (IOException e) {
e.printStackTrace();
}
}
public Class getClassTag() {
return this.getClass();
}
public void read(JMEImporter im) throws IOException {
InputCapsule cp = im.getCapsule(this);
cp.readSavable("inner", null);
}
public void write(JMEExporter ex) throws IOException {
OutputCapsule oc = ex.getCapsule(this);
oc.write(inner, "inner", null);
}
}
public class Entry {
GlobalClass test;
public Entry () {
test = new GlobalClass();
saveClasses();
loadClasses();
}
public static void main(String args[ ]) {
new Entry();
}
public void loadClasses() {
test.loadInstnaces();
}
public void saveClasses() {
test.saveInstances();
}
}
Can this be handled with the Importer/Exporter ?
You would have to write a custom ClassLoaderModule to use non-static inner classes as they have to be created with the outer object as parameter. You can take a look into jME Physics 2 if you need some hints on how to do this (physics objects need the physics space for creation).
I'd recommend though that you make your classes static instead, as it's a lot easier. If you need to have access to fields of the surround class you can pass the reference to the outer object as a parameter of an additional constructor.