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

来源:互联网 发布:人工智能观后感500字 编辑:程序博客网 时间:2024/05/08 15:41

序列化对象到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类:

importjava.io.File;

importjava.io.FileInputStream;

importjava.io.FileOutputStream;

importjava.io.IOException;

 

importjunit.framework.TestCase;

 

importorg.apache.tools.ant.Project;

importorg.jdom.Document;

importorg.jdom.input.SAXBuilder;

importorg.jdom.output.Format;

importorg.jdom.output.XMLOutputter;

 

public classXmlSerializerUtilTest extends TestCase {

      

       public XmlSerializerUtilTest(String name){

              super(name);

       }

      

       private final StringfileName="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 = newXMLOutputter(); // 生成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, newFileOutputStream(fileName));

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

        } catch (IOException ex) {

            System.out.println("the causeof 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("failsto open a file called " + fileName);

            } else {

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

                SAXBuilder sb = newSAXBuilder();

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

            }

        } catch (Exception e) {

            System.out.println("fails toopen 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){

           XMLOutputterxmlOut = 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 textformat.

            xmlOut.output(doc, System.out);

         

        } catch (IOException ex) {

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

        }

    }

}

 

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

HelloWorld1hello1 = new HelloWorld1();

Documentdocument1 = XmlSerializerUtil.serializeObject(hello1);

createFile(document1,fileName);

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

反序列化的步骤类似:

Document doc =loadFile(fileName);

Object object =XmlSerializerUtil.deserializeObject(doc);

HelloWorld1hello2 = (HelloWorld1) object;

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

其中HelloWorld1类如下:

importjava.io.Serializable;

public classHelloWorld1

{

    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>

    <objectclass="HelloWorld1" id="0">

       <fieldname="m_sName" declaringclass=" HelloWorld1">

           <reference>1</reference>

       </field>

    </object>

    <objectclass="java.lang.String" id="1">

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

           <reference>2</reference>

       </field>

       <fieldname="offset" declaringclass="java.lang.String">

           <value>0</value>

       </field>

       <fieldname="count" declaringclass="java.lang.String">

           <value>5</value>

       </field>

       <fieldname="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类是怎么去实现序列化和反序列化的:

importjava.lang.reflect.Array;

importjava.lang.reflect.Constructor;

importjava.lang.reflect.Field;

importjava.lang.reflect.Method;

importjava.lang.reflect.Modifier;

importjava.util.ArrayList;

import java.util.Arrays;

importjava.util.HashMap;

importjava.util.IdentityHashMap;

importjava.util.LinkedList;

importjava.util.List;

importjava.util.Map;

importjava.util.Vector;

 

importorg.jdom.Document;

importorg.jdom.Element;

 

 

public classXmlSerializerUtil

{

 

    //start extract serializeObject

 

    public static DocumentserializeObject(Object source)

        throws Exception

    {

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

            new IdentityHashMap());

    }

 

 

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

        throws Exception

    {

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

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

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

 

        Element oElt = newElement("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 = newElement("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 ElementserializeVariable(Class fieldtype,

        Object child,

        Document target,

        Map table)

        throws Exception

    {

        if (child == null) {

            return newElement("null");

        }

        else if (!fieldtype.isPrimitive()) {

            Element reference = newElement("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 = newElement("value");

            value.setText(child.toString());

            return value;

        }

    }

 

 

    //stop extract serializeVariable

 

    //start extract deserializeObject

 

    public static ObjectdeserializeObject(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(Maptable,

        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(Maptable,

        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 ObjectdeserializeValue(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)) {

                returnByte.valueOf(vElt.getText());

            }

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

                returnShort.valueOf(vElt.getText());

            }

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

                returnInteger.valueOf(vElt.getText());

            }

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

                returnLong.valueOf(vElt.getText());

            }

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

                returnFloat.valueOf(vElt.getText());

            }

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

                returnDouble.valueOf(vElt.getText());

            }

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

                return newCharacter(vElt.getText().charAt(0));

            }

            else {

                return vElt.getText();

            }

        }

    }

    //stop extract deserializeValue

 

}

 

 

abstract classMopex

{

 

    /**

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

     * object represents an array, the propernumber 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 {

            returngetTypeName(cls.getComponentType()) + "[]";

        }

    }

 

 

    //stop extract classNameToString

 

    /**

     * Returns an array of the superclasses ofcls.

     *

     * @return java.lang.Class[]

     * @param cls

     *            java.lang.Class

     */

    //start extract getSuperclasses

    public static Class[] getSuperclasses(Classcls)

    {

        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 instancevariablies of the the specified class.

     * An instance variable is defined to be anon-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 = newField[accum.size()];

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

    }

 

 

    //stop extract getInstanceVariables

 

    /**

     * Returns an array of fields that are thedeclared instance variables of

     * cls. An instance variable is a fieldthat is not static.

     *

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

     * @param cls

     *            java.lang.Class

     */

    //start extract getDeclaredIVS

    public static Field[] getDeclaredIVs(Classcls)

    {

        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 = newField[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 supportedinstance variables of this class. A

     * supported instance variable is notstatic 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(Classcls)

    {

        if (cls == null) {

            return new Field[0];

        }

        else {

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

            Field[] declaredIVs =getDeclaredIVs(cls);

            Field[] supportedIVs = newField[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 arenot 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 = newMethod[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 whichinstances 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 aMethod without the unwanted

     * modifiers specified in the secondparameter. Because this method uses

     * bitwise operations, multiple unwantedmodifiers may be specified by

     * bitwise or.

     *

     * @return int

     * @param m

     *            java.lang.Method

     * @param unwantedModifiers

     *            int

     */

    //start extract getModifiersWithout

    public static intgetModifiersWithout(Method m,

        int unwantedModifiers)

    {

        int mods = m.getModifiers();

        return (mods ^ unwantedModifiers) &mods;

    }

 

 

    //stop extract getModifiersWithout

 

    /**

     * Returns a Method that has the signaturespecified by the calling

     * parameters.

     *

     * @return Method

     * @param cls

     *            java.lang.Class

     * @param name

     *            String

     * @param paramTypes

     *            java.lang.Class[]

     */

    //start extract getSupportedMethod

    public static MethodgetSupportedMethod(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 towhich instances of the specified

     * respond except for those methods definedin the class specifed by limit

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

     * them methods defined byjava.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 = newMethod[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 methodobject for the equalSignatures

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

     * instead of calling getMethod each timeit is called.

     */

 

    //start extract equalSignaturesMethod

    static private MethodequalSignaturesMethod;

 

    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 twomethod objects are equal. In Java, a

     * signature comprises the method name andthe 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 thesame type (in the same order).

     *

     * @return boolean

     * @param m1

     *            java.lang.Method

     * @param m2

     *            java.lang.Method

     */

    //start extract equalSignatures

    public static booleanequalSignatures(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 thesignature of the specified method.

     *

     * @return String

     * @param m

     *            java.lang.Method

     */

    //start extract signatureToString

    public static StringsignatureToString(Method m)

    {

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

    }

 

 

    //stop extract signatureToString

    /**

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

     * that has the parameter types of thespecified array.

     *

     *@return String

     * @param pts

     *            java.lang.Class[]

     */

    //start extract formalParametersToString

    public static StringformalParametersToString(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 actualparameter list that matches the formal

     * parameter list produced byformalParametersToString.

     *

     * @return String

     * @param pts

     *            java.lang.Class[]

     */

    //start extract actualParametersToString

    public static StringactualParametersToString(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 theheader for a constructor.

     *

     * @return String

     * @param c

     *            java.lang.Constructor

     */

    //start extract constructorHeaderToString

    public static StringheaderToString(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 theheader suffix for a constructor. The

     * term "header suffix" is not astandard 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 StringheaderSuffixToString(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 thesignature for a constructor.

     *

     * @return String

     * @param c

     *            java.lang.Constructor

     */

    //start extract constructorHeaderToString

    public static String signatureToString(Constructorc)

    {

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

    }

 

 

    //stop extract constructorHeaderToString

 

    /**

     * Returns a String that represents theheader of a method.

     *

     * @return String

     * @param m

     *            java.lang.Method

     */

    //start extract headerToString

    public static String headerToString(Methodm)

    {

        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 thesuffix of the header of a method.

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

     * mean the Java header without the methodmodifiers.

     *

     * @return String

     * @param m

     *            java.lang.Method

     */

    //start extract headerToString

    public static StringheaderSuffixToString(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 commaseparated list of the typenames of the

     * classes in the array pts.

     *

     * @return String

     * @param pts

     *            java.lang.Class[]

     */

    //start extract classArrayToString

    public static StringclassArrayToString(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 headersuffixes of the two specified

     * methods are equal. The header suffix isdefined 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 booleanequalsHeaderSuffixes(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 signatureof c and a new name. It adds some

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

     * when generating a subclass of class thatdeclared c.

     *

     * @return String

     * @param c

     *            java.lang.Constructor

     * @param name

     *            String

     * @param code

     *            String

     */

    //start extract createRenamedConstructor

    public static StringcreateRenamedConstructor(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 aJava method declaration having

     * the same header as the specified methodbut with the code parameter

     * substituted for the method body.

     *

     * @return String

     * @param m

     *            java.lang.Method

     * @param code

     *            String

     */

    //start extract createReplacementMethod

    public static StringcreateReplacementMethod(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 cooperativeoverride of the method m. That is, The

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

     * super call that is sandwiched betweenthe strings code1 and code2.

     *

     * @return String

     * @param m

     *            java.lang.Method

     * @param code1

     *            String

     * @param code2

     *            String

     */

    //start extract createCooperativeWrapper

    public static String createCooperativeWrapper(Methodm,

        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 uniquemethod named mName. If no such

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

     * a runtime exception is thrown.

     *

     * @return Method

     * @param cls

     *            java.lang.Class

     * @param mName

     *            String

     */

    public static MethodgetUniquelyNamedMethod(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 newRuntimeException("name is not unique");

            }

        return result;

    }

 

 

    /**

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

     * the specified name. Note thatClass.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 {

                returncls.getDeclaredField(name);

            } catch (NoSuchFieldException e) {

                returnfindField(cls.getSuperclass(), name);

            }

        }

        else {

            throw new NoSuchFieldException();

        }

    }

}

 

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

原创粉丝点击