JAVA:Class赢得';连载

JAVA:Class赢得';连载,java,notserializableexception,Java,Notserializableexception,我一直在编写一个程序来学习更多关于JAVA的知识,我几乎完成了。我已经有一段时间没有处理序列化了,即使在复习了它之后,我仍然缺少一些东西。我试图将这个类保存到一个文件中,但它抛出了一个NotSerializableException。此类MonetaryField包含非原语类型的SingleField,该字段已序列化并可以保存到磁盘。它还包含以下内容: public class MonetaryField extends JPanel implements Serializable {

我一直在编写一个程序来学习更多关于JAVA的知识,我几乎完成了。我已经有一段时间没有处理序列化了,即使在复习了它之后,我仍然缺少一些东西。我试图将这个类保存到一个文件中,但它抛出了一个NotSerializableException。此类MonetaryField包含非原语类型的SingleField,该字段已序列化并可以保存到磁盘。它还包含以下内容:

public class MonetaryField extends JPanel implements Serializable {

    private static final long serialVersionUID = 1L;
    public JLabel label;
    public SingleField gold;
    public SingleField silver;
    public SingleField copper;

    public MonetaryField() {

    }

    public MonetaryField(String s, boolean editable, boolean border) {
            label = new JLabel(s);
            gold = new SingleField("gold.png", border);
            silver = new SingleField("silver.png", border);
            copper = new SingleField("copper.png", border);
            gold.addKeyListener(keys);
            silver.addKeyListener(keys);
            copper.addKeyListener(keys);

            if(!editable) {
                    gold.setEditable(false);
                    silver.setEditable(false);
                    copper.setEditable(false);
            }
            GroupLayout layout = new GroupLayout(this);             
            this.setLayout(layout);
            layout.setHorizontalGroup(
                  layout.createSequentialGroup()
                      .addComponent(label)
                      .addComponent(gold)
                      .addComponent(silver)
                      .addComponent(copper)
        );
            layout.setVerticalGroup(
                  layout.createSequentialGroup()
                      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                       .addComponent(label)
                       .addComponent(gold)
                       .addComponent(silver)
                       .addComponent(copper)
                    ));
    }

    public void setAmount(int g, int s, int c) {
            gold.setValue(g);
            silver.setValue(s);
            copper.setValue(c);
    }

    public void setAmount(String g, String s, String c) {
            gold.setValue(Integer.parseInt(g.replaceAll(",", "")));
            silver.setValue(Integer.parseInt(s.replaceAll(",", "")));
            copper.setValue(Integer.parseInt(c.replaceAll(",", "")));
    }

    public void setAmount(int amount) {
            gold.setValue(Math.floor(amount / 10000));
            silver.setValue(((amount % 10000) - (amount % 100)) / 100);
            copper.setValue(amount % 100);
    }

    public boolean sizeFits(Object field) {
            SingleField s_field = (SingleField) field;
            int max_chars = 4;
            boolean g = s_field.getText().length() < max_chars;
            if(!g) {
                    return false;
            }
            return true;
    }

    KeyListener keys = new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {
                    if(!Character.isDigit(e.getKeyChar()) || sizeFits(e.getSource()) == false) {
                            e.consume();
                    }
            }

            @Override
            public void keyReleased(KeyEvent e) {    }

            @Override
            public void keyPressed(KeyEvent e) {    }
    };

    public double getAmount() {
            double d = 0.0;
            d += Double.parseDouble(gold.getText());
            d += Double.parseDouble(silver.getText())/100;
            d += Double.parseDouble(copper.getText())/10000;
            return d;
    }
}
公共类MonetaryField扩展JPanel实现可序列化{
私有静态最终长serialVersionUID=1L;
公共标签;
公共单场金;
公共单场银;
公共单场铜;
公共货币领域(){
}
公共货币字段(字符串s,布尔可编辑,布尔边框){
标签=新的JLabel;
gold=新的单字段(“gold.png”,边框);
银色=新的单字段(“silver.png”,边框);
铜=新单字段(“copper.png”,边框);
gold.addKeyListener(键);
silver.addKeyListener(键);
铜。addKeyListener(键);
如果(!可编辑){
gold.setediate(false);
银色。可编辑(假);
铜。可编辑设置(假);
}
GroupLayout布局=新的GroupLayout(本);
这个.setLayout(布局);
layout.setHorizontalGroup(
layout.createSequentialGroup()
.addComponent(标签)
.addComponent(黄金)
.addComponent(银色)
.addComponent(铜)
);
layout.setVerticalGroup(
layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(标签)
.addComponent(黄金)
.addComponent(银色)
.addComponent(铜)
));
}
公共无效设置金额(整数g、整数s、整数c){
黄金设定值(g);
银。设定值;
铜。设定值(c);
}
公共void setAmount(字符串g、字符串s、字符串c){
gold.setValue(Integer.parseInt(g.replaceAll(“,”,”));
silver.setValue(Integer.parseInt(s.replaceAll(“,”,”));
copper.setValue(Integer.parseInt(c.replaceAll(“,”,”));
}
公共无效设置金额(整数金额){
黄金设定值(数学下限(金额/10000));
银。设定值((金额%10000)-(金额%100))/100);
铜。设定值(金额%100);
}
公共布尔sizeFits(对象字段){
单字段s_字段=(单字段)字段;
int max_chars=4;
布尔g=s_field.getText().length()

最后,我知道:非原语类型的单字段不是问题,因为它已序列化并成功保存到磁盘。当我在将其保存为数据的类中查询“
e.getCause()
”时,它说“null”。当我让它返回“
e.getMessage
”时,它将其归咎于“
javax.swing.GroupLayout
”。删除GroupLayout后,“
e.getMessage()
”刚刚返回“
omnitool.MonetaryField$1
”。Omnitool是主包。这就是我剩下的地方。我刚才试着为你们打印一个堆栈跟踪(例如getStackTrace().toString),但它告诉我的只是“
[Ljava.lang.StackTraceeElement;@6ab7501b
”…如果有人能解释这意味着什么。另外,我已经对序列化进行了几个小时的研究,但是如果有人有任何好的材料可以共享,那就太好了!

要打印堆栈跟踪,我建议您使用

e.printStackTrace();
您似乎有一个名为
keys
的非
transient
字段,这是名为
omnitool.MonetaryField$1
的匿名内部类,它不可序列化,因此它不会序列化。您可以将其设置为transient,但需要通过定义
readObject
me在反序列化时重新创建丁字裤

从中可以定义

private void readObject(java.io.ObjectInputStream stream)
     throws IOException, ClassNotFoundException {
    stream.defaultReadObject();
    // re-initialise transient fields.
}
我建议您避免将GUI组件与数据传输对象混淆。如果您有包含纯数据且易于序列化的类,以及可视化该数据的独立GUI组件,您的生活会轻松得多


我刚才试着为你们打印一个堆栈跟踪(例如getStackTrace().toString),但它告诉我的只是“[Ljava.lang.StackTraceeElement;@6ab7501b”…如果有人能解释这是什么意思的话


这意味着Java的array.toString被破坏,当您试图打印普通数组时,它使用Object.toString()打印类和System.IdentitHashCode(),这很少有用。您需要像Throwable.printStackTrace()或Arrays.toString(array)这样的帮助函数或者自己打印每个元素以查看它。

要打印堆栈跟踪,我建议您使用

e.printStackTrace();
您似乎有一个名为
keys
的非
transient
字段,该字段是匿名字段
KeyListener keys = new KeyListener() {