Bits of Java (トップ)

目次  前へ  次へ

XML に保存可能なオブジェクト

XML に保存する際にはプリミティブ型とそのラッパークラスは値が書き出されます。 String オブジェクトもそのまま書き出されます。 それ以外のオブジェクトの場合は基本的に引数を取らないコンストラクタがあれば書き出されます。さらにそのオブジェクトの内部状態を XML に保存するには プロパティ として getter setter メソッドの存在が必要です。 デフォルトコンストラクタがあってもプロパティが無ければデフォルトコンストラクタを実行した直後の状態にしか復元できません。

API ドキュメントの java.beans.XMLEncoder のクラス説明の部分にはプリミティブ型とそのラッパークラスのインスタンスの値が書き出されることやString オブジェクトが表す文字列が書き出されることが記述されています。 また配列も XML に保存されることが記述されています。 これらは JavaBeans のプロパティではありませんがサポートされていることがドキュメントに明記されています。 しかしドキュメントに記述はないものの他にも JavaBeans のプロパティ以外の内部状態が XML に書き出されるクラスはたくさんあります。

XML に内部状態を書き出す処理は XMLEncoder オブジェクト自身ではなく java.beans.PersistenceDelegate オブジェクトに委譲されます。 JavaBeans のプロパティの書き出しは java.beans.DefaultPersistenceDelegate クラスに実装されています。 JavaBeans のプロパティ以外のオブジェクトの内部状態を XML に書き出す為には、その処理を実装した PersistenceDelegate のサブクラスを作成する必要があります。

デフォルトで XML への書き出しがサポートされているクラスには Swing のコンポーネントを始め AWT や Swing 関連のクラスが多いのですが他にも Vector, ArrayList, LinkedList, HashSet, TreeSet, TreeMap, HashMap, Hashtable などは要素あるいはキーと値のペアが XML に書き出されます。 (AbstractCollection, AbstractList, AbstractMap のサブクラスや Hashtable やそのサブクラスであれば要素あるいはキーと値のペアが XML に保存されます。jdk1.5.0) ただしこれらがサポートされているという記述はドキュメントにはありません。 これらのクラスに対応する為の PersistenceDelegate のサブクラスは java.beans.MetaData クラスの内部クラスとして定義されおり MetaData クラス自体も同じパッケージ内からしかアクセスできないので外部から隠蔽されていることになります。 その上ドキュメントにも記述がまったくないということは将来におけるこれらのクラスのサポートが保証されていないと受け取ることもできます。 この辺りの曖昧さが XMLEncoder による JavaBeans の保存に関して書籍等であまり詳しく紹介していない原因の1つになっている気がします。 (とは言えコレクション、マップなどが将来において XML に書き出されなくなるということは考えられないと思います。)

下は JavaBeans 以外でデフォルトで XML に保存される内部状態を持つクラスに関する動作確認のプログラムです。

/******************** SampleBean.java ********************/
import java.util.*;

public class SampleBean {
    private boolean booleanValue;
    private char cahrValue;
    private byte byteValue;
    private short shortValue;
    private int intValue;
    private long longValue;
    private float floatValue;
    private double doubleValue;

    private String stringValue;

    private Object[] objectArray;
    private int[] intArray;

    private Vector vector = new Vector();
    private ArrayList arrayList = new ArrayList();
    private LinkedList linkedList = new LinkedList();
    private HashSet hashSet = new HashSet();
    private TreeSet treeSet = new TreeSet();
    private TreeMap treemap = new TreeMap();
    private HashMap hashMap = new HashMap();
    private Hashtable hashTable = new Hashtable();

    public ArrayList getArrayList() {
        return arrayList;
    }
    public void setArrayList(ArrayList arrayList) {
        this.arrayList = arrayList;
    }
    public boolean isBooleanValue() {
        return booleanValue;
    }
    public void setBooleanValue(boolean booleanValue) {
        this.booleanValue = booleanValue;
    }
    public byte getByteValue() {
        return byteValue;
    }
    public void setByteValue(byte byteValue) {
        this.byteValue = byteValue;
    }
    public char getCahrValue() {
        return cahrValue;
    }
    public void setCahrValue(char cahrValue) {
        this.cahrValue = cahrValue;
    }
    public double getDoubleValue() {
        return doubleValue;
    }
    public void setDoubleValue(double doubleValue) {
        this.doubleValue = doubleValue;
    }
    public float getFloatValue() {
        return floatValue;
    }
    public void setFloatValue(float floatValue) {
        this.floatValue = floatValue;
    }
    public HashMap getHashMap() {
        return hashMap;
    }
    public void setHashMap(HashMap hashMap) {
        this.hashMap = hashMap;
    }
    public HashSet getHashSet() {
        return hashSet;
    }
    public void setHashSet(HashSet hashSet) {
        this.hashSet = hashSet;
    }
    public Hashtable getHashTable() {
        return hashTable;
    }
    public void setHashTable(Hashtable hashTable) {
        this.hashTable = hashTable;
    }
    public int getIntValue() {
        return intValue;
    }
    public void setIntValue(int intValue) {
        this.intValue = intValue;
    }
    public LinkedList getLinkedList() {
        return linkedList;
    }
    public void setLinkedList(LinkedList linkedList) {
        this.linkedList = linkedList;
    }
    public long getLongValue() {
        return longValue;
    }
    public void setLongValue(long longValue) {
        this.longValue = longValue;
    }
    public short getShortValue() {
        return shortValue;
    }
    public void setShortValue(short shortValue) {
        this.shortValue = shortValue;
    }
    public String getStringValue() {
        return stringValue;
    }
    public void setStringValue(String stringValue) {
        this.stringValue = stringValue;
    }
    public TreeMap getTreemap() {
        return treemap;
    }
    public void setTreemap(TreeMap treemap) {
        this.treemap = treemap;
    }
    public TreeSet getTreeSet() {
        return treeSet;
    }
    public void setTreeSet(TreeSet treeSet) {
        this.treeSet = treeSet;
    }
    public Vector getVector() {
        return vector;
    }
    public void setVector(Vector vector) {
        this.vector = vector;
    }
    public int[] getIntArray() {
        return intArray;
    }
    public void setIntArray(int[] intArray) {
        this.intArray = intArray;
    }

    public Object[] getObjectArray() {
        return objectArray;
    }
    public void setObjectArray(Object[] objectArray) {
        this.objectArray = objectArray;
    }
}

/******************** Test.java ********************/
import java.beans.XMLEncoder;
import java.io.*;
import java.util.*;

public class Test {
   public static void main(String[] args) throws Exception {
        SampleBean bean = new SampleBean();
        bean.setBooleanValue(true);
        bean.setCahrValue('A');
        bean.setByteValue(Byte.MAX_VALUE);
        bean.setShortValue(Short.MIN_VALUE);
        bean.setIntValue(Integer.MAX_VALUE);
        bean.setLongValue(Long.MIN_VALUE);
        bean.setFloatValue(Float.MAX_VALUE);
        bean.setDoubleValue(Double.MIN_VALUE);
        bean.setStringValue("String");

        Object[] objectArray = new Object[3];
        objectArray[0] = "AAA";
        objectArray[2] = new Integer(100);
        bean.setObjectArray(objectArray);

        int[] intArray = new int[3];
        intArray[0] = -100;
        intArray[2] = 100;
        bean.setIntArray(intArray);

        ArrayList list = bean.getArrayList();
        list.add("CC");
        list.add("AA");
        list.add("DD");
        list.add("EE");
        list.add("BB");
        bean.setArrayList(list);
        bean.getVector().addAll(list);
        bean.getLinkedList().addAll(list);

        bean.getHashSet().addAll(list);
        bean.getTreeSet().addAll(list);

        HashMap map = bean.getHashMap();
        int size = list.size();
        for (int i = 0; i < size; i++) {
            map.put(new Integer(i), list.get(i));
        }
        bean.getHashTable().putAll(map);
        bean.getTreemap().putAll(map);

        XMLEncoder encoder = new XMLEncoder(
                                 new BufferedOutputStream(
                                     new FileOutputStream("sample.xml")));
        encoder.writeObject(bean);
        encoder.close();
    }
}

/******************** sample.xml ********************/
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.5.0_01" class="java.beans.XMLDecoder">
 <object class="SampleBean">
  <void property="arrayList">
   <void method="add">
    <string>CC</string>
   </void>
   <void method="add">
    <string>AA</string>
   </void>
   <void method="add">
    <string>DD</string>
   </void>
   <void method="add">
    <string>EE</string>
   </void>
   <void method="add">
    <string>BB</string>
   </void>
  </void>
  <void property="booleanValue">
   <boolean>true</boolean>
  </void>
  <void property="byteValue">
   <byte>127</byte>
  </void>
  <void property="cahrValue">
   <char>A</char>
  </void>
  <void property="doubleValue">
   <double>4.9E-324</double>
  </void>
  <void property="floatValue">
   <float>3.4028235E38</float>
  </void>
  <void property="hashMap">
   <void method="put">
    <int>2</int>
    <string>DD</string>
   </void>
   <void method="put">
    <int>4</int>
    <string>BB</string>
   </void>
   <void method="put">
    <int>1</int>
    <string>AA</string>
   </void>
   <void method="put">
    <int>3</int>
    <string>EE</string>
   </void>
   <void method="put">
    <int>0</int>
    <string>CC</string>
   </void>
  </void>
  <void property="hashSet">
   <void method="add">
    <string>DD</string>
   </void>
   <void method="add">
    <string>CC</string>
   </void>
   <void method="add">
    <string>EE</string>
   </void>
   <void method="add">
    <string>AA</string>
   </void>
   <void method="add">
    <string>BB</string>
   </void>
  </void>
  <void property="hashTable">
   <void method="put">
    <int>4</int>
    <string>BB</string>
   </void>
   <void method="put">
    <int>3</int>
    <string>EE</string>
   </void>
   <void method="put">
    <int>2</int>
    <string>DD</string>
   </void>
   <void method="put">
    <int>1</int>
    <string>AA</string>
   </void>
   <void method="put">
    <int>0</int>
    <string>CC</string>
   </void>
  </void>
  <void property="intArray">
   <array class="int" length="3">
    <void index="0">
     <int>-100</int>
    </void>
    <void index="2">
     <int>100</int>
    </void>
   </array>
  </void>
  <void property="intValue">
   <int>2147483647</int>
  </void>
  <void property="linkedList">
   <void method="add">
    <string>CC</string>
   </void>
   <void method="add">
    <string>AA</string>
   </void>
   <void method="add">
    <string>DD</string>
   </void>
   <void method="add">
    <string>EE</string>
   </void>
   <void method="add">
    <string>BB</string>
   </void>
  </void>
  <void property="longValue">
   <long>-9223372036854775808</long>
  </void>
  <void property="objectArray">
   <array class="java.lang.Object" length="3">
    <void index="0">
     <string>AAA</string>
    </void>
    <void index="2">
     <int>100</int>
    </void>
   </array>
  </void>
  <void property="shortValue">
   <short>-32768</short>
  </void>
  <void property="stringValue">
   <string>String</string>
  </void>
  <void property="treeSet">
   <void method="add">
    <string>AA</string>
   </void>
   <void method="add">
    <string>BB</string>
   </void>
   <void method="add">
    <string>CC</string>
   </void>
   <void method="add">
    <string>DD</string>
   </void>
   <void method="add">
    <string>EE</string>
   </void>
  </void>
  <void property="treemap">
   <void method="put">
    <int>0</int>
    <string>CC</string>
   </void>
   <void method="put">
    <int>1</int>
    <string>AA</string>
   </void>
   <void method="put">
    <int>2</int>
    <string>DD</string>
   </void>
   <void method="put">
    <int>3</int>
    <string>EE</string>
   </void>
   <void method="put">
    <int>4</int>
    <string>BB</string>
   </void>
  </void>
  <void property="vector">
   <void method="add">
    <string>CC</string>
   </void>
   <void method="add">
    <string>AA</string>
   </void>
   <void method="add">
    <string>DD</string>
   </void>
   <void method="add">
    <string>EE</string>
   </void>
   <void method="add">
    <string>BB</string>
   </void>
  </void>
 </object>
</java>