Это зависит от того, хотите ли вы использовать этот Object
в другой программе или на другом языке, если на то пошло, тогда да JSON — это то, что вам нужно (или XML).
Но если вы хотите повторно использовать этот Object
в другой программе JAVA, я думаю, было бы удобнее поискать способ сделать возможной не-сериализуемую Objects
сериализуемую.
Я еще не тестировал его, но нашел многообещающее решение в этот блог (извините, на французском языке). Постараюсь резюмировать:
что у вас есть
скажем, у вас есть имена классов Pojo
, и вы хотите их сериализовать, хотя вы не знаете, сериализуемы они или нет.
public final class Pojo {
private final String msg;
public Pojo(String msg) {
this.msg = msg;
}
public String getMsg() {
return msg;
}
public String toString() {
return "Pojo says : " + msg;
}
}
что вам нужно
вам нужен новый класс, который действует как суррогат, который будет принимать переменные-члены реального Pojo
и просто заменять его.
public class PojoSurrogate implements Serializable {
private String foo;
public PojoSurrogate(Pojo pojo) {
this.foo = pojo.getMsg();
}
private Object readResolve() throws ObjectStreamException {
return new Pojo(foo);
}
}
последний метод ( readResolve()
) — это тот, который в конце концов вернет вам ваш новый Pojo
позже.
Еще вам понадобится ваша собственная суррогатная версия ObjectOutputStream
:
public class SurrogateObjectOutputStream extends ObjectOutputStream {
public SurrogateObjectOutputStream(OutputStream out) throws IOException {
super(out);
enableReplaceObject(true);
}
protected SurrogateObjectOutputStream() throws IOException, SecurityException {
super();
enableReplaceObject(true);
}
@Override
protected Object replaceObject(Object obj) throws IOException {
if (obj instanceof Pojo) {
return new PojoSurrogate((Pojo) obj);
} else return super.replaceObject(obj);
}
}
И снова здесь последний метод replaceObject()
совершит волшебство и преобразует Pojo
в сериализуемую версию PojoSurrogate
для хранения всей информации в виде байтов.
Сериализация вот так
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new SurrogateObjectOutputStream(baos);
oos.writeObject(o);
oos.flush();
oos.close();
byte[] serializedPojo = baos.toByteArray();
Обычная десериализация
ObjectInputStream bais = new ObjectInputStream(new ByteArrayInputStream( serializedPojo ));
Pojo myNewPojo = (Pojo) bais.readObject();
bais.close();
Извините, длинный ответ ... и я надеюсь, что не пропустил ничего супер крутого из этого блога, где проще создать более масштабируемое решение ... надеюсь, что это все равно поможет!
[ИЗМЕНИТЬ:]
Я попробовал ваш код с объектом Area, и вот как я кое-что заработал (хотя я не уверен, действительно ли это работает со всеми Areas
, поэтому вам, возможно, придется проверить, имеют ли ваши области те же характеристики после десериализации)
Заместитель площади
public class AreaSurrogate implements Serializable {
private final Rectangle bounds;
public AreaSurrogate(Area area) {
this.bounds = area.getBounds();
}
private Object readResolve() throws ObjectStreamException {
return new Area(bounds);
}
}
Суррогатный выходной поток
public class SurrogateOutputStream extends ObjectOutputStream {
public SurrogateOutputStream(OutputStream out) throws IOException {
super(out);
enableReplaceObject(true);
}
protected SurrogateOutputStream() throws IOException, SecurityException {
super();
enableReplaceObject(true);
}
@Override
protected Object replaceObject(Object obj) throws IOException {
if (obj instanceof Area) {
return new AreaSurrogate((Area) obj);
} else {
return super.replaceObject(obj);
}
}
}
Сериализатор
public class Serializer {
public static byte[] serialize(Object o) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new SurrogateOutputStream(baos); // Magically handle Pojos !
oos.writeObject(o);
oos.flush();
oos.close();
return baos.toByteArray();
}
public static Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
Object o = ois.readObject();
bais.close();
return o;
}
}
Основной (для тестирования)
public static void main(String[] args) throws Exception {
Area area = new Area(new Rectangle(0, 0, 100, 100)); // The original object, NOT SERIALIZABLE !
System.out.println(area.contains(new Rectangle(1, 1, 10, 10))); // Good as new !
System.out.print("serializing...");
byte[] pojoBytes = Serializer.serialize(area); // Serialize
System.out.println("done");
System.out.print("deserializing...");
area = (Area) Serializer.deserialize(pojoBytes); // Deserialize
System.out.println("done");
System.out.println(area.contains(new Rectangle(1, 1, 10, 10))); // Good as new !
}
В main()
я создаю Area
из Rectangle
, который начинается с Координаты (0,0) и имеет ширину 100 и высоту 100. Затем я проверяю, находится ли прямоугольник из (1,1) шириной 10 и высотой 10 внутри области (принудительно). После сериализации и десериализации я проверяю, находится ли тот же прямоугольник внутри нового Area
.
Этого может быть недостаточно, поскольку новый Объект Area
создается из Rectangle
(см. AreaSurrogate
). так что это может не работать с другими формами Area..
ожидаемый результат
true
serializing...done
deserializing...done
true
person
GameDroids
schedule
21.02.2014