序列化对象到Xml文件以及反序列话Xml文件到对象(序列化数据到8个Java原型类型)
来源:互联网 发布:人工智能观后感500字 编辑:程序博客网 时间:2024/05/08 15:41
序列化对象到Xml文件以及反序列化Xml文件到对象
----(持续序列化对象到只含有属于8个Java基本类型的变量)
在前面一篇文章《Java序列化中SUID问题的完美解决方案》中,通过用新对象的SUID替换原对象的SUID,使得经过改动后的对象无法反序列化原来对象数据的问题得到解决。但是这个方法也有它的不足地方,就是如果一个对象没有实现Serializable接口的话,我们就无法实现序列化这个对象,而且一般经过序列化后产生的数据对用户来说无法看懂,因此我们有必要自己实现一种序列化方法,将对象中的数据序列化到用户看得懂的Xml文件中,而且序列化后的Xml文件中的数据全部都是Java的8种基本类型。也就是说,序列化对象的时候,如果对象的变量类型属于8种Java基本类型(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方法完成将任意一个对象序列化为一个JDOM的Document对象,然后使用方法createFile方法将Document内容输出到一个Xml文件中去。
反序列化的步骤类似:
Document doc =loadFile(fileName);
Object object =XmlSerializerUtil.deserializeObject(doc);
HelloWorld1hello2 = (HelloWorld1) object;
首先将一个Xml文件读入到JDOM的Document对象中去,然后再调用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();
}
}
}
通过上面的源代码我们可以看到这个类主要是运用反射机制,将被序列化的对象分解到8种Java基本类型后,再将数据存入到xml文件中。反序列化则是根据xml中记录的class类型使用反射机制自动构造这个对象,同时将来的数据填充到正确的变量上去。通过这样完成反序列化。
- 序列化对象到Xml文件以及反序列话Xml文件到对象(序列化数据到8个Java原型类型)
- 类对象序列化(反序列化)成xml文件或者二进制文件到本地文件方法
- 简述Xml.Serialization如何序列化对象到XML文件
- 使用XStream将对象序列化到XML以及从XML反序列化到对象
- java序列化/反序列化对象到mysql
- XML序列化对象到字符串,从字符串反序列化
- C#实现序列化对象到XML文档与反序列化
- xstream ---java序列化到xml,xml反序列化到java对象(一)
- 序列化对象为xml文件,将xml文件反序列化为对象
- 序列化对象到文件
- 如何将多个对象序列化到同一个文件和反序列化
- 对象序列化反序列化为xml
- 序列化和反序列化对象到数据库
- 怎么给这个xml文件建立对象,以便使对象和xml文件序列化和反序列化
- 图像文件序列化到XML文件中
- java序列化多次序列化到同一个文件及反序列化的问题[转载]
- 序列化对象为xml,从xml反序列化
- 序列化反序列化对象XML文件写入Sample,简单但是有代表性
- test
- 运动补偿
- 记录几个脚本(弹出文件选择框、页面回滚时回到滚动条以前的位置)
- __stdcall 和_cdecl 使用
- 软件测试的就业前景——中国IT界的黄金职业
- 序列化对象到Xml文件以及反序列话Xml文件到对象(序列化数据到8个Java原型类型)
- Loadrunner,Jmeter
- 周末,老公不能陪我!
- C++builder 中的多线程
- Java华为面试题
- fatal error C1853: 'Debug/***.pch' is not a precompiled header file created with this compiler
- shell function in vb
- 安装启动
- Net远程管理实验