序列化对象到Xml文件以及反序列话Xml文件到对象(序列化数据到8个Java原型类型)

序列化对象到Xml文件以及反序列化Xml文件到对象

----(持续序列化对象到只含有属于8Java基本类型的变量)

在前面一篇文章《Java序列化中SUID问题的完美解决方案》中,通过用新对象的SUID替换原对象的SUID,使得经过改动后的对象无法反序列化原来对象数据的问题得到解决。但是这个方法也有它的不足地方,就是如果一个对象没有实现Serializable接口的话,我们就无法实现序列化这个对象,而且一般经过序列化后产生的数据对用户来说无法看懂,因此我们有必要自己实现一种序列化方法,将对象中的数据序列化到用户看得懂的Xml文件中,而且序列化后的Xml文件中的数据全部都是Java8种基本类型。也就是说,序列化对象的时候,如果对象的变量类型属于8Java基本类型(boolean,byte,short,int,long,float,double,char),那么就将这个变量数据存入到Xml文件中去,如果对象的变量类型不是8种基本类型,那么继续序列化这个变量对象,直到将这个变量对象分解到到基本类型,然后存数据入Xml文件。

我们写了一个类XmlSerializerUtil来完成序列化和反序列化的任务,它有两个公开的方法public static Document serializeObject(Object source)
public static Object deserializeObject(Document source)
。下面是这个类的testcase,主要是演示如果使用这个XmlSerializerUtil类:

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

 

import junit.framework.TestCase;

 

import org.apache.tools.ant.Project;

import org.jdom.Document;

import org.jdom.input.SAXBuilder;

import org.jdom.output.Format;

import org.jdom.output.XMLOutputter;

 

public class XmlSerializerUtilTest extends TestCase {

      

       public XmlSerializerUtilTest(String name) {

              super(name);

       }

      

       private final String fileName="serializedObject.xml";

      

       public void testMain() throws Exception {

       

              /**

         * serialize a object

         */

        HelloWorld1 hello1 = new HelloWorld1();

        System.out.println("object id (before serialization):/r/n"+hello1);

        Document document1 = XmlSerializerUtil.serializeObject(hello1);

        printDocument(document1);

       

        /**

         * deserialize a object

         */

 HelloWorld1 hello2 =
 (HelloWorld1) XmlSerializerUtil.deserializeObject(document1);

        System.out.println("object id (after serialization and deserialization):/r/n"+hello2);

        Document document2 = XmlSerializerUtil.serializeObject(hello2);

        printDocument(document2);

 

    }

      

       /**

        * 首先将HelloWorld1对象序列化到一个xml文件中去,他能够序列化数据到primitive类型.

        *

        */

       public void testSerialization2XmlFile() throws Exception {

       

        /**

         * serialize a object

         */

        HelloWorld1 hello1 = new HelloWorld1();

        Document document1 = XmlSerializerUtil.serializeObject(hello1);

        createFile(document1, fileName);

       

        /**

         * put data to a object  from xml file

         */

        Document doc = loadFile(fileName);

        Object object = XmlSerializerUtil.deserializeObject(doc);

        HelloWorld1 hello2 = (HelloWorld1) object;

 

        /**

         * serialize a object again.

         */

        Document document2 = XmlSerializerUtil.serializeObject(hello2);

        printDocument(document2);

    }

      

       /**

        * 在运行完成testSerialization2XmlFile,会得到一个serializedObject.xml文件,修改这个文件中的

        * HelloWorld1 改成HelloWorld2.

        * 然后再运行下面这个方法,可以看到HelloWord1中的数据到HelloWorld2中去了.

        */

       public void testDeserialization2Object() throws Exception {

       

        /**

         * put data to a object  from xml file

         */

        Document doc = loadFile(fileName);

        Object object = XmlSerializerUtil.deserializeObject(doc);

        HelloWorld2 hello2 = (HelloWorld2) object;

 

        /**

         * serialize a object again.

         */

        Document document2 = XmlSerializerUtil.serializeObject(hello2);

        printDocument(document2);

    }

      

       public void testSerializeAntProject() throws Exception {

        /**

         * serialize a object

         */

        Project project1 = new Project();

        System.out.println("object id (before serialization):"+project1);

        Document document1 = XmlSerializerUtil.serializeObject(project1);

        printDocument(document1);

       

        /**

         * deserialize a object

         */

        Project project2 = (Project)  XmlSerializerUtil.deserializeObject(document1);

        System.out.println("object id (after serialization and deserialization):"+project2);

        Document document2 = XmlSerializerUtil.serializeObject(project2);

        printDocument(document2);

    }

 

    private void createFile(Document doc, String fileName) {

        XMLOutputter xmlOut = new XMLOutputter(); // 生成xml的输出流

        Format format = xmlOut.getFormat(); // 输出流格式化

        format.setEncoding("UTF-8"); // 设置字符集

        format.setExpandEmptyElements(true); //是否填充

        format.setIndent("/t");

        format.setLineSeparator("/r/n");

        xmlOut.setFormat(format); // 把格式化的流给输出流

        try {

            // 生成xml的文件,文件名为用户输入的文件

            xmlOut.output(doc, new FileOutputStream(fileName));

            System.out.println("create a file called " + fileName);

        } catch (IOException ex) {

            System.out.println("the cause of file creation failure is " + ex.getMessage());

        }

    }

 

    private Document loadFile(String fileName) {

        Document doc = null;

        FileInputStream fi = null; // 文件输入流

        File file = new File(fileName);

        try {

            if (!file.isFile()) { // 文件打开失败

                System.out.println("fails to open a file called " + fileName);

            } else {

                fi = new FileInputStream(file); // 建立打开流

                SAXBuilder sb = new SAXBuilder();

                doc = sb.build(fi); // 把文件流给build

            }

        } catch (Exception e) {

            System.out.println("fails to open a file called " + fileName + ",the cause is "+ e.getMessage());

        } finally {

            try {

                fi.close();

            } catch (Exception e) {

                e.printStackTrace();

            }

        }

        return doc;

    }

   

    private void printDocument(Document doc){

           XMLOutputter xmlOut = new XMLOutputter(); // 生成xml的输出流

        Format format = xmlOut.getFormat(); // 输出流格式化

        format.setEncoding("UTF-8"); // 设置字符集

        format.setExpandEmptyElements(true); //是否填充

        format.setIndent("/t");

        format.setLineSeparator("/r/n");

        xmlOut.setFormat(format); // 把格式化的流给输出流

        try {

            //print Document in normal text format.

            xmlOut.output(doc, System.out);

         

        } catch (IOException ex) {

            System.out.println("the cause of file creation failure is " + ex.getMessage());

        }

    }

}

 

从上面这个类我们可以看到很容易使用它:

HelloWorld1 hello1 = new HelloWorld1();

Document document1 = XmlSerializerUtil.serializeObject(hello1);

createFile(document1, fileName);

通过调用serializeObject方法完成将任意一个对象序列化为一个JDOMDocument对象,然后使用方法createFile方法将Document内容输出到一个Xml文件中去。

反序列化的步骤类似:

Document doc = loadFile(fileName);

Object object = XmlSerializerUtil.deserializeObject(doc);

HelloWorld1 hello2 = (HelloWorld1) object;

首先将一个Xml文件读入到JDOMDocument对象中去,然后再调用deserializeObject方法完成将一个Document对象反序列化到原来那个对象中去。

其中HelloWorld1类如下:

import java.io.Serializable;

public class HelloWorld1

{

    private String m_sName="20000";

    public String getName()

    {

        return m_sName;

    }

   

    public void setName(String name){

      m_sName=name; 

    }

}

下面是序列化后的xml数据:

<?xml version="1.0" encoding="UTF-8"?>

<serialized>

    <object class="HelloWorld1" id="0">

       <field name="m_sName" declaringclass=" HelloWorld1">

           <reference>1</reference>

       </field>

    </object>

    <object class="java.lang.String" id="1">

       <field name="value" declaringclass="java.lang.String">

           <reference>2</reference>

       </field>

       <field name="offset" declaringclass="java.lang.String">

           <value>0</value>

       </field>

       <field name="count" declaringclass="java.lang.String">

           <value>5</value>

       </field>

       <field name="hash" declaringclass="java.lang.String">

           <value>0</value>

       </field>

    </object>

    <object class="[C" id="2" length="5">

       <value>2</value>

       <value>0</value>

       <value>0</value>

       <value>0</value>

       <value>0</value>

    </object>

</serialized>

 

然后让我们来看看这个XmlSerializerUtil类是怎么去实现序列化和反序列化的:

import java.lang.reflect.Array;

import java.lang.reflect.Constructor;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

import java.lang.reflect.Modifier;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.HashMap;

import java.util.IdentityHashMap;

import java.util.LinkedList;

import java.util.List;

import java.util.Map;

import java.util.Vector;

 

import org.jdom.Document;

import org.jdom.Element;

 

 

public class XmlSerializerUtil

{

 

    //start extract serializeObject

 

    public static Document serializeObject(Object source)

        throws Exception

    {

        return serializeHelper(source, new Document(new Element("serialized")),

            new IdentityHashMap());

    }

 

 

    private static Document serializeHelper(Object source,Document target,Map table)

        throws Exception

    {

        String id = Integer.toString(table.size()); //#1

        table.put(source, id); //#1

        Class sourceclass = source.getClass(); //#1

 

        Element oElt = new Element("object"); //#2

        oElt.setAttribute("class", sourceclass.getName()); //#2

        oElt.setAttribute("id", id); //#2

        target.getRootElement().addContent(oElt); //#2

 

        if (!sourceclass.isArray()) { //#3

            Field[] fields = Mopex.getInstanceVariables(sourceclass); //#4

            for (int i = 0; i < fields.length; i++) { //#4

 

                if (!Modifier.isPublic(fields[i].getModifiers())) //#5

                    fields[i].setAccessible(true); //#5

 

                Element fElt = new Element("field"); //#6

                fElt.setAttribute("name", fields[i].getName()); //#6

                Class declClass = fields[i].getDeclaringClass(); //#6

                fElt.setAttribute("declaringclass", //#6

                    declClass.getName()); //#6

                //#6

                Class fieldtype = fields[i].getType(); //#6

                Object child = fields[i].get(source); //#6

                //#6

                if (Modifier.isTransient(fields[i].getModifiers())) { //#6

                    child = null; //#6

                } //#6

                fElt.addContent(serializeVariable(fieldtype, child, //#6

                    target, table)); //#6

                //#6

                oElt.addContent(fElt); //#6

            }

        }

        else {

            Class componentType = sourceclass.getComponentType(); //#7

            //#7

            int length = Array.getLength(source); //#7

            oElt.setAttribute("length", Integer.toString(length)); //#7

            //#7

            for (int i = 0; i < length; i++) { //#7

                oElt.addContent(serializeVariable(componentType, //#7

                    Array.get(source, i),//#7

                    target, //#7

                    table)); //#7

            } //#7

        }

        return target;

    }

 

 

    //stop extract serializeObject

 

    //start extract serializeVariable

 

    private static Element serializeVariable(Class fieldtype,

        Object child,

        Document target,

        Map table)

        throws Exception

    {

        if (child == null) {

            return new Element("null");

        }

        else if (!fieldtype.isPrimitive()) {

            Element reference = new Element("reference");

            if (table.containsKey(child)) {

                reference.setText(table.get(child).toString());

            }

            else {

                reference.setText(Integer.toString(table.size()));

                serializeHelper(child, target, table);

            }

            return reference;

        }

        else {

            Element value = new Element("value");

            value.setText(child.toString());

            return value;

        }

    }

 

 

    //stop extract serializeVariable

 

    //start extract deserializeObject

 

    public static Object deserializeObject(Document source)

        throws Exception

    {

        List objList = source.getRootElement().getChildren();

 

        Map table = new HashMap();

 

        createInstances(table, objList);

 

        assignFieldValues(table, objList);

 

        return table.get("0");

    }

 

 

    //stop extract deserializeObject

 

    //start extract createInstances

 

    private static void createInstances(Map table,

        List objList)

        throws Exception

    {

        for (int i = 0; i < objList.size(); i++) {

            Element oElt = (Element) objList.get(i);

            Class cls = Class.forName(oElt.getAttributeValue("class"));

            Object instance = null;

            if (!cls.isArray()) {

                Constructor c = cls.getDeclaredConstructor(null);

                if (!Modifier.isPublic(c.getModifiers())) {

                    c.setAccessible(true);

                }

                instance = c.newInstance(null);

            }

            else {

                instance = Array.newInstance(cls.getComponentType(), Integer

                    .parseInt(oElt.getAttributeValue("length")));

            }

            table.put(oElt.getAttributeValue("id"), instance);

        }

    }

 

 

    //stop extract createInstances

 

    //start extract assignFieldValues

 

    private static void assignFieldValues(Map table,

        List objList)

        throws Exception

    {

        for (int i = 0; i < objList.size(); i++) {

            Element oElt = (Element) objList.get(i);

            Object instance = table.get(oElt.getAttributeValue("id"));

            List fElts = oElt.getChildren();

            if (!instance.getClass().isArray()) {

                for (int j = 0; j < fElts.size(); j++) {

                    Element fElt = (Element) fElts.get(j);

                    String className = fElt.getAttributeValue("declaringclass");

                    Class fieldDC = Class.forName(className);

                    String fieldName = fElt.getAttributeValue("name");

                    Field f = fieldDC.getDeclaredField(fieldName);

                    if (!Modifier.isPublic(f.getModifiers())) {

                        f.setAccessible(true);

                    }

 

                    Element vElt = (Element) fElt.getChildren().get(0);

                    f.set(instance, deserializeValue(vElt, f.getType(), table));

                }

            }

            else {

                Class comptype = instance.getClass().getComponentType();

                for (int j = 0; j < fElts.size(); j++) {

                    Array.set(instance, j, deserializeValue((Element) fElts.get(j),

                        comptype, table));

                }

            }

        }

    }

 

 

    //stop extract assignFieldValues

 

    //start extract deserializeValue

 

    private static Object deserializeValue(Element vElt,

        Class fieldType,

        Map table)

        throws ClassNotFoundException

    {

        String valtype = vElt.getName();

        if (valtype.equals("null")) {

            return null;

        }

        else if (valtype.equals("reference")) {

            return table.get(vElt.getText());

        }

        else {

            if (fieldType.equals(boolean.class)) {

                if (vElt.getText().equals("true")) {

                    return Boolean.TRUE;

                }

                else {

                    return Boolean.FALSE;

                }

            }

            else if (fieldType.equals(byte.class)) {

                return Byte.valueOf(vElt.getText());

            }

            else if (fieldType.equals(short.class)) {

                return Short.valueOf(vElt.getText());

            }

            else if (fieldType.equals(int.class)) {

                return Integer.valueOf(vElt.getText());

            }

            else if (fieldType.equals(long.class)) {

                return Long.valueOf(vElt.getText());

            }

            else if (fieldType.equals(float.class)) {

                return Float.valueOf(vElt.getText());

            }

            else if (fieldType.equals(double.class)) {

                return Double.valueOf(vElt.getText());

            }

            else if (fieldType.equals(char.class)) {

                return new Character(vElt.getText().charAt(0));

            }

            else {

                return vElt.getText();

            }

        }

    }

    //stop extract deserializeValue

 

}

 

 

abstract class Mopex

{

 

    /**

     * Returns a syntactically correct name for a class object. If the class

     * object represents an array, the proper number of square bracket pairs are

     * appended to the component type.

     *

     * @return java.lang.String

     * @param cls

     *            java.lang.Class

     */

    //start extract classNameToString

    public static String getTypeName(Class cls)

    {

        if (!cls.isArray()) {

            return cls.getName();

        }

        else {

            return getTypeName(cls.getComponentType()) + "[]";

        }

    }

 

 

    //stop extract classNameToString

 

    /**

     * Returns an array of the superclasses of cls.

     *

     * @return java.lang.Class[]

     * @param cls

     *            java.lang.Class

     */

    //start extract getSuperclasses

    public static Class[] getSuperclasses(Class cls)

    {

        int i = 0;

        for (Class x = cls.getSuperclass(); x != null; x = x.getSuperclass())

            i++;

        Class[] result = new Class[i];

        i = 0;

        for (Class x = cls.getSuperclass(); x != null; x = x.getSuperclass())

            result[i++] = x;

        return result;

    }

 

 

    //stop extract getSuperclasses

 

    /**

     * Returns an array of the instance variablies of the the specified class.

     * An instance variable is defined to be a non-static field that is declared

     * by the class or inherited.

     *

     * @return java.lang.Field[]

     * @param cls

     *            java.lang.Class

     */

    //start extract getInstanceVariables

    public static Field[] getInstanceVariables(Class cls)

    {

        List accum = new LinkedList();

        while (cls != null) {

            Field[] fields = cls.getDeclaredFields();

            for (int i = 0; i < fields.length; i++) {

                if (!Modifier.isStatic(fields[i].getModifiers())) {

                    accum.add(fields[i]);

                }

            }

            cls = cls.getSuperclass();

        }

        Field[] retvalue = new Field[accum.size()];

        return (Field[]) accum.toArray(retvalue);

    }

 

 

    //stop extract getInstanceVariables

 

    /**

     * Returns an array of fields that are the declared instance variables of

     * cls. An instance variable is a field that is not static.

     *

     * @return java.lang.reflect.Field[]

     * @param cls

     *            java.lang.Class

     */

    //start extract getDeclaredIVS

    public static Field[] getDeclaredIVs(Class cls)

    {

        Field[] fields = cls.getDeclaredFields();

        // Count the IVs

        int numberOfIVs = 0;

        for (int i = 0; i < fields.length; i++) {

            if (!Modifier.isStatic(fields[i].getModifiers()))

                numberOfIVs++;

        }

        Field[] declaredIVs = new Field[numberOfIVs];

        // Populate declaredIVs

        int j = 0;

        for (int i = 0; i < fields.length; i++) {

            if (!Modifier.isStatic(fields[i].getModifiers()))

                declaredIVs[j++] = fields[i];

        }

        return declaredIVs;

    }

 

 

    //stop extract getDeclaredIVS

 

    /**

     * Return an array of the supported instance variables of this class. A

     * supported instance variable is not static and is either declared or

     * inherited from a superclass.

     *

     * @return java.lang.reflect.Field[]

     * @param cls

     *            java.lang.Class

     */

    //start extract getSupportedIVS

    public static Field[] getSupportedIVs(Class cls)

    {

        if (cls == null) {

            return new Field[0];

        }

        else {

            Field[] inheritedIVs = getSupportedIVs(cls.getSuperclass());

            Field[] declaredIVs = getDeclaredIVs(cls);

            Field[] supportedIVs = new Field[declaredIVs.length + inheritedIVs.length];

            for (int i = 0; i < declaredIVs.length; i++) {

                supportedIVs[i] = declaredIVs[i];

            }

            for (int i = 0; i < inheritedIVs.length; i++) {

                supportedIVs[i + declaredIVs.length] = inheritedIVs[i];

            }

            return supportedIVs;

        }

    }

 

 

    //stop extract getSupportedIVS

 

    /**

     * Returns an array of the methods that are not static.

     *

     * @return java.lang.reflect.Method[]

     * @param cls

     *            java.lang.Class

     */

    //start extract getInstanceMethods

    public static Method[] getInstanceMethods(Class cls)

    {

        List instanceMethods = new ArrayList();

        for (Class c = cls; c != null; c = c.getSuperclass()) {

            Method[] methods = c.getDeclaredMethods();

            for (int i = 0; i < methods.length; i++)

                if (!Modifier.isStatic(methods[i].getModifiers()))

                    instanceMethods.add(methods[i]);

        }

        Method[] ims = new Method[instanceMethods.size()];

        for (int j = 0; j < instanceMethods.size(); j++)

            ims[j] = (Method) instanceMethods.get(j);

        return ims;

    }

 

 

    //stop extract getInstanceMethods

 

    /**

     * Returns an array of methods to which instances of this class respond.

     *

     * @return java.lang.reflect.Method[]

     * @param cls

     *            java.lang.Class

     */

    //start extract getSupportedMethods

    public static Method[] getSupportedMethods(Class cls)

    {

        return getSupportedMethods(cls, null);

    }

 

 

    //stop extract getSupportedMethods

 

    /**

     * This method retrieves the modifiers of a Method without the unwanted

     * modifiers specified in the second parameter. Because this method uses

     * bitwise operations, multiple unwanted modifiers may be specified by

     * bitwise or.

     *

     * @return int

     * @param m

     *            java.lang.Method

     * @param unwantedModifiers

     *            int

     */

    //start extract getModifiersWithout

    public static int getModifiersWithout(Method m,

        int unwantedModifiers)

    {

        int mods = m.getModifiers();

        return (mods ^ unwantedModifiers) & mods;

    }

 

 

    //stop extract getModifiersWithout

 

    /**

     * Returns a Method that has the signature specified by the calling

     * parameters.

     *

     * @return Method

     * @param cls

     *            java.lang.Class

     * @param name

     *            String

     * @param paramTypes

     *            java.lang.Class[]

     */

    //start extract getSupportedMethod

    public static Method getSupportedMethod(Class cls,

        String name,

        Class[] paramTypes)

        throws NoSuchMethodException

    {

        if (cls == null) {

            throw new NoSuchMethodException();

        }

        try {

            return cls.getDeclaredMethod(name, paramTypes);

        } catch (NoSuchMethodException ex) {

            return getSupportedMethod(cls.getSuperclass(), name, paramTypes);

        }

    }

 

 

    //stop extract getSupportedMethod

    /**

     * Returns a Method array of the methods to which instances of the specified

     * respond except for those methods defined in the class specifed by limit

     * or any of its superclasses. Note that limit is usually used to eliminate

     * them methods defined by java.lang.Object.

     *

     * @return Method[]

     * @param cls

     *            java.lang.Class

     * @param limit

     *            java.lang.Class

     */

    //start extract getSupportedMethods

    public static Method[] getSupportedMethods(Class cls,

        Class limit)

    {

        Vector supportedMethods = new Vector();

        for (Class c = cls; c != limit; c = c.getSuperclass()) {

            Method[] methods = c.getDeclaredMethods();

            for (int i = 0; i < methods.length; i++) {

                boolean found = false;

                for (int j = 0; j < supportedMethods.size(); j++)

                    if (equalSignatures(methods[i], (Method) supportedMethods

                        .elementAt(j))) {

                        found = true;

                        break;

                    }

                if (!found)

                    supportedMethods.add(methods[i]);

            }

        }

        Method[] mArray = new Method[supportedMethods.size()];

        for (int k = 0; k < mArray.length; k++)

            mArray[k] = (Method) supportedMethods.elementAt(k);

        return mArray;

    }

 

    //stop extract getSupportedMethods

 

    /**

     * This field is initialized with a method object for the equalSignatures

     * method. This is an optimization in that selectMethods can use this field

     * instead of calling getMethod each time it is called.

     */

 

    //start extract equalSignaturesMethod

    static private Method equalSignaturesMethod;

 

    static {

        Class[] fpl = { Method.class, Method.class };

        try {

            equalSignaturesMethod = Mopex.class.getMethod("equalSignatures", fpl);

        } catch (NoSuchMethodException e) {

            throw new RuntimeException(e);

        }

    }

 

 

    //stop extract equalSignaturesMethod

    /**

     * Determines if the signatures of two method objects are equal. In Java, a

     * signature comprises the method name and the array of of formal parameter

     * types. For two signatures to be equal, the method names must be the same

     * and the formal parameters must be of the same type (in the same order).

     *

     * @return boolean

     * @param m1

     *            java.lang.Method

     * @param m2

     *            java.lang.Method

     */

    //start extract equalSignatures

    public static boolean equalSignatures(Method m1,

        Method m2)

    {

        if (!m1.getName().equals(m2.getName()))

            return false;

        if (!Arrays.equals(m1.getParameterTypes(), m2.getParameterTypes()))

            return false;

        return true;

    }

 

 

    //stop extract equalSignatures

 

    /**

     * Return a string that represents the signature of the specified method.

     *

     * @return String

     * @param m

     *            java.lang.Method

     */

    //start extract signatureToString

    public static String signatureToString(Method m)

    {

        return m.getName() + "(" + formalParametersToString(m.getParameterTypes()) + ")";

    }

 

 

    //stop extract signatureToString

    /**

     * Returns a string that can be used as a formal parameter list for a method

     * that has the parameter types of the specified array.

     *

     * @return String

     * @param pts

     *            java.lang.Class[]

     */

    //start extract formalParametersToString

    public static String formalParametersToString(Class[] pts)

    {

        String result = "";

        for (int i = 0; i < pts.length; i++) {

            result += getTypeName(pts[i]) + " p" + i;

            if (i < pts.length - 1)

                result += ",";

        }

        return result;

    }

 

 

    //stop extract formalParametersToString

    /**

     * Returns a string that is an actual parameter list that matches the formal

     * parameter list produced by formalParametersToString.

     *

     * @return String

     * @param pts

     *            java.lang.Class[]

     */

    //start extract actualParametersToString

    public static String actualParametersToString(Class[] pts)

    {

        String result = "";

        for (int i = 0; i < pts.length; i++) {

            result += "p" + i;

            if (i < pts.length - 1)

                result += ",";

        }

        return result;

    }

 

 

    //stop extract actualParametersToString

 

    /**

     * Returns a String that represents the header for a constructor.

     *

     * @return String

     * @param c

     *            java.lang.Constructor

     */

    //start extract constructorHeaderToString

    public static String headerToString(Constructor c)

    {

        String mods = Modifier.toString(c.getModifiers());

        if (mods.length() == 0)

            return headerSuffixToString(c);

        else

            return mods + " " + headerSuffixToString(c);

    }

 

 

    //stop extract constructorHeaderToString

    /**

     * Returns a String that represents the header suffix for a constructor. The

     * term "header suffix" is not a standard Java term. We use it to mean the

     * Java header without the modifiers.

     *

     * @return String

     * @param c

     *            java.lang.Constructor

     */

    //start extract constructorHeaderToString

    public static String headerSuffixToString(Constructor c)

    {

        String header = signatureToString(c);

        Class[] eTypes = c.getExceptionTypes();

        if (eTypes.length != 0)

            header += " throws " + classArrayToString(eTypes);

        return header;

    }

 

 

    //stop extract constructorHeaderToString

    /**

     * Returns a String that represents the signature for a constructor.

     *

     * @return String

     * @param c

     *            java.lang.Constructor

     */

    //start extract constructorHeaderToString

    public static String signatureToString(Constructor c)

    {

        return c.getName() + "(" + formalParametersToString(c.getParameterTypes()) + ")";

    }

 

 

    //stop extract constructorHeaderToString

 

    /**

     * Returns a String that represents the header of a method.

     *

     * @return String

     * @param m

     *            java.lang.Method

     */

    //start extract headerToString

    public static String headerToString(Method m)

    {

        String mods = Modifier.toString(m.getModifiers());

        if (mods.length() == 0)

            return headerSuffixToString(m);

        else

            return mods + " " + headerSuffixToString(m);

    }

 

 

    //stop extract headerToString

    /**

     * Returns a String that represents the suffix of the header of a method.

     * The suffix of a header is not a standard Java term. We use the term to

     * mean the Java header without the method modifiers.

     *

     * @return String

     * @param m

     *            java.lang.Method

     */

    //start extract headerToString

    public static String headerSuffixToString(Method m)

    {

        String header = getTypeName(m.getReturnType()) + " " + signatureToString(m);

        Class[] eTypes = m.getExceptionTypes();

        if (eTypes.length != 0) {

            header += " throws " + classArrayToString(eTypes);

        }

        return header;

    }

 

 

    //stop extract headerToString

    /**

     * Returns a String that is a comma separated list of the typenames of the

     * classes in the array pts.

     *

     * @return String

     * @param pts

     *            java.lang.Class[]

     */

    //start extract classArrayToString

    public static String classArrayToString(Class[] pts)

    {

        String result = "";

        for (int i = 0; i < pts.length; i++) {

            result += getTypeName(pts[i]);

            if (i < pts.length - 1)

                result += ",";

        }

        return result;

    }

 

 

    //stop extract classArrayToString

 

    /**

     * Turns true if and only if the header suffixes of the two specified

     * methods are equal. The header suffix is defined to be the signature, the

     * return type, and the exception types.

     *

     * @return boolean

     * @param m1

     *            java.lang.Method

     * @param m2

     *            java.lang.Method

     */

    public static boolean equalsHeaderSuffixes(Method m1,

        Method m2)

    {

        if (m1.getReturnType() != m2.getReturnType())

            return false;

        if (!Arrays.equals(m1.getExceptionTypes(), m2.getExceptionTypes()))

            return false;

        return equalSignatures(m1, m2);

    }

 

 

    /**

     * Creates constructor with the signature of c and a new name. It adds some

     * code after generating a super statement to call c. This method is used

     * when generating a subclass of class that declared c.

     *

     * @return String

     * @param c

     *            java.lang.Constructor

     * @param name

     *            String

     * @param code

     *            String

     */

    //start extract createRenamedConstructor

    public static String createRenamedConstructor(Constructor c,

        String name,

        String code)

    {

        Class[] pta = c.getParameterTypes();

        String fpl = formalParametersToString(pta);

        String apl = actualParametersToString(pta);

        Class[] eTypes = c.getExceptionTypes();

        String result = name + "(" + fpl + ")/n";

        if (eTypes.length != 0)

            result += "    throws " + classArrayToString(eTypes) + "/n";

        result += "{/n    super(" + apl + ");/n" + code + "}/n";

        return result;

    }

 

 

    //stop extract createRenamedConstructor

 

    /**

     * Returns a String that is formatted as a Java method declaration having

     * the same header as the specified method but with the code parameter

     * substituted for the method body.

     *

     * @return String

     * @param m

     *            java.lang.Method

     * @param code

     *            String

     */

    //start extract createReplacementMethod

    public static String createReplacementMethod(Method m,

        String code)

    {

        Class[] pta = m.getParameterTypes();

        String fpl = formalParametersToString(pta);

        Class[] eTypes = m.getExceptionTypes();

        String result = m.getName() + "(" + fpl + ")/n";

        if (eTypes.length != 0)

            result += "    throws " + classArrayToString(eTypes) + "/n";

        result += "{/n" + code + "}/n";

        return result;

    }

 

 

    //stop extract createReplacementMethod

 

    /**

     * Returns a string for a cooperative override of the method m. That is, The

     * string has the same return type and signature as m but the body has a

     * super call that is sandwiched between the strings code1 and code2.

     *

     * @return String

     * @param m

     *            java.lang.Method

     * @param code1

     *            String

     * @param code2

     *            String

     */

    //start extract createCooperativeWrapper

    public static String createCooperativeWrapper(Method m,

        String code1,

        String code2)

    {

        Class[] pta = m.getParameterTypes();

        Class retType = m.getReturnType();

        String fpl = formalParametersToString(pta);

        String apl = actualParametersToString(pta);

        Class[] eTypes = m.getExceptionTypes();

        String result = retType.getName() + " " + m.getName() + "(" + fpl + ")/n";

        if (eTypes.length != 0)

            result += "    throws " + classArrayToString(eTypes) + "/n";

        result += "{/n" + code1 + "    ";

        if (retType != void.class)

            result += retType.getName() + " cooperativeReturnValue = ";

        result += "super." + m.getName() + "(" + apl + ");/n";

        result += code2;

        if (retType != void.class)

            result += "    return cooperativeReturnValue;/n";

        result += "}/n";

        return result;

    }

 

 

    /**

     * Returns the method object for the unique method named mName. If no such

     * method exists, a null is returned. If there is more than one such method,

     * a runtime exception is thrown.

     *

     * @return Method

     * @param cls

     *            java.lang.Class

     * @param mName

     *            String

     */

    public static Method getUniquelyNamedMethod(Class cls,

        String mName)

    {

        Method result = null;

        Method[] mArray = cls.getDeclaredMethods();

        for (int i = 0; i < mArray.length; i++)

            if (mName.equals(mArray[i].getName())) {

                if (result == null)

                    result = mArray[i];

                else

                    throw new RuntimeException("name is not unique");

            }

        return result;

    }

 

 

    /**

     * Finds the first (from the bottom of the inheritance hierarchy) field with

     * the specified name. Note that Class.getField returns only public fields.

     *

     * @return Field

     * @param cls

     *            java.lang.Class

     * @param name

     *            String

     */

    //start extract findField

    public static Field findField(Class cls,

        String name)

        throws NoSuchFieldException

    {

        if (cls != null) {

            try {

                return cls.getDeclaredField(name);

            } catch (NoSuchFieldException e) {

                return findField(cls.getSuperclass(), name);

            }

        }

        else {

            throw new NoSuchFieldException();

        }

    }

}

 

通过上面的源代码我们可以看到这个类主要是运用反射机制,将被序列化的对象分解到8Java基本类型后,再将数据存入到xml文件中。反序列化则是根据xml中记录的class类型使用反射机制自动构造这个对象,同时将来的数据填充到正确的变量上去。通过这样完成反序列化。

你可能感兴趣的:(java,xml,exception,object,String,Class)