LoginSignup
4
3

More than 5 years have passed since last update.

SerializableなクラスのserialVersionUID定義を不要にする方法

Posted at

使い方

こんな感じ。

public class HogeTest {
    @Test
    public void test() throws Exception {
        Hoge before = new HogeImpl();
        Hoge after = Hoge.deserialize(HogeImpl.class, before.serialize());
        assertEquals(before, after);
    }
}

やり方

こんな感じのクラスをベースにすればOKです♪

abstract public class Hoge implements Externalizable {

    private static Map<String, Field[]> classFields = new ConcurrentHashMap<>();

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        for (Field field : getSortedFields()) {
            try {
                Object value = field.get(this);
                out.writeObject(value);
            } catch (Exception e) {
                continue;
            }
        }
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException,
            ClassNotFoundException {
        for (Field field : getSortedFields()) {
            try {
                Object value = in.readObject();
                field.set(this, value);
            } catch (Exception e) {
                continue;
            }
        }
    }


    private synchronized Field[] getSortedFields() {
        Class<?> clazz = this.getClass();
        Field[] fields = classFields.get(clazz.getName());
        if (null == fields) {
            fields =
                getSortedFields(clazz, clazz, new TreeMap<String, Field>());
            classFields.put(clazz.getName(), fields);
        }
        return fields;
    }

    private Field[] getSortedFields(Class<?> parent, Class<?> clazz,
            TreeMap<String, Field> treeMap) {
        for (Field field : clazz.getDeclaredFields()) {
            int mod = field.getModifiers();
            if (!Modifier.isFinal(mod) && !Modifier.isStatic(mod)) {
                String key = field.getName();
                Field value;
                try {
                    value = parent.getField(key);
                } catch (Exception e) {
                    continue;
                }
                treeMap.put(key, value);
            }
        }
        Class<?> superClass = clazz.getSuperclass();
        if (Object.class == superClass) {
            return treeMap.values().toArray(new Field[] {});
        }
        return getSortedFields(parent, superClass, treeMap);
    }

    public byte[] serialize() {
        ObjectOutputStream out = null;
        try {
            ByteArrayOutputStream byteArrayOutputStream =
                new ByteArrayOutputStream();
            out =
                new ObjectOutputStream(new BufferedOutputStream(
                    byteArrayOutputStream));
            out.writeObject(this);
            out.flush();
            byte[] bytes = byteArrayOutputStream.toByteArray();
            return bytes;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (null != out) {
                try {
                    out.close();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    public static <T> T deserialize(Class<T> type, byte[] bytes) {
        ObjectInputStream in = null;
        try {
            in =
                new ObjectInputStream(new BufferedInputStream(
                    new ByteArrayInputStream(bytes)));
            @SuppressWarnings("unchecked")
            T obj = (T) in.readObject();
            return obj;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (null != in) {
                try {
                    in.close();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3