みーのぺーじ

みーが趣味でやっているPCやソフトウェアについて.Python, Javascript, Processing, Unityなど.

processingのClassをSerializableにできない問題

Processingでデータを保存したい時、ObjectOutputStreamを使用すると便利ですが、Classのインスタンスを保存したい場合は、Serializableする必要があります。しかし、普通にSerializableするだけはNotSerializableExceptionとなってしまいます。(T_T)

例えば以下のコードを実行してみます。

これは、SerializableなclassであるTestを、ObjectOutputStreamを用いて、dataフォルダのtest.binファイルに保存するプログラムです。

void setup() { 
  try {
    OutputStream os = createOutput(new java.io.File(dataPath("test.bin")));
    java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(os);
    oos.writeObject(new Test(1,2));
  }
  catch (IOException e) {
    e.printStackTrace();
  }
}

class Test implements java.io.Serializable {
  private int x;
  private int y;
  public Test(int _x, int _y) {
    x=_x;
    y=_y;
  }
}

TestはSerializableであるはずなのに、実行すると以下のようにNotSerializableExceptionが発生します。

java.io.NotSerializableException: processing.core.PApplet$InternalEventQueue
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
    .....

これはおそらくTestはPAppletの内部クラスであることが原因だと思われます。これを防ぐ方法は、普通の外部クラスにすればいいわけです。

Processingでは、プロジェクトフォルダにあるpdeファイルはすべて結合してコンパイルされますが、javaファイルは別にコンパイルされるようです。

参考:うえちょこ@ぼろぐ

エディタ上で新規タブを作成し、Test.javaと命名します。これでjavaファイルが作成されます。上記のソースを、Testクラスの部分だけをTest.javaにカット・アンド・ペーストします。

void setup() {
  try {
    OutputStream os = createOutput(new java.io.File(dataPath("test.bin")));
    java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(os);
    oos.writeObject(new Test(1,2));
  }
  catch (IOException e) {
    e.printStackTrace();
  }
}
/// Test.java
class Test implements java.io.Serializable {
  private int x;
  private int y;
  public Test(int _x, int _y) {
    x=_x;
    y=_y;
  }
}

実行すると、無事にtest.binが出力されます。

(2013.6.18)