﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-9910-随笔分类-java</title><link>http://www.blogjava.net/sdyjmc/category/17746.html</link><description>九九归一:十年一剑</description><language>zh-cn</language><lastBuildDate>Thu, 26 Apr 2007 09:37:53 GMT</lastBuildDate><pubDate>Thu, 26 Apr 2007 09:37:53 GMT</pubDate><ttl>60</ttl><item><title>ClassLoader.getResourceAsStream(name);路径问题</title><link>http://www.blogjava.net/sdyjmc/archive/2007/04/26/113766.html</link><dc:creator>弹弓</dc:creator><author>弹弓</author><pubDate>Thu, 26 Apr 2007 05:54:00 GMT</pubDate><guid>http://www.blogjava.net/sdyjmc/archive/2007/04/26/113766.html</guid><wfw:comment>http://www.blogjava.net/sdyjmc/comments/113766.html</wfw:comment><comments>http://www.blogjava.net/sdyjmc/archive/2007/04/26/113766.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdyjmc/comments/commentRss/113766.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdyjmc/services/trackbacks/113766.html</trackback:ping><description><![CDATA[InputStream in = getClass().getResourceAsStream('/'+"spring-beans.dtd"); 表示从classs目录下面的找文件,文件放在src下面就可以了.<br>InputStream in = getClass().getResourceAsStream("spring-beans.dtd"); 表示从当前classs下面的路径找文件<br>如果是在com.a.b.c.d.Test这个class就表示spring-beans.dtd要放在目录src\com\a\b\c\d下.<br>
<br>SAXBuilder builder = new SAXBuilder();<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; EntityResolver resolver = new EntityResolver() {<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; public InputSource resolveEntity(String publicId,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; String systemId) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (publicId.equals("-//SPRING//DTD BEAN//EN")) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; InputStream in = getClass().getResourceAsStream(<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; '/'+"spring-beans.dtd");<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return new InputSource(in);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return null;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; };<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; builder.setEntityResolver(resolver);<br><br>这样才能解决dtd的本地查找问题.<br><br><img src ="http://www.blogjava.net/sdyjmc/aggbug/113766.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdyjmc/" target="_blank">弹弓</a> 2007-04-26 13:54 <a href="http://www.blogjava.net/sdyjmc/archive/2007/04/26/113766.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> java.lang.Class.getSimpleName() Exception</title><link>http://www.blogjava.net/sdyjmc/archive/2007/04/11/109848.html</link><dc:creator>弹弓</dc:creator><author>弹弓</author><pubDate>Wed, 11 Apr 2007 03:21:00 GMT</pubDate><guid>http://www.blogjava.net/sdyjmc/archive/2007/04/11/109848.html</guid><wfw:comment>http://www.blogjava.net/sdyjmc/comments/109848.html</wfw:comment><comments>http://www.blogjava.net/sdyjmc/archive/2007/04/11/109848.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdyjmc/comments/commentRss/109848.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdyjmc/services/trackbacks/109848.html</trackback:ping><description><![CDATA[在试用Tapestry5.0.3的时候发现这个问题:<br>WARN [(jetty.servlet.ServletHandler)] Error for /wfmanager/<br>java.lang.NoSuchMethodError: java.lang.Class.getSimpleName()Ljava/lang/String;<br>&nbsp;&nbsp;&nbsp; at org.apache.tapestry.ioc.internal.util.InternalUtils.asString(InternalUtils.java:91)<br>&nbsp;&nbsp;&nbsp; at org.apache.tapestry.ioc.services.MethodLocation.toString(MethodLocation.java:50)<br>&nbsp;&nbsp;&nbsp; at org.apache.tapestry.ioc.internal.util.InternalUtils.asString(InternalUtils.java:67)<br>&nbsp;&nbsp;&nbsp; at org.apache.tapestry.ioc.internal.ServiceBuilderMethodInvoker.methodId(ServiceBuilderMethodInvoker.java:82)<br>我的jdk是J2sdk1.5.0的后来换成j2sdk1.5.10就可以了.所以说j2sdk.15不全是都支持getSimpleName()这个方法的.<br><br><br><img src ="http://www.blogjava.net/sdyjmc/aggbug/109848.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdyjmc/" target="_blank">弹弓</a> 2007-04-11 11:21 <a href="http://www.blogjava.net/sdyjmc/archive/2007/04/11/109848.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Extra bytes at the end of a .class file</title><link>http://www.blogjava.net/sdyjmc/archive/2007/02/28/101091.html</link><dc:creator>弹弓</dc:creator><author>弹弓</author><pubDate>Wed, 28 Feb 2007 03:24:00 GMT</pubDate><guid>http://www.blogjava.net/sdyjmc/archive/2007/02/28/101091.html</guid><wfw:comment>http://www.blogjava.net/sdyjmc/comments/101091.html</wfw:comment><comments>http://www.blogjava.net/sdyjmc/archive/2007/02/28/101091.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdyjmc/comments/commentRss/101091.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdyjmc/services/trackbacks/101091.html</trackback:ping><description><![CDATA[j2sdk1.6 不允许多余的byte存在于class文件中。而j2sdk1.5就允许。<br /><img src ="http://www.blogjava.net/sdyjmc/aggbug/101091.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdyjmc/" target="_blank">弹弓</a> 2007-02-28 11:24 <a href="http://www.blogjava.net/sdyjmc/archive/2007/02/28/101091.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OO失败的地方</title><link>http://www.blogjava.net/sdyjmc/archive/2006/12/27/90348.html</link><dc:creator>弹弓</dc:creator><author>弹弓</author><pubDate>Wed, 27 Dec 2006 09:18:00 GMT</pubDate><guid>http://www.blogjava.net/sdyjmc/archive/2006/12/27/90348.html</guid><wfw:comment>http://www.blogjava.net/sdyjmc/comments/90348.html</wfw:comment><comments>http://www.blogjava.net/sdyjmc/archive/2006/12/27/90348.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdyjmc/comments/commentRss/90348.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdyjmc/services/trackbacks/90348.html</trackback:ping><description><![CDATA[  看到进来大家都在讨论“Java将死”特别是<span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Trustno1 的言论，</span>猛然领悟到为什么现在有这么多的FrameWork，或许这些裹脚布就是大厨们的必修功课，可是一旦编译器来完成这些工作，能够提供“指那打那的功能”那么“失业青年”也能够完成现在大厨的工作。<br />
如果Java在下一个版本不提供“支那打那”的功能，那么ruby就会替代Java。OO提供了太多没有用的功能。<br /><br />
果然JRuby出现了：<br />
http://www.javaeye.com/article/24173<br /><br />
http://lightyror.blogspot.com/search/label/jruby<br /><br />
有幸能目睹IT新一门语言的诞生幸甚至哉。<br /><br />
http://jruby.sourceforge.net/<br /><img src ="http://www.blogjava.net/sdyjmc/aggbug/90348.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdyjmc/" target="_blank">弹弓</a> 2006-12-27 17:18 <a href="http://www.blogjava.net/sdyjmc/archive/2006/12/27/90348.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Class作为Hash索引的隐藏问题</title><link>http://www.blogjava.net/sdyjmc/archive/2006/12/20/89131.html</link><dc:creator>弹弓</dc:creator><author>弹弓</author><pubDate>Wed, 20 Dec 2006 12:35:00 GMT</pubDate><guid>http://www.blogjava.net/sdyjmc/archive/2006/12/20/89131.html</guid><wfw:comment>http://www.blogjava.net/sdyjmc/comments/89131.html</wfw:comment><comments>http://www.blogjava.net/sdyjmc/archive/2006/12/20/89131.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdyjmc/comments/commentRss/89131.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdyjmc/services/trackbacks/89131.html</trackback:ping><description><![CDATA[不同classloader加载的class造成isAnnotationPresent失效<br /><br />
@ComponentClass<br />
public class Home {<br />
}<br />
Class clazz = loader.loadClass("Home");    //loader 和现在运行的classLoader不是相同的。<br />
flag = clazz.isAnnotationPresent(ComponentClass.class);//返回false<br />
原因:<br />
Class.clss<br />
 public boolean isAnnotationPresent(<br />
        Class&lt;? extends Annotation&gt; annotationClass) {<br />
        if (annotationClass == null)<br />
            throw new NullPointerException();<br /><br /><div align="center">        return getAnnotation(annotationClass) != null;<br /></div>
    }<br /><br /><br />
public &lt;A extends Annotation&gt; A getAnnotation(Class&lt;A&gt; annotationClass) {<br />
        if (annotationClass == null)<br />
            throw new NullPointerException();<br /><br />
        initAnnotationsIfNecessary();<br />
        return (A) annotations.get(annotationClass);<br />
    }<br />
private transient Map&lt;Class, Annotation&gt; annotations;<br /><br />
而不同的ClassLoader 加载的ComponentClass不是同一个对象，所以用Class作为id不合适，应该使用String。<br />
解决办法：<br /><br />
ComponentClass.class也使用loader加载这样才能保证一致性。<br />
banq详细的解答了这个问题：<br />
http://www.jdon.com/jive/article.jsp?forum=91&amp;thread=15456<br /><br />Classloader存在下面问题：<br />
在一个JVM中可能存在多个ClassLoader，每个ClassLoader拥有自己的
NameSpace。一个ClassLoader只能拥有一个class对象类型的实例，但是不同的ClassLoader可能拥有相同的class对象
实例，这时可能产生致命的问题。如ClassLoaderA，装载了类A的类型实例A1，而ClassLoaderB，也装载了类A的对象实例A2。逻辑
上讲A1=A2，但是由于A1和A2来自于不同的ClassLoader，它们实际上是完全不同的，如果A中定义了一个静态变量c，则c在不同的
ClassLoader中的值是不同的。<br /><br />
Thread{<br />
            ClassLoader cl = Thread.currentThread().getContextClassLoader();<br />
            URL[] urls = ...<br />
            ClassLoader ncl = new URLClassLoader(urls, cl);//构造新的<br />
            Thread.currentThread().setContextClassLoader(ncl);<br />
            do do do do;<br />
            Thread.currentThread().setContextClassLoader(cl);//执行完恢复<br />
}<br /><img src ="http://www.blogjava.net/sdyjmc/aggbug/89131.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdyjmc/" target="_blank">弹弓</a> 2006-12-20 20:35 <a href="http://www.blogjava.net/sdyjmc/archive/2006/12/20/89131.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>『转贴』比较Eclipse与Mozilla中的COM/XPCOM Java Wrapper技术</title><link>http://www.blogjava.net/sdyjmc/archive/2006/12/04/85409.html</link><dc:creator>弹弓</dc:creator><author>弹弓</author><pubDate>Mon, 04 Dec 2006 09:19:00 GMT</pubDate><guid>http://www.blogjava.net/sdyjmc/archive/2006/12/04/85409.html</guid><wfw:comment>http://www.blogjava.net/sdyjmc/comments/85409.html</wfw:comment><comments>http://www.blogjava.net/sdyjmc/archive/2006/12/04/85409.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdyjmc/comments/commentRss/85409.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdyjmc/services/trackbacks/85409.html</trackback:ping><description><![CDATA[
		<b>http://liumspace.spaces.live.com/blog/cns!bc24129fc2e42afd!122.entry<br /><br /></b>
		<h3>JavaXPCOM</h3>
JavaXPCOM基于一套与Eclipse
SWT不同的思路。在JavaXPCOM中，每一个XPCOM interface有一个对应的Java interface，注意这里是Java
interface，而不是Java class。那么，在JavaXPCOM中怎么生成一个XPCOM对象的Java
wrapper呢？在JavaXPCOM中，巧妙地使用了reflection。对每一个XPCOM对象，会生成一个<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/reflect/Proxy.html"><u><font color="#0000ff">Proxy </font></u></a>来作为Java wrapper，这个Proxy对象实现XPCOM对象所实现的interface。然后这个Proxy把Java interface中的方法调用再delegate到一个JavaXPCOM提供的<a href="http://lxr.mozilla.org/seamonkey/source/extensions/java/xpcom/XPCOMJavaProxy.java"><u><font color="#0000ff">XPCOMJavaProxy</font></u></a>（实现<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/reflect/InvocationHandler.html"><u><font color="#0000ff">InvocationHandler</font></u></a>）上。<br /><br />
这
里有几个问题：1。系统根据一个XPCOM对象的指针，怎么知道这个XPCOM对象实现了什么XPCOM接口？再怎么根据这个XPCOM接口找到对应的
Java interface来生成Proxy？2。XPCOMJavaProxy怎么把一个Java调用再映射到底层的XPCOM调用上？<br /><br />
JavaXPCOM是这样实现的：<br /><ol><li>对每一个XPCOM对象的指针，知道其实现的interface的IID。</li><li>使用<a href="http://lxr.mozilla.org/seamonkey/source/xpcom/reflect/xptinfo/public/nsIInterfaceInfoManager.idl"><u><font color="#0000ff">nsIInterfaceInfoManager</font></u></a>来reflect 这个IID，得到这个interface的meta data（<a href="http://lxr.mozilla.org/seamonkey/source/xpcom/reflect/xptinfo/public/nsIInterfaceInfo.idl"><u><font color="#0000ff">nsIInterfaceInfo</font></u></a>）</li><li>将这个XPCOM对象的指针及nsIInterfaceInfo组合在一起，放在一个JavaXPCOMInterface的数据结构里。</li><li>用这个JavaXPCOMInterface结构的指针来构建XPCOMJavaProxy（java
wrapper）。构建XPCOMJavaProxy对象时（XPCOMJavaProxy#createProxy(Class
aInterface, long aXPCOMInterface)）有两个参数，第一个为这个proxy实现的Java
interface。这个Java interface的名字由"org.mozilla.xpcom" + (XPCOM interface
name)得来。</li><li>当XPCOMJavaProxy上的方法被调用时，native
code会得到方法名、参数数组以及JavaXPCOMInterface的指针。从JavaXPCOMInterface可以得到
nsIInterfaceInfo，通过nsIInterface里所包含的meta data，可以得到这个方法在virtual
table中的位置。同时meta
data还会包含信息说明每个参数的数据类型，根据这个信息，可以把每个参数marshall成一个nsXPTCVariant结构。</li><li>通过<a href="http://www.mozilla.org/scriptable/xptcall-faq.html"><u><font color="#0000ff">xptcall</font></u></a>，就可以完成对virtual table中的方法的调用。</li><li>对方法调用的结果，可以再根据meta
data来unmarshall成Java对象。如果某个out参数或return参数是一个XPCOM对象，在meta
data中会描述这个参数的interface的IID，那么又可以象第一步一样来对其生成Java wrapper（XPCOMJavaProxy）（<a href="http://lxr.mozilla.org/seamonkey/source/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp#706"><u><font color="#0000ff">nsJavaXPCOMBindingUtils.cpp#GetNewOrUsedJavaObject</font></u></a>）。</li></ol>
当然，实际的实现更复杂，比如说有一个global table来记录Java wrapper与native的JavaXPCOMInterface之间的关系以避免不必要的多次为同一XPCOM对象建立Java wrapper等。<br /><div><h2>在Java中实现COM/XPCOM组件（component）</h2></div><div>前面讨论了怎么从Java中调用COM/XPCOM中的组件，接下来讨论怎么用Java语言来实现COM/XPCOM组件。<br /><br /><br /><h3>JavaXPCOM</h3><div> JavaXPCOM中的支持还是依赖了type
information，这是有了这个依赖，JavaXPCOM中实现XPCOM组件要容易得多。在JavaXPCOM中，只需要这个Java对象实现了
所需要实现的XPCOM interface所对应的Java interface即可。<br /><ol><li>当一个Java object作为参数传给某个XPCOM方法时，native code会通过这个方法的meta data，知道这个参数应该是一个XPCOM对象。</li><li>native code会检查这个Java object是不是一个Java wrapper，如果是，那么可以直接从这个Java wrapper知道它所wrap的XPCOM对象。</li><li>接下来会检查是不是已经给这个Java object生成过stub，如果没有则生成一个<a href="http://lxr.mozilla.org/seamonkey/source/extensions/java/xpcom/nsJavaXPTCStub.h"><u><font color="#0000ff">nsJavaXPTCStub</font></u></a>。nsJavaXPTCStub
会根据meta data生成virtual table，而且当virtual table中的方法被调用时，会根据meta
data知道被调用方法的名字，再根据这个名字到Java object中通过reflect找到对应的Java方法并调用它。</li></ol>另外JavaXPCOM的实现中还实现了reference management，这样在Java code中不再需要去实现如AddRef/Release，系统已经都管理好了。<br /><br /><br /><div id="msgcns!bc24129fc2e42afd!122"><h2>JavaXPCOM</h2>优点：<br /><ol><li>每个XPCOM interface对应到Java中还是interface。</li><li>支持Java的garbase collection。在XPCOMJavaProxy中，重载了finalize()方法，所以Java programmer不需要再去调用Release。</li><li>增加新的XPCOM interface容易。只需在org.mozilla.xpcom这个package中增加相应的Java interface即可。</li><li>Java interface可以通过工具自动生成。</li><li>用Java实现XPCOM组件非常简单。<br /></li></ol>缺点：<br /><ol><li>由于实现依赖nsIInterfaceInfoManager，也就依赖<a href="http://www.mozilla.org/scriptable/typelib_file.html"><u><font color="#0000ff">typelib</font></u></a>。这样一来，方法调用不能象Eclipse SWT中一样直接转换为virtual table调用，效率要明显低一些。另外，只能支持那些支持typelib的interface。</li><li>虽然增加新的XPCOM interface容易，但这个interface必须放在org.mozilla.xpcom这个package中，不适合第三方扩充。</li></ol></div><table border="0" cellspacing="0"><tbody><tr height="8"><td><br /></td></tr></tbody></table><br /></div><br /></div><br /><img src ="http://www.blogjava.net/sdyjmc/aggbug/85409.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdyjmc/" target="_blank">弹弓</a> 2006-12-04 17:19 <a href="http://www.blogjava.net/sdyjmc/archive/2006/12/04/85409.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>神奇的XStream</title><link>http://www.blogjava.net/sdyjmc/archive/2006/11/26/83618.html</link><dc:creator>弹弓</dc:creator><author>弹弓</author><pubDate>Sun, 26 Nov 2006 07:27:00 GMT</pubDate><guid>http://www.blogjava.net/sdyjmc/archive/2006/11/26/83618.html</guid><wfw:comment>http://www.blogjava.net/sdyjmc/comments/83618.html</wfw:comment><comments>http://www.blogjava.net/sdyjmc/archive/2006/11/26/83618.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdyjmc/comments/commentRss/83618.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdyjmc/services/trackbacks/83618.html</trackback:ping><description><![CDATA[我尝试着用它来保存继承了Externalizeable的java类，可是没有成功。<br />
import java.io.Externalizable;<br />
import java.io.IOException;<br />
import java.io.ObjectInput;<br />
import java.io.ObjectOutput;<br /><br />
public class Person implements Externalizable{<br />
    private String name ;<br />
    private int sex;<br />
    private Person son;<br />
    <br />
    <br />
    public String getName() {<br />
        return name;<br />
    }<br />
    public void setName(String name) {<br />
        this.name = name;<br />
    }<br />
    public int getSex() {<br />
        return sex;<br />
    }<br />
    public void setSex(int sex) {<br />
        this.sex = sex;<br />
    }<br />
    public Person getSon() {<br />
        return son;<br />
    }<br />
    public void setSon(Person son) {<br />
        this.son = son;<br />
    }<br />
    public void writeExternal(ObjectOutput out) throws IOException{<br />
        out.writeObject(name);<br />
        out.writeInt(sex);<br />
        out.writeObject(son);<br />
        <br />
        <br />
    }<br />
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException{<br />
        name = (String)in.readObject();<br />
        sex = in.readInt();<br />
        son = (Person)in.readObject();<br />
    }<br />
}<br /><br /><br />
import java.io.File;<br />
import java.io.FileReader;<br />
import java.io.FileWriter;<br />
import java.io.ObjectInputStream;<br />
import java.io.ObjectOutputStream;<br />
import java.io.Reader;<br />
import java.io.Writer;<br /><br />
import com.thoughtworks.xstream.XStream;<br />
import com.thoughtworks.xstream.io.xml.DomDriver;<br /><br />
public class TestXml {<br />
    public static void main(String[] args) {<br />
        try {<br />
            XStream xstream = new XStream(new DomDriver());<br />
            File file = new File("c:/ssx.xml");<br />
            Writer writer = new FileWriter(file);<br />
            ObjectOutputStream out = xstream.createObjectOutputStream(writer);<br />
            Person father = new Person();<br />
            father.setName("father");<br />
            father.setSex(1);<br />
            Person son = new Person();<br />
            son.setName("son");<br />
            father.setSon(son);<br />
            //----------------write----------<br />
            xstream.alias("Person", Person.class);<br />
            out.writeObject(father);<br />
            out.close();<br />
            //-----------------read--------------<br />
            Reader reader = new FileReader(file);<br />
            ObjectInputStream in = xstream.createObjectInputStream(reader);<br />
            Person sfather = (Person)in.readObject();<br />
            System.out.println(sfather.getName());<br />
            <br />
        } catch (Exception e) {<br />
            e.printStackTrace();<br />
        }<br /><br />
    }<br />
}<br />
可是XStream提供了Converter这个类<br /><pre>import com.thoughtworks.xstream.converters.Converter;<br />import com.thoughtworks.xstream.converters.MarshallingContext;<br />import com.thoughtworks.xstream.converters.UnmarshallingContext;<br />import com.thoughtworks.xstream.io.HierarchicalStreamReader;<br />import com.thoughtworks.xstream.io.HierarchicalStreamWriter;<br /><br />public class PersonConverter implements Converter {<br /><br />        public boolean canConvert(Class clazz) {<br />                return false;<br />        }<br /><br />        public void marshal(Object value, HierarchicalStreamWriter writer,<br />                        MarshallingContext context) {<br />        }<br /><br />        public Object unmarshal(HierarchicalStreamReader reader,<br />                        UnmarshallingContext context) {<br />                return null;<br />        }<br />这样就可以来自己建立Converter如：date..等类型。<br />然后注册一下：<br />xStream.registerConverter(new PersonConverter());<br /><br />通过对比发现XStream要比betwixt更易于使用，betwixt需要更多的设置才能运行，并且有大量隐藏的要求。<br /></pre>
http://xstream.codehaus.org 有很详细的文档介绍。<br /><img src ="http://www.blogjava.net/sdyjmc/aggbug/83618.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdyjmc/" target="_blank">弹弓</a> 2006-11-26 15:27 <a href="http://www.blogjava.net/sdyjmc/archive/2006/11/26/83618.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>