Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
hab in eine Elternklasse eine XML-Serialsierung eingebaut (AbstractFrame). Da die Elternklasse abstrakt ist, kann ich nur mit Kindklassenobjekten arbeiten. (z.b. LoginFrame, MainFrame, SettingsFrame, ...).
Jetzt ist das Problem, dass wenn ich ein Objekt einer Kindklasse (zb. LoginFrame) serialisieren will, der nur die Membervariablen und deren Inhalt der Elternklasse übernimmt.
Beispiel:
Java:
public class KlasseA {
private int a;
private int b;
}
Java:
public class KlasseB extends KlasseA {
private int c;
}
Wird ein Objekt der KlasseA serialisiert, werden nur die vererbten Membervariablen/Attribute übernommen (in diesem Fall nur die Attribute a und b, nicht aber c).
Was soll ich machen, wenn ich die eigenen und vererbten Attribute mit serialisiert haben will?
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
@SuppressWarnings("serial")
public class Test {
public static void main(String[] args) {
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(new KlasseB(1, 2, 3));
oos.close();
byte[] data = os.toByteArray();
oos.close();
ByteArrayInputStream is = new ByteArrayInputStream(data);
ObjectInputStream ois = new ObjectInputStream(is);
KlasseB object = (KlasseB) ois.readObject();
System.out.println(object.a);
System.out.println(object.b);
System.out.println(object.c);
} catch (Exception e) {
e.printStackTrace();
}
}
public static class KlasseA implements Serializable {
KlasseA(int a, int b) {
this.a = a;
this.b = b;
}
int a;
int b;
}
public static class KlasseB extends KlasseA {
KlasseB(int a, int b, int c) {
super(a, b);
this.c = c;
}
int c;
}
}
Also, damit keine Unverständlichkeiten auftauchen, hier mal mein kompletter Code:
Steige gerade in die Serialisierung ein, daher sind sicher einige Sachen nicht so ganz konform, könnt ihr aber gerne ansprechen!
An was ich halt gerade arbeite ist, aus Übungszwecken ein kleines datenbankbasiertes Buchhaltungsprogramm zu basteln.
Zusätzlich sollen an einigen Stellen Eingaben mit der Serialisierung wieder hergestellt werden.
Hier die Klassen:
Core - Hauptklasse von allem.
Java:
public class Core {
private String appdataPath;
private LoginFrame loginFrame = null;
private MainFrame mainFrame = null;
private SettingsFrame settingsFrame = null;
public Core() {
}
public void init() {
try {
setAppdataPath(System.getProperty("user.home") + "\\AppData\\Roaming\\iEnterprise");
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
if (!(new File(appdataPath).exists())) {
System.out.println(appdataPath);
if (!(new File(appdataPath)).mkdir()) {
throw new Exception();
}
}
loginFrame = new LoginFrame();
if (loginFrame.getLastSerialization() != null) {
loginFrame.equalize(loginFrame.getLastSerialization());
}
loginFrame.setVisible(true);
}
catch (Exception exc) {
JOptionPane.showMessageDialog(null, exc.getStackTrace(), "iEnterprise - General Error", JOptionPane.ERROR_MESSAGE);
System.exit(1000);
}
}
/**
* @return the appdataPath
*/
public String getAppdataPath() {
return appdataPath;
}
/**
* @param appdataPath the appdataPath to set
*/
public void setAppdataPath(String appdataPath) {
this.appdataPath = appdataPath;
}
/**
* @return the loginFrame
*/
public LoginFrame getLoginFrame() {
return loginFrame;
}
/**
* @param loginFrame the loginFrame to set
*/
public void setLoginFrame(LoginFrame loginFrame) {
this.loginFrame = loginFrame;
}
/**
* @return the mainFrame
*/
public MainFrame getMainFrame() {
return mainFrame;
}
/**
* @param mainFrame the mainFrame to set
*/
public void setMainFrame(MainFrame mainFrame) {
this.mainFrame = mainFrame;
}
}
Klasse AbstractFrame. Soll für jeden Frame Standardfunktionen bereitstellen, so auch die Serialisierung.
Java:
package enterprise;
import javax.swing.*;
import java.io.*;
import java.beans.*;
/**
*
* @author Spitfire777
*/
public abstract class AbstractFrame extends JFrame {
private long timeCreated;
public AbstractFrame() {
super();
setTimeCreated(System.currentTimeMillis());
}
public void centerFrame() {
//...
}
public void write() throws java.io.FileNotFoundException, java.io.IOException {
File outputFile = new File(Main.getCore().getAppdataPath() + "\\" + this.getClass().getSimpleName() + "_" + getTimeCreated() + ".xml");
System.out.println(outputFile.getAbsolutePath());
FileOutputStream os = new FileOutputStream(outputFile);
XMLEncoder encoder = new XMLEncoder(os);
encoder.writeObject(this);
encoder.close();
os.close();
}
public AbstractFrame read(String path) throws java.io.FileNotFoundException {
File inputFile = new File(path);
FileInputStream is = new FileInputStream(inputFile);
XMLDecoder decoder = new XMLDecoder(is);
return (AbstractFrame) decoder.readObject();
}
public AbstractFrame getLastSerialization() {
File appdataDirectory = new File(Main.getCore().getAppdataPath());
File[] allFiles = appdataDirectory.listFiles();
long currentTime = 0;
long lastTime = 0;
for (int i = 0; i < allFiles.length; i++) {
if (allFiles[i].isFile() && (allFiles[i].getName().contains(this.getClass().getSimpleName()))) {
String s1 = allFiles[i].getName().substring(this.getClass().getSimpleName().length() + 1, allFiles[i].getName().length());
String s2 = s1.substring(0, s1.length() - 4);
currentTime = Long.parseLong(s2);
if (currentTime > lastTime) lastTime = currentTime;
}
}
try {
return read(Main.getCore().getAppdataPath() + "\\" + this.getClass().getSimpleName() + "_ " + lastTime + ".xml");
}
catch (FileNotFoundException exc) {
return null;
}
}
public abstract void equalize(AbstractFrame frame);
/**
* @return the timeCreated
*/
public long getTimeCreated() {
return timeCreated;
}
/**
* @param timeCreated the timeCreated to set
*/
public void setTimeCreated(long timeCreated) {
this.timeCreated = timeCreated;
}
}
Auf die Art funktioniert zwar soweit alles wunderbar, jedoch bekomme ich nach der Serialierung eines abgeleiteten Frames von AbstractFrame nur die Attribute von AbstractFrame serialisiert.
Folgender XML-Output nach der Serialisierung eines Login-Fensters:
du schreibst gar nicht, wie die Subklassen aussehen, oder zumindest eine davon,
wenn setter/getter fehlen oder Werte null bzw. der Standard sind, dann schreibt XMLEncoder anscheinend nix,
ersteres mangels Können, letzteres aus Sparsamkeit,
hier ein weiteres gekürztes Beispiel:
Java:
public class Test
{
public static void main(final String[] args)
throws Exception
{
LoginFrame l = new LoginFrame();
// l.setAbc("y");
l.write();
}
public static class LoginFrame
extends AbstractFrame
{
private String abc = "z";
/**
* @return abc
*/
public String getAbc()
{
return this.abc;
}
/**
* @param abc
*/
public void setAbc(String abc)
{
this.abc = abc;
}
}
public static abstract class AbstractFrame
extends JFrame
{
private long timeCreated;
public AbstractFrame()
{
setTimeCreated(System.currentTimeMillis());
}
public void write()
throws Exception
{
File outputFile = new File("test.xml");
System.out.println(outputFile.getAbsolutePath());
FileOutputStream os = new FileOutputStream(outputFile);
XMLEncoder encoder = new XMLEncoder(os);
encoder.writeObject(this);
encoder.close();
os.close();
}
public AbstractFrame read()
throws Exception
{
File inputFile = new File("test.xml");
FileInputStream is = new FileInputStream(inputFile);
XMLDecoder decoder = new XMLDecoder(is);
return (AbstractFrame)decoder.readObject();
}
public AbstractFrame getLastSerialization()
throws Exception
{
return read();
}
/**
* @return the timeCreated
*/
public long getTimeCreated()
{
return timeCreated;
}
/**
* @param timeCreated
* the timeCreated to set
*/
public void setTimeCreated(long timeCreated)
{
this.timeCreated = timeCreated;
}
}
}
wie die subklasse ausgesehen hätte ist ja im prinzip egal. wichtig ist einfach, dass ich von jeder subklasse die vererbte methode "write()" ausführen will und mir dann die eingabedaten etc. als xml gesichert werden.
führe ich sie aus, speichert er nur die daten der AbstractFrame.