Java(处理)对象序列化

Java(处理)对象序列化,java,serialization,stream,processing,Java,Serialization,Stream,Processing,我正试图通过处理来制作彩色方块的3D矩阵。它工作正常,但是当我想将它保存到序列化DataMatrix对象的文件中时,我得到了这个异常:java.io.NotSerializableException。Square和DataMatrix都实现了可序列化,所以我不知道是什么导致了它 文件管理器: class FileManager { FileManager() {} public void saveMatrix(String path, DataMatrix dm) {

我正试图通过处理来制作彩色方块的3D矩阵。它工作正常,但是当我想将它保存到序列化DataMatrix对象的文件中时,我得到了这个异常:java.io.NotSerializableException。Square和DataMatrix都实现了可序列化,所以我不知道是什么导致了它

文件管理器:

class FileManager
{

  FileManager()
  {}

  public void saveMatrix(String path, DataMatrix dm)
  {
    try
    {
    FileOutputStream file = new FileOutputStream(path);
    ObjectOutputStream output = new ObjectOutputStream(file);
    output.writeObject(dm); 
    output.close();
    }
    catch (Exception e)
    {
       e.printStackTrace();
    }
  } 

  public DataMatrix openMatrix(String path)
  {
    DataMatrix dm = null;

    try
    {

       FileInputStream file = new FileInputStream(path);
       ObjectInputStream input = new ObjectInputStream(file);
       Object aux = input.readObject();
       input.close();
       if(aux instanceof DataMatrix)
       {
         dm = (DataMatrix)aux;
       }        
    }
    catch (EOFException e1)
    {
       System.out.println ("Fin de fichero");
    }
    catch (Exception e2)
    {
        e2.printStackTrace();
    }

    return dm; 
  }
}
数据矩阵:

class DataMatrix implements Serializable
{

  Square[][][] dataMatrix;

  DataMatrix()
  { 
      dataMatrix = new Square[5][32][32];
  }

  public void setSquare(int x, int y, int z, color c, String type)
  {

     dataMatrix[z][x][y].setSquare(c,type);   

  }
正方形:

class Square implements Serializable
{

  public int x;
  public int y;
  public int z;
  public color c;
  public String type;

  Square(int xx, int yy, int zz, color cc, String tt){
    x = xx;
    y = yy;
    z = zz;
    c = cc;
    type = tt; 
  }

  public void setSquare(color cc, String tt){

    c = cc;
    type = tt;

  }

  public void printSquare()
  {
     println(green(c) +"  "+ type); 
  }

}
错误日志:

java.io.NotSerializableException: processing.core.PApplet$InternalEventQueue
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
    at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
    at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
    at maindatamatrix$FileManager.saveMatrix(maindatamatrix.java:105)
    at maindatamatrix.setup(maindatamatrix.java:30)
    at processing.core.PApplet.handleDraw(PApplet.java:2245)
    at processing.core.PGraphicsJava2D.requestDraw(PGraphicsJava2D.java:243)
    at processing.core.PApplet.run(PApplet.java:2141)
    at java.lang.Thread.run(Thread.java:662)
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: processing.core.PApplet$InternalEventQueue
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1332)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1666)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1322)
    at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1666)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1322)
    at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1666)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1322)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at maindatamatrix$FileManager.openMatrix(maindatamatrix.java:123)
    at maindatamatrix.setup(maindatamatrix.java:33)
    at processing.core.PApplet.handleDraw(PApplet.java:2245)
    at processing.core.PGraphicsJava2D.requestDraw(PGraphicsJava2D.java:243)
    at processing.core.PApplet.run(PApplet.java:2141)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.io.NotSerializableException: processing.core.PApplet$InternalEventQueue
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
    at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
    at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
    at maindatamatrix$FileManager.saveMatrix(maindatamatrix.java:105)
    at maindatamatrix.setup(maindatamatrix.java:30)
    ... 4 more

我认为它可能是颜色类,所以我使用瞬态修改器来检查它。还是一样的错误。有什么想法吗?

似乎在文件管理器类中,在try block中,对象的字段依次具有它们的字段,其中一些字段没有实现可序列化

如果颜色类实现可序列化。。??
如果您使用的是不可序列化的第三方库,请尝试基于xml的序列化或其他序列化形式,如json。

好吧,我实际上测试了您的代码,但更改了一个简单字符串的未知颜色类。它编写文件时没有抱怨,因此,我假设如下:

  • 也许当您声明transient时,您仍然运行较旧的编译版本?这取决于您如何设置编译/运行时环境

  • 颜色类可能会导致问题。您能准确地提供该类的包名以便我们查找它吗

  • 在您的导入中,您是否100%确定您是这样导入的?我遇到过这样的情况,主要是在eclipse中,当您让eclipse帮助您解决问题时,您获取了一个错误的导入

    导入java.io.Serializable

  • 您使用的是什么版本的Java,在哪里运行代码?它看起来像小程序的一部分

  • 根据你最后的回答,我可以推荐如下:

    在Square类中存储3个变量:

    private int r;
    private int g;
    private int b;
    
    public void setColor(int r, int g, int b) {
        this.r = r;
        this.g = g;
        this.b = b;
    }
    
    public color getColor() {
        return color(r, g, b);
    }
    
    这样就可以解决颜色序列化问题


    顺便说一句,我想你的意思是处理:

    要实现这一点,我必须:

    • 将实现可序列化的所有类重命名为.java,使DataMatrix成为DataMatrix.javaSquare成为Square.java
    • 在这些类中使用
      int
      而不是
      color
    • 在这些类中添加缺少的导入
    代码如下:

    SerializableTest.pde:

    void setup(){
      DataMatrix dm = new DataMatrix();
      FileManager f = new FileManager();
      f.saveMatrix("/Users/me/test", dm);
    }
    
    DataMatrix.java:

    import java.io.Serializable;
    
    class DataMatrix implements Serializable
    {
    
      Square[][][] dataMatrix;
    
      DataMatrix()
      { 
          dataMatrix = new Square[5][32][32];
      }
    
      public void setSquare(int x, int y, int z, int c, String type)
      {
    
         dataMatrix[z][x][y].setSquare(c,type);   
    
      }
    }
    
    FileManager.pde:

    import java.io.FileOutputStream;
    import java.io.ObjectOutputStream;
    import java.io.FileInputStream;
    import java.io.ObjectInputStream;
    import java.io.EOFException;
    
    class FileManager
    {
    
      FileManager()
      {}
    
      public void saveMatrix(String path, DataMatrix dm)
      {
        try
        {
        FileOutputStream file = new FileOutputStream(path);
        ObjectOutputStream output = new ObjectOutputStream(file);
        output.writeObject(dm); 
        output.close();
        }
        catch (Exception e)
        {
           e.printStackTrace();
        }
      } 
    
      public DataMatrix openMatrix(String path)
      {
        DataMatrix dm = null;
    
        try
        {
    
           FileInputStream file = new FileInputStream(path);
           ObjectInputStream input = new ObjectInputStream(file);
           Object aux = input.readObject();
           input.close();
           if(aux instanceof DataMatrix)
           {
             dm = (DataMatrix)aux;
           }        
        }
        catch (EOFException e1)
        {
           System.out.println ("Fin de fichero");
        }
        catch (Exception e2)
        {
            e2.printStackTrace();
        }
    
        return dm; 
      }
    }
    
    Square.java:

    import java.io.Serializable;
    import processing.core.*;
    
    class Square implements Serializable
    {
    
      public int x;
      public int y;
      public int z;
      public int c;
      public String type;
    
      Square(int xx, int yy, int zz, int cc, String tt){
        x = xx;
        y = yy;
        z = zz;
        c = cc;
        type = tt; 
      }
    
      public void setSquare(int cc, String tt){
    
        c = cc;
        type = tt;
    
      }
    
      public void printSquare()
      {
         //System.out.println(PApplet.green(c) +"  "+ type);
        int g = (c >> 8) & 0xFF;   // Faster way of getting green(argb)
        System.out.println(g); 
      }
    
    }
    

    Oracle本身已不再强调可序列化接口、DataInputStream和DataOutputStream类

    这种老式序列化的问题在于,如果更改对象中需要保存到二进制文件中的字段,则现有文件与较新版本的软件不兼容

    我建议您定义自己的文件格式并掌握自己的命运。这在前面需要一点努力,但从长远来看,你不会“把自己画进一个角落”

    我宁愿使用XML文件,也不愿使用Java的老式序列化

    或者,如果您真的想要一个二进制文件,您可以使用DataInputStream和DataOutputStream并读取和写入您自己的字段

    但我认为XML是最好的,因为生成的文件是“人类可读的”,甚至是“人类可编辑的”


    当我设计一种文件格式(或传输数据的格式)时,我认为最好有一个版本号来标识文件格式的哪个版本。您可能不需要此文件格式版本号,但拥有它只会在将来为您提供更大的灵活性。

    这是什么
    color
    ?它是Processing@Phob1a“本机类”是什么意思?实际上并没有从可序列化接口实现任何方法。对不起,我不知道“本地人”这个词是否正确。我的意思是,它带有处理功能,你不需要导入任何东西。没有类颜色。处理IDE将颜色变量视为int。