Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

使い方

こんな感じ。

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);
                }
            }
        }
    }
}
hirokapi
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away