﻿<?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-Mark's Java Blog</title><link>http://www.blogjava.net/mark1207/</link><description>MyEclipse, Java EE, Spring, Struts, Hibernate, JPA, SWT, Swing, AJAX, JavaScript,SOA</description><language>zh-cn</language><lastBuildDate>Sun, 20 Jul 2008 22:11:38 GMT</lastBuildDate><pubDate>Sun, 20 Jul 2008 22:11:38 GMT</pubDate><ttl>60</ttl><item><title>Struts2访问隐藏的request和session</title><link>http://www.blogjava.net/mark1207/archive/2008/05/27/203105.html</link><dc:creator>Mark</dc:creator><author>Mark</author><pubDate>Tue, 27 May 2008 01:26:00 GMT</pubDate><guid>http://www.blogjava.net/mark1207/archive/2008/05/27/203105.html</guid><wfw:comment>http://www.blogjava.net/mark1207/comments/203105.html</wfw:comment><comments>http://www.blogjava.net/mark1207/archive/2008/05/27/203105.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mark1207/comments/commentRss/203105.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mark1207/services/trackbacks/203105.html</trackback:ping><description><![CDATA[Struts2访问隐藏的request和session <br />
<br />
在Struts1.*中，要想访问request、response以及session等Servlet对象是很方便的，因为它们一直是作为形参在各个方法之间进行传递的，而在Struts2中我们就很难看到它们的芳踪了，因为我们获得表单中的值都是通过预先设置好了的get方法来得到的，那么如果有些参数我们必须通过request.getParametre或者session.getAttribute来得到，那么应该怎么做呢？按照Max的教程上的说法，可以分为两种：IoC方式和非IoC方式，如何理解这两种方式的区别呢？IoC是Spring里面的特征之一，字面意思是反转控制，说白了就是依赖注入，比方说类A依赖类B，那么就主动的给A注入一个类B的对象，下面看一下这两种方法的具体实现。<br />
<br />
1．非Ioc方式<br />
<br />
这种方式主要是利用了com.opensymphony.xwork2.ActionContext类以及org.apache.struts2.ServletActionContext类，具体的方法如下所示。<br />
获得request对象：<br />
<br />
A．HttpServletRequest request = ServletActionContext.getRequest ();<br />
B．ActionContext ct= ActionContext.getContext()<br />
&nbsp;&nbsp; HttpServletRequest request=(HttpServletRequest)ct.get(ServletActionContext.HTTP_REQUEST);<br />
<br />
获得session对象：<br />
<br />
在Struts2中底层的session都被封装成了Map类型，我们称之为SessionMap，而平常我们所说的session则是指HttpSession对象，具体的获得方法如下所示。<br />
<br />
A．Map session=ActionContext.getSession();<br />
B．Map session=(Map)ActionContext.getContext().get(ActionContext.SESSION);<br />
得到这个SessionMap之后我们就可以对session进行读写了，如果我们想得到原始的HttpSession可以首先得到HttpServletRequest对象，然后通过request.getSession()来取得原始的HttpSession对象。一般情况下SessionMap已经可以完成所有的工作，我们不必再去碰底层的session了。<br />
<br />
2．IoC方式<br />
<br />
这种方式相对来说变化就比较少了，具体流程如下所示。<br />
获得request对象：<br />
<br />
第一步：让action实现ServletRequestAware接口<br />
第二步：在action中声明一个HttpServletRequest类型的实例变量<br />
第三步：在action中实现ServletRequestAware接口的setServletRequest方法，实现方式很简单，如下所示。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private HttpServletRequest request;<br />
publicvoid setServletRequest(HttpServletRequest request) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.request = request;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
获得Session对象(注意，此时的session是SessionMap类型)：<br />
<br />
第一步：让action实现SessionAware接口<br />
第二步：在action中声明一个HttpServletRequest类型的实例变量<br />
第三步：在action中实现SessionAware接口的setSession方法，实现方式很简单，如下所示。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Map session;<br />
publicvoid setSession(Map session) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this. session = session;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1721226
 <img src ="http://www.blogjava.net/mark1207/aggbug/203105.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mark1207/" target="_blank">Mark</a> 2008-05-27 09:26 <a href="http://www.blogjava.net/mark1207/archive/2008/05/27/203105.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java基本类型计算与运算符测试（一）</title><link>http://www.blogjava.net/mark1207/archive/2008/05/09/199449.html</link><dc:creator>Mark</dc:creator><author>Mark</author><pubDate>Fri, 09 May 2008 03:44:00 GMT</pubDate><guid>http://www.blogjava.net/mark1207/archive/2008/05/09/199449.html</guid><wfw:comment>http://www.blogjava.net/mark1207/comments/199449.html</wfw:comment><comments>http://www.blogjava.net/mark1207/archive/2008/05/09/199449.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mark1207/comments/commentRss/199449.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mark1207/services/trackbacks/199449.html</trackback:ping><description><![CDATA[突然有人问起，自己做了些测验，把结果记录下来。<br />
<br />
java的几种数值基本类型：int,short,long,float,double<br />
<br />
测试代码：<br />
<br />
<p>&nbsp;public static void main(String[] args) {<br />
<br />
&nbsp;&nbsp;short x = 100;<br />
&nbsp;&nbsp;long b = 2;<br />
&nbsp;&nbsp;int a = 2;<br />
&nbsp;&nbsp;double y=1.1;<br />
&nbsp;&nbsp;float z=(float) 1.2;<br />
&nbsp;&nbsp;double c=1.1;<br />
&nbsp;&nbsp;float d=(float) 1.2;<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;a=x+a;<br />
&nbsp;&nbsp;x+=1.1;<br />
&nbsp;&nbsp;b=b+a;<br />
&nbsp;&nbsp;y=y-1;<br />
&nbsp;&nbsp;z=z-1;<br />
&nbsp;&nbsp;c=c+1;<br />
&nbsp;&nbsp;d=d+1;<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;System.out.println(a);<br />
&nbsp;&nbsp;System.out.println(x);<br />
&nbsp;&nbsp;System.out.println(b);<br />
&nbsp;&nbsp;System.out.println(z);<br />
&nbsp;&nbsp;System.out.println(y);<br />
&nbsp;&nbsp;System.out.println(c);<br />
&nbsp;&nbsp;System.out.println(d);</p>
<p>&nbsp;&nbsp;c=c+d;<br />
&nbsp;&nbsp;System.out.println(c);<br />
&nbsp;&nbsp;c=c-d;<br />
&nbsp;&nbsp;System.out.println(c);<br />
&nbsp;&nbsp;d=(float) (d-1.1);<br />
&nbsp;&nbsp;System.out.println(d);<br />
&nbsp;}<br />
<br />
运行结果：<br />
<br />
102<br />
101<br />
104<br />
0.20000005<br />
0.10000000000000009<br />
2.1<br />
2.2<br />
4.3000000476837155<br />
2.0999999999999996<br />
1.1<br />
<br />
测试说明：<br />
<br />
不同类型数据做计算时按照计算中最大范围数据类型返回，例如：a=x+a;(如果负值对象是较小范围的类型就需要强转类型，否则会报错)<br />
double类型做加时运算精度准确，做减运算时有精度偏差，且和float类型相互作加减操作都会出现精度缺失；<br />
+=符号做运算不牵扯类型转换问题，按照负值对象的类型返回。<br />
</p>
<img src ="http://www.blogjava.net/mark1207/aggbug/199449.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mark1207/" target="_blank">Mark</a> 2008-05-09 11:44 <a href="http://www.blogjava.net/mark1207/archive/2008/05/09/199449.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate的saveorUpdate与unsaved-value，save，update，delete总结(转)</title><link>http://www.blogjava.net/mark1207/archive/2008/05/05/198563.html</link><dc:creator>Mark</dc:creator><author>Mark</author><pubDate>Mon, 05 May 2008 13:16:00 GMT</pubDate><guid>http://www.blogjava.net/mark1207/archive/2008/05/05/198563.html</guid><wfw:comment>http://www.blogjava.net/mark1207/comments/198563.html</wfw:comment><comments>http://www.blogjava.net/mark1207/archive/2008/05/05/198563.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mark1207/comments/commentRss/198563.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mark1207/services/trackbacks/198563.html</trackback:ping><description><![CDATA[<p>这些操作对经常使用hibernate的同学已经很熟悉了，我也经常用但一些细节并不了解， <br />
最近遇到问题才开始有看了一下。</p>
<p>在读完robbin的这两个精华贴的时候，感觉清晰了很多，确实好文章。 <br />
<a href="http://www.javaeye.com/topic/2712" target="blank">http://www.javaeye.com/topic/2712</a> <br />
<a href="http://www.javaeye.com/topic/1604?page=1" target="blank">http://www.javaeye.com/topic/1604?page=1</a> <br />
还有这个精华贴 <br />
<a href="http://www.javaeye.com/topic/7484" target="blank">http://www.javaeye.com/topic/7484</a> <br />
也很不错。</p>
<p>里面总结的很好了，我结合以上三个帖子、自己的试验（版本hibernate-3.0.5）和Hibernate文档也总结了一点，加深理解。<strong><span style="color: red">希望对刚开始学Hibernate的同学有所帮助</span>。</strong></p>
<p><span style="color: red">一、saveorUpdate与unsaved-value</span> <br />
到底是sava还是update <br />
Hibernate需要判断被操作的对象究竟是一个已经持久化过的持久对象还是临时对象。 <br />
<strong>1）．主键Hibernate的id generator产生</strong> <br />
&lt;id name="id" type="java.lang.Long"&gt; <br />
&lt;column name="ID" precision="22" scale="0" /&gt; <br />
&lt;generator class="increment" /&gt; <br />
&lt;/id&gt;</p>
<p>Project project = new Project(); <br />
project.setId(XXX); <br />
this.projectDao.saveOrUpdate(project);</p>
<p>1、默认unsaved-value="null" <br />
<strong>主键是对象类型，hebernate判断project的主键是否位null，来判断project是否已被持久化</strong> <br />
是的话，对project对象发送save(project)， <br />
若自己设置了主键则直接生成update的sql，发送update(project)，即便数据库里没有那条记录。 <br />
主键是基本类型如int/long/double/ <br />
自己设置unsaved-null="0"。 <br />
所以这样的话save和update操作肯定不会报错。</p>
<p>2、unsaved-value="none"， <br />
由于不论主键属性为任何值，都不可能为none，因此Hibernate总是对project对象发送update(project)</p>
<p>3、unsaved-value="any" <br />
由于不论主键属性为任何值，都肯定为any，因此Hibernate总是对project对象发送save(project)，hibernate生成主键。</p>
<p>Hibernate文档中写到 <br />
saveOrUpdate()完成了如下工作： <br />
如果对象已经在这个session中持久化过了，什么都不用做 <br />
如果对象没有标识值，调用save()来保存它 <br />
如果对象的标识值与unsaved-value中的条件匹配，调用save()来保存它 <br />
如果对象使用了版本(version或timestamp),那么除非设置unsaved-value="undefined",版本检查会发生在标识符检查之前. <br />
如果这个session中有另外一个对象具有同样的标识符，抛出一个异常 </p>
<p><strong>2）．主键由自己来赋值</strong> <br />
&lt;id name="id" type="java.lang.Long"&gt; <br />
&lt;column name="ID" precision="22" scale="0" /&gt; <br />
&lt;generator class="assigned" /&gt; <br />
&lt;/id&gt;</p>
<p>Project project = new Project(); <br />
project.setId(XXX); <br />
this.projectDao.saveOrUpdate(project);</p>
<p>1、默认unsaved-value="null" <br />
<strong>这时有所不同，hibernate会根据主键产生一个select，来判断此对象是否已被持久化</strong> <br />
已被持久化则update，未被持久化则save。 <br />
2、unsaved-value="none"，update对象，同上</p>
<p>3、unsaved-value="any" ，save对象， <br />
如果自己自己设置的ID在数据库中已存在，则报错。</p>
<p><span style="color: red">二、save与update操作</span> <br />
显式的使用session.save()或者session.update()操作一个对象的时候，实际上是用不到unsaved-value的 <br />
在同一Session，save没什么可说得 <br />
update对象时, 最直接的更改一个对象的方法就是load()它，保持Session打开，然后直接修改即可: <br />
Session s =&#8230; <br />
Project p = (Project) sess.load(Project.class, id) ); <br />
p.setName(&#8220;test&#8221;); <br />
s.flush(); <br />
不用调用s.update(p);hibernate能察觉到它的变化，会自动更新。当然显示调用的话也不会错</p>
<p>Hibernate文档中写到 <br />
update()方法在下列情形下使用： <br />
程序在前面的session中装载了对象 <br />
对象被传递到UI（界面）层 <br />
对该对象进行了一些修改 <br />
对象被传递回业务层 <br />
应用程序在第二个session中调用update()保存修改 </p>
<p><span style="color: red">三、delete操作</span> <br />
删除时直接自己构造一个project即可删除 <br />
this.projectDao.delete(preojct);</p>
<p>以前删除我是这样写的 <br />
public void deleteProject(String id) { <br />
Project project = (Project) this.projectDao.get(Project.class, id); <br />
if (project != null) { <br />
this.projectDao.delete(project); <br />
} <br />
即这样也是可以的 <br />
Project project = new Project(); <br />
project.setId(id); <br />
this.projectDao.delete(project).</p>
<p>如果有级联关系，需要把级联的子类也构造出来add进去，同样可以删除。</p>
<img src ="http://www.blogjava.net/mark1207/aggbug/198563.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mark1207/" target="_blank">Mark</a> 2008-05-05 21:16 <a href="http://www.blogjava.net/mark1207/archive/2008/05/05/198563.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>J2EE基础：对于Spring初学者的学习建议（转）</title><link>http://www.blogjava.net/mark1207/archive/2008/04/21/194414.html</link><dc:creator>Mark</dc:creator><author>Mark</author><pubDate>Sun, 20 Apr 2008 16:40:00 GMT</pubDate><guid>http://www.blogjava.net/mark1207/archive/2008/04/21/194414.html</guid><wfw:comment>http://www.blogjava.net/mark1207/comments/194414.html</wfw:comment><comments>http://www.blogjava.net/mark1207/archive/2008/04/21/194414.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/mark1207/comments/commentRss/194414.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mark1207/services/trackbacks/194414.html</trackback:ping><description><![CDATA[<p align="justify">一、首先Java的基础、面向对象的基础和设计模式的基础知识是必不可少的。 <br />
<br />
　　关于设计模式我觉得不用学太多，但以下三个模式是学习Spring必不可少的：factory模式（包括简单工厂和抽象工厂），Strategy模式，Template method模式。如果不掌握这些你就根本没法领悟Spring的精髓，只能依样画葫芦地照搬，这是很可怕的事。 <br />
<br />
　　我这里强烈建议的书可能让人有点意外，那就是Expert one on one J2EE design and development的第四章，这一章不仅仅是Spring初学者，而是任何搞Java开发的人必读的一章。经典！ <br />
<br />
　　二、接下可以看一些Spring的入门书籍 <br />
<br />
　　其实我自己没怎么看过这方面的书，我当时只看过Spring的reference，不过现在这方面的书好象多的是，而Spring reference看起来还是有些吃力的。JavaEye上很多人建议夏昕的Spring开发指南，据说入门很容易。另外的入门书应该是Spring live或Spring in action。我大概扫了一下，Spring live是一本只讲怎么做而不讲为什么的书，我不太喜欢（偶尔参考一下倒不错），不过有些人特别喜欢这样的书，看自己的个人爱好吧。 <br />
<br />
　　三、研究几个用Spring做的开源项目 <br />
<br />
　　理论还是要与实际结合，所以看完书后是要看实际的项目的。很多人喜欢appfuse，我觉得appfuse花的东西太多，真正实质性的内容又太少。我更喜欢Spring自带的jpetstore，这是一个非常完整的例子，看完后Spring的基本用法应该都能掌握。 <br />
<br />
　　四、开始做实际的项目 <br />
<br />
　　在上述这些都完备以后，我觉得应该要去实际项目中锻炼了。当然并不是每人都有这样的机会的，这时只能自己做个玩具项目啦。项目的锻炼是非常关键的，其实每个人都清楚，我就不重复了。 <br />
<br />
　　五、继续深入学习 <br />
<br />
　　经过项目的锤炼，对Spring的用法和原理有了一定的了解的时候，才有可能真正掌握Spring的精髓。这时要读的书才是Rod Johnson的三本经典名著，分别是： <br />
<br />
　　Expert one on one J2ee design and development <br />
<br />
　　Expert one on one J2ee without EJB <br />
<br />
　　Professional Java Development with SpringFramework <br />
<br />
　　前两本书的经典程度我就不说了，只有读了它们，才能真正了解Spring的设计意图，掌握Spring的精髓。 <br />
<br />
　　第三本书是我强烈不建议初学者读的书。里面的东西深入而全，但是原理讲解得又不够深，很容易让初学者犯迷糊。但是却是Spring的高级用户必读的一本书（还有一本pro Spring据说也不错，不过我没读过）。我过几天会写一下这本书的书评。 <br />
<br />
　　当然这个阶段与第四阶段是交错的，边读书边做项目学到的东西才会更多的。 <br />
<br />
　　六、分析源代码，扩展Spring <br />
<br />
　　有人认为没有必要分析Spring的源代码，因为这是很累人又不计好的事。但是要想成为Spring的高级用户，这是必经的阶段。在学习的过程中，我们学到的不仅是Spring，更重要的是他的设计思想。不管怎样，看牛人的源代码是绝对有好处的。不过这是一个很累人的过程，要有思考准备哦！</p>
<img src ="http://www.blogjava.net/mark1207/aggbug/194414.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mark1207/" target="_blank">Mark</a> 2008-04-21 00:40 <a href="http://www.blogjava.net/mark1207/archive/2008/04/21/194414.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java程序员的学习目标：破坏源程序？（转，精彩文章，推荐）</title><link>http://www.blogjava.net/mark1207/archive/2008/04/21/194413.html</link><dc:creator>Mark</dc:creator><author>Mark</author><pubDate>Sun, 20 Apr 2008 16:35:00 GMT</pubDate><guid>http://www.blogjava.net/mark1207/archive/2008/04/21/194413.html</guid><wfw:comment>http://www.blogjava.net/mark1207/comments/194413.html</wfw:comment><comments>http://www.blogjava.net/mark1207/archive/2008/04/21/194413.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mark1207/comments/commentRss/194413.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mark1207/services/trackbacks/194413.html</trackback:ping><description><![CDATA[<a href="http://whatis.ctocio.com.cn/searchwhatis/403/5948403.shtml" target="_bank">Java</a>作为一门编程语言，最好的学习方法就是写代码。当你学习一个类以后，你就可以自己写个简单的例子程序来运行一下，看看有什么结果，然后再多调用几个类的方法，看看运行结果，这样非常直观的把类给学会了，而且记忆非常深刻。然后不应该满足把代码调通，你应该想想看如果我不这样写，换个方式，再试试行不行。记得哪个高人说过学习编程就是个破坏的过程，把书上的例子，自己学习Documentation编写的例子在运行通过以后，不断的尝试着用不同的方法实现，不断的尝试破坏代码的结构，看看它会有什么结果。通过这样的方式，你会很彻底的很精通的掌握Java。举个例子，我们都编过<a href="http://whatis.ctocio.com.cn/searchwhatis/62/5948062.shtml" target="_bank">Hello World</a>这个程序。 　　&nbsp;<br />
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
    <tbody>
        <tr>
            <td style="word-wrap: break-word" bgcolor="#f3f3f3">public <a href="http://whatis.ctocio.com.cn/searchwhatis/213/5947213.shtml" target="_bank">class</a> HelloWorld {
            <p>　　public static void main(String[] args) {</p>
            <p>　　System.out.println("Hello World");</p>
            <p>　　}</p>
            <p>　　}</p>
            </td>
        </tr>
    </tbody>
</table>
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　很多初学者不是很理解为什么main方法一定要这样来定义public static void main(String[] args)，能不能不这样写?包括我刚学习Java的时候也有这样的疑问。想知道答案吗?很简单，你把main改个名字运行一下，看看报什么错误，然后根据出错信息进行分析;把main的public取掉，在试试看，报什么错误;static去掉还能不能运行;不知道main方法是否一定要传一个String[]数组的，把String[]改掉，改成<a href="http://whatis.ctocio.com.cn/searchwhatis/69/6025569.shtml" target="_bank">int</a>[]，或者String试试看;不知道是否必须写args参数名称的，也可以把args改成别的名字，看看运行结果如何。我当初学习Java的时候就是这样做的，把Hello World程序反复改了七八次，不断运行，分析运行结果，最后就彻底明白为什么main方法是这样定义的了。
<p>　　此外，我对于static，public，private，Exception，try{ }catch {}finally{}等等一开始都不是很懂，都是把参考书上面的例子运行成功，然后就开始破坏它，不断的根据自己心里面的疑问来重新改写程序，看看能不能运行，运行出来是个什么样子，是否可以得到预期的结果。这样虽然比较费时间，不过一个例子程序这样反复破坏几次之后。我就对这个相关的知识彻底学通了。有时候甚至故意写一些错误的代码来运行，看看能否得到预期的运行错误。这样对于编程的掌握是及其深刻的。其中特别值得一提的是<a href="http://whatis.ctocio.com.cn/searchwhatis/435/5948435.shtml" target="_bank">JDK</a>有一个非常棒的调试功能-verbose。</p>
<p>　　java &#8211;verbose</p>
<p>　　javac &#8211;verbose 以及其它很多JDK工具都有这个选项</p>
<p>　　-verbose 可以显示在命令执行的过程中，<a href="http://whatis.ctocio.com.cn/searchwhatis/0/5948500.shtml" target="_bank">JVM</a>都依次加载哪里Class，通过这些宝贵的调试信息，可以帮助我们分析出J<a href="http://whatis.ctocio.com.cn/searchwhatis/24/6026524.shtml" target="_bank">VM</a>在执行的过程中都干了些什么。另外，自己在学习过程中，写的很多的这种破坏例程，应该有意识的分门别类的保存下来，在工作中积累的典型例程也应该定期整理，日积月累，自己就有了一个代码库了。遇到类似的问题，到代码库里面 Copy &amp; Paste ，Search &amp; Replace，就好了，极大提高了开发速度。最理想的情况是把一些通用的例程自己再抽象一层，形成一个通用的类库，封装好。那么可复用性就更强了。所以我觉得其实不是特别需要例程的，自己写的破坏例程就是最好的例子，如果你实在对自己写的代码不放心的话，我强烈推荐你看看JDK基础类库的Java源代码。在JDK安装目录下面会有一个src.zip，解开来就可以完整的看到整个JDK基础类库，也就是rt.jar的Java源代码，你可以参考一下<a href="http://whatis.ctocio.com.cn/searchwhatis/347/7786847.shtml" target="_bank">Sun</a>是怎么写Java程序的，规范是什么样子的。我自己在学习Java的类库的时候，当有些地方理解的不是很清楚的时候，或者想更加清晰的理解运作的细节的时候，往往会打开相应的类的源代码，通过看源代码，所有的问题都会一扫而空。</p>
<img src ="http://www.blogjava.net/mark1207/aggbug/194413.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mark1207/" target="_blank">Mark</a> 2008-04-21 00:35 <a href="http://www.blogjava.net/mark1207/archive/2008/04/21/194413.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ajax 在企业应用上的优势（转）</title><link>http://www.blogjava.net/mark1207/archive/2008/04/21/194412.html</link><dc:creator>Mark</dc:creator><author>Mark</author><pubDate>Sun, 20 Apr 2008 16:31:00 GMT</pubDate><guid>http://www.blogjava.net/mark1207/archive/2008/04/21/194412.html</guid><wfw:comment>http://www.blogjava.net/mark1207/comments/194412.html</wfw:comment><comments>http://www.blogjava.net/mark1207/archive/2008/04/21/194412.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mark1207/comments/commentRss/194412.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mark1207/services/trackbacks/194412.html</trackback:ping><description><![CDATA[为了帮助企业方便使用<a href="http://whatis.ctocio.com.cn/searchwhatis/252/7422252.shtml" target="_bank">Ajax</a>，供应商们正在设法降低它的使用难度。
<p>　　如今的网络用户都被宠坏了。他们一旦在谷歌公司(<a href="http://whatis.ctocio.com.cn/searchwhatis/191/6093191.shtml" target="_bank">Google</a>)或Flickr网站体验过快捷的响应和良好的互动功能后，传统的点击-等待式的Web界面就再也无法满足他们的需求了。这些功能正是通过Ajax来实现的。由于Ajax所带来的商业价值日益凸现，微软公司(<a href="http://whatis.ctocio.com.cn/searchwhatis/251/5948751.shtml" target="_bank">Microsoft</a>)和<a href="http://whatis.ctocio.com.cn/searchwhatis/446/7372446.shtml" target="_bank">开源</a>的开发者工作平台<a href="http://whatis.ctocio.com.cn/searchwhatis/431/7372431.shtml" target="_bank">Eclipse</a>的支持者们，最近正积极开发一些适合Ajax的平台，以便用户能够方便地利用这种工具来创建互动式的Web应用。</p>
<p>　　Ajax等网络开发工具和技术与传统的服务器端软件不同。服务器端软件普遍具有成熟的技术标准，而Ajax等网络开发技术尚还处在不断的变化中。Ajax是新兴的网络开发技术的象征。它将<a href="http://whatis.ctocio.com.cn/searchwhatis/403/5948403.shtml" target="_bank">Java</a>Script和<a href="http://whatis.ctocio.com.cn/searchwhatis/203/5949203.shtml" target="_bank">XML</a>技术结合在一起，用户每次调用新数据时，无需反复向服务器发出请求，而是在浏览器的缓存区预先获取下次可能用到的数据，界面的响应速度因此得到了显著提升。Google公司的地图服务(Google Maps)就是Ajax应用最典型的例子之一。</p>
<p>　　不久前，Eclipse开源项目的领导厂商，包括国际商业机器公司(<a href="http://whatis.ctocio.com.cn/searchwhatis/199/5948199.shtml" target="_bank">IBM</a>)、英特尔公司(Intel)、红帽公司(<a href="http://whatis.ctocio.com.cn/searchwhatis/56/6093556.shtml" target="_bank">Red Hat</a>)和思爱普软件系统公司(<a href="http://whatis.ctocio.com.cn/searchwhatis/126/7787126.shtml" target="_bank">SAP</a>)等宣布，将把Eclipse从开发者工作平台扩展成能与微软公司在企业市场展开竞争的新平台。在日前召开的EclipseCon大会上，Eclipse基金会执行总监迈克&#183;米林科维奇(Mike Milinkovich)表示：&#8220;今后3年，微软公司可能会不断说服一些企业放弃Win32 API，并转向(Windows)Vista。&#8221;然而，米林科维奇却建议企业最好采用Eclipse的富客户平台。因为开发者采用这套组件，就可以在企业桌面应用程序创建交互性更好的界面，一次开发完毕后，在视窗系统(Windows)、<a href="http://whatis.ctocio.com.cn/searchwhatis/210/5948710.shtml" target="_bank">Linux</a>或者苹果系统上都能够运行。</p>
<p>　　<strong>Eclipse行动</strong></p>
<p>　　Eclipse项目组正在设法为用户提供除微软公司产品之外的更多选择。不久前，该项目组推出了一个开源项目Rich Ajax Platform(下称&#8220;<a href="http://whatis.ctocio.com.cn/searchwhatis/465/6028465.shtml" target="_bank">RA</a>P&#8221;)，吸引开发人员使用Eclipse来提供界面组件，包括视窗风格的菜单、拖动条以及支持拖曳功能的弹出窗口(Drag-and-Drop Window Expanders)等，目的是使Web应用在浏览器中更具有交互性。</p>
<p>　　不久前，IBM公司与Google公司、Laszlo系统公司、Mozilla公司、网威公司(Novell)、甲骨文公司(<a href="http://whatis.ctocio.com.cn/searchwhatis/14/6093014.shtml" target="_bank">Oracle</a>)、红帽公司和雅虎公司(<a href="http://whatis.ctocio.com.cn/searchwhatis/66/6026566.shtml" target="_bank">Yahoo</a>)等多家企业，共同合作创建了一项开源项目Ajax Toolkit Framework，旨在建立一种基于Eclipse的软件系统，以降低在Eclipse平台内使用Ajax工具的难度。在此之前，使用Ajax开发程序并不那么容易。Google公司是在开发Google Maps的过程中发现这一点的。它发现地图上标记下的阴影或者两点之间的驾驶路线，都会因为浏览器的使用差异而产生不同的显示效果。不过，Google Maps产品经理布莱特&#183;泰勒(Bret Taylor)也表示：&#8220;Google公司在创建工具包方面投入了大量精力，因此大家对这些细节方面大可放心。&#8221;Eclipse项目在像Google公司这样的大公司帮助下，正在采用Google公司的方法，以便使所有企业都能更方便地使用Ajax技术。</p>
<p>　　而与此同时，微软公司也并没有在原地踏步。在日前举行的微软网络技术大会上，公司主席比尔&#183;盖茨(Bill Gates)发表了一篇主题演讲。盖茨在讲话中承认，新一轮的Web应用热潮即将到来。一些网站变得像传统软件的组件一样，可以被API调用，以及像子程序一样运行。&#8220;现在，富有创新想法的时代已经到来。&#8221;盖茨表示，&#8220;这是软件的新时代。&#8221;</p>
<p>　　日前，微软公司发布了一个自有Ajax开发工具—<a href="http://whatis.ctocio.com.cn/searchwhatis/373/7466873.shtml" target="_bank">Atlas</a>的升级测试版。它可以在应用程序的客户端创建标准的JavaScript。微软公司也开发了基于JavaScript的服务器端扩展程序，来优化Ajax应用在视窗电脑上的执行。这样，用Atlas编写的软件，可以与Windows Vista的各种元素产生互动。而且，采用Atlas编写的Web应用特别能够与Vista的其他程序产生互动，比如日历、即时通讯联系人、照相簿和媒体播放软件等。微软公司Web工具产品经理布赖恩&#183;戈德法伯(Brian Goldfarb)还透露说：&#8220;公司正在考虑其他更丰富的应用场景，从而可以更好地与<a href="http://whatis.ctocio.com.cn/searchwhatis/201/5948201.shtml" target="_bank">IE</a>浏览器和视窗系统进行配合。"</p>
<p>　　不过，微软公司在发布代号为&#8220;Orcas&#8221;的下一版本Visual Studio 时，才会正式推出Atlas工具。因此，距离Atlas的面世还要等上好几年的时间。而与此同时，Eclipse却在利用Ajax工具包而快速发展。</p>
<p>　　微软公司的优势就在于，能够把Atlas工具与公司的视窗系统、SQL Server数据库以及其他软件整合在一起。不过，IBM公司也以开源代码的形式，捐献出了Eclipse的核心工作平台技术，因为它也希望Java工具拥有与微软公司类似的集成度。</p>
<p>　　格雷格&#183;斯坦因(Greg Stein)是Google公司的工程经理、<a href="http://whatis.ctocio.com.cn/searchwhatis/299/6025299.shtml" target="_bank">Apache</a>软件基金会主席以及Apache Web服务器等项目的赞助人。斯坦因认为：&#8220;Eclipse是一种集成的开发环境，因此将会在一定程度上简化Ajax应用的开发难度。&#8221;而德国小型软件公司Innoopract公司的管理总监约亨&#183;克劳泽(Jochen Krause)也预测说，这个平台&#8220;将会把Eclipse的应用扩展到一个不同的领<a href="http://whatis.ctocio.com.cn/searchwhatis/194/7352194.shtml" target="_bank">域</a>，即互动Web应用领域。&#8221;RAP项目就是由这家公司提出的。</p>
<p>　　<strong>简单为上</strong></p>
<p>　　Eclipse项目将会给企业带来一定的帮助。有了Eclipse工具包，他们就无需掌握专门的JavaScript知识，可以在Eclipse的框架下工作。而大多数C语言、<a href="http://whatis.ctocio.com.cn/searchwhatis/441/5946941.shtml" target="_bank">C++</a>、Cobol、Java和<a href="http://whatis.ctocio.com.cn/searchwhatis/77/6026077.shtml" target="_bank">PHP</a>程序员，对于Eclipse都不陌生。加拿大研究委员会(National Research Council Canada)计算机系统官员丹尼&#183;达穆尔(Danny D&#8217;amours)表示：&#8220;我们的一些应用程序，响应时间会变得更快捷，而且还能够有更好的在线互动。&#8221;在Eclipse的Ajax framework项目中，&#8220;Ajax将会整合成为Eclipse开发环境的一部分。&#8221;达穆尔补充说道。</p>
<p>　　达穆尔会考虑使用微软公司的Atlas吗?看上去，他似乎对此不感兴趣。的确，微软和非微软阵营的对抗似乎依然处于紧张状态。尽管企业往往会同时采用Visual Studio与Eclipsebased的开发工具，很可能也包括两者的Ajax和Web应用技术。</p>
<p>　　企业通过使用Ajax，可以强化网站的功能，提高用户体验。他们可以滚动屏幕浏览大量的信息，或者方便地把物品拖入在线购物车，或者在线配置产品而无需不断地刷新页面。其实，不仅仅是Google这样的公司在使用Ajax，Lands&#8217;End网站和沃尔沃公司(Volvo)等也在使用Ajax技术让潜在的客户设计他们的产品或汽车，而且Sabre控股公司(Sabre Holdings)也采用了Ajax技术来减少其航空公司客户使用的飞行计划软件的响应时间。</p>
<img src ="http://www.blogjava.net/mark1207/aggbug/194412.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mark1207/" target="_blank">Mark</a> 2008-04-21 00:31 <a href="http://www.blogjava.net/mark1207/archive/2008/04/21/194412.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java关键字new和newInstance的区别方法(转)</title><link>http://www.blogjava.net/mark1207/archive/2008/04/21/194411.html</link><dc:creator>Mark</dc:creator><author>Mark</author><pubDate>Sun, 20 Apr 2008 16:19:00 GMT</pubDate><guid>http://www.blogjava.net/mark1207/archive/2008/04/21/194411.html</guid><wfw:comment>http://www.blogjava.net/mark1207/comments/194411.html</wfw:comment><comments>http://www.blogjava.net/mark1207/archive/2008/04/21/194411.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mark1207/comments/commentRss/194411.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mark1207/services/trackbacks/194411.html</trackback:ping><description><![CDATA[在初始化一个类，生成一个实例的时候，newInstance()方法和new关键字除了一个是方法，一个是关键字外，最主要有什么区别?它们的区别在于创建对象的方式不一样，前者是使用类加载机制，后者是创建一个新类。那么为什么会有两种创建对象方式?这主要考虑到软件的可伸缩、可扩展和可重用等软件设计思想。
<p>　　<a href="http://whatis.ctocio.com.cn/searchwhatis/403/5948403.shtml" target="_bank">Java</a>中工厂模式经常使用newInstance()方法来创建对象，因此从为什么要使用工厂模式上可以找到具体答案。 例如：</p>
<p>　　
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
    <tbody>
        <tr>
            <td style="word-wrap: break-word" bgcolor="#f3f3f3"><a href="http://whatis.ctocio.com.cn/searchwhatis/213/5947213.shtml" target="_bank">class</a> c = Class.forName(&#8220;Example&#8221;);
            <p>　　factory = (ExampleInterface)c.newInstance();</p>
            </td>
        </tr>
    </tbody>
</table>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　其中ExampleInterface是Example的接口，可以写成如下形式：</p>
<p>　　
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
    <tbody>
        <tr>
            <td style="word-wrap: break-word" bgcolor="#f3f3f3">String className = "Example";
            <p>　　class c = Class.forName(className);</p>
            <p>　　factory = (ExampleInterface)c.newInstance();</p>
            </td>
        </tr>
    </tbody>
</table>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　进一步可以写成如下形式：</p>
<p>　　
<table style="border-right: #cccccc 1px dotted; table-layout: fixed; border-top: #cccccc 1px dotted; border-left: #cccccc 1px dotted; border-bottom: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
    <tbody>
        <tr>
            <td style="word-wrap: break-word" bgcolor="#f3f3f3">String className = readfromXMlConfig;//从xml 配置文件中获得字符串
            <p>　　class c = Class.forName(className);</p>
            <p>　　factory = (ExampleInterface)c.newInstance();</p>
            </td>
        </tr>
    </tbody>
</table>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　上面代码已经不存在Example的类名称，它的优点是，无论Example类怎么变化，上述代码不变，甚至可以更换Example的兄弟类Example2 , Example3 , Example4&#8230;&#8230;，只要他们继承ExampleInterface就可以。</p>
<p>　　从<a href="http://whatis.ctocio.com.cn/searchwhatis/0/5948500.shtml" target="_bank">JVM</a>的角度看，我们使用关键字new创建一个类的时候，这个类可以没有被加载。但是使用newInstance()方法的时候，就必须保证：1、这个类已经加载;2、这个类已经连接了。而完成上面两个步骤的正是Class的静态方法forName()所完成的，这个静态方法调用了启动类加载器，即加载java API的那个加载器。</p>
<p>　　现在可以看出，newInstance()实际上是把new这个方式分解为两步，即首先调用Class加载方法加载某个类，然后实例化。 这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性，提供给了一种降耦的手段。</p>
<p>　　最后用最简单的描述来区分new关键字和newInstance()方法的区别：</p>
<p>　　newInstance: 弱类型。低效率。只能调用无参构造。</p>
<p>　　new: 强类型。相对高效。能调用任何public构造。</p>
<img src ="http://www.blogjava.net/mark1207/aggbug/194411.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mark1207/" target="_blank">Mark</a> 2008-04-21 00:19 <a href="http://www.blogjava.net/mark1207/archive/2008/04/21/194411.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>西方国家这次为什么会如次的团结？ （转）</title><link>http://www.blogjava.net/mark1207/archive/2008/04/18/194081.html</link><dc:creator>Mark</dc:creator><author>Mark</author><pubDate>Fri, 18 Apr 2008 09:37:00 GMT</pubDate><guid>http://www.blogjava.net/mark1207/archive/2008/04/18/194081.html</guid><wfw:comment>http://www.blogjava.net/mark1207/comments/194081.html</wfw:comment><comments>http://www.blogjava.net/mark1207/archive/2008/04/18/194081.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/mark1207/comments/commentRss/194081.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mark1207/services/trackbacks/194081.html</trackback:ping><description><![CDATA[西方国家这次为什么会如次的团结？
<p><strong><font size="3">&nbsp; 欧洲的德国、法国，一般是不会冒着这样的风险得罪中国这个经济大国的。伊拉克战争时德国和法国都和中国站在一边，不支持美国对伊动武。为伊拉克而得罪美国，不符合他们的国家利益啊。法国10年前为了不得罪中国，终止了对台军售，损失了几十亿的收入。而为什么今天会冒着这么大的风险公然与中国为敌？难到就是为了和自己根本不相干的西藏和奥运？<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 而另一个值得让人思考的问题是，一向是西方老大的美国，为什么这一次这么低调？让英、法、德在前台唱主角？对于西藏，西方国家很清楚，再怎么闹，中国也不可能做出让步。对于奥运，他们也很清楚，就算西方国家没有一个领导人出席北京奥运会，中国也就是面子上过不去罢了，对中国有实质影响吗？没有。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 所以，西藏只是一个幌子，奥运也只是一个幌子。那么他们到底想从中国得到什么？ <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 西方国家正面临着10年来经济陷入衰退的危险，他们需要有一个有实力的国家为这次西方经济的衰退买单。不言而喻，他们不约而同的想到了中国。 做为一个普通老百姓，我对国际经济没有什么研究，但2008年一开始我还是隐约到中国经济面临的危险，现在也就想起了温总理说过的一句话：2008年也许是中国经济最困难的一年。现在想起正在进行的这场闹剧，真的有点让人毛骨耸然了。美国不是低调，是很冷静，他们早已经不露声色的出招了： <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、美元贬值。因为美元贬值，人民币升值，中国16000亿美元的外汇储备已经人间蒸发了3000亿美元，而且还在继续蒸发中。更要命的是，由于人民币升值，中国出口产品成本增加，沉重的打击中国的出口，许多企业面临倒闭的危险。因为中国企业的倒闭，西方国家生产企业就可以开始生产复苏。 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、通过高油价以拖跨中国经济。中国经济的高速发展需要大量的进品原油，而西方国家则不断的提高石油储备，造成高油价一直持续，以增加中国经济建设的成本。这就是美国为什么要打伊拉克、打伊朗的原因：控制石油就是控制了经济命脉。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3、助涨中国金融泡沫。人民币升值，大量热钱自然要涌入中国，造成中国高成本、高币值的经济泡沫。或许这就是为什么政府就算是背着千夫所指都绝不救市的原因，就是为了打击国际投机资本在中国的恶意圈钱行为，而另一方面却不得不面对成千上万痛不欲生的股民的唾骂而有可能造成国内社会动荡的危险。现在看了，什么西藏事件、抵制奥运都是不足为道的事。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 所以，&#8220;西藏&#8221;和&#8220;奥运&#8221;只是西方国家绑架的两个&#8220;人质&#8221;，他们真正的目的不是西藏，也不是奥运，而是以此为要挟，要中国为他们的经济衰退买单。不买单：搞乱你，要死大家一起死。买单：坐下来谈，你答应我我就息事宁人！&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 中国政府的冷静是对的，死死抓住经济建设这个中心不动摇才是关键。经济如果一跨，那就什么都跨了。 国民要冷静，要相互理解，不要给政府出难题。还是那句话：发展才是硬道理，压倒一切的是稳定。一个普通的中国人都能预料到，我相信政府能从容应对。我们要支持政府打赢这场表面上看起来是舆论战，而事实上是经济的战争&nbsp; <br />
我们需要更团结&nbsp; 希望大家奔走先告<br />
1、多省油&nbsp; 多乘坐公共交通出行&nbsp; 能做车就不要开车 能开窗户就不要开 空调<br />
2、多省电&nbsp; 路灯不用就关掉， 能用耳机就不要开音箱，家电不用就要把整个开关拔下来 又省电又安全 希望政府把夜景工程的灯光就关掉&nbsp; <br />
3、支持国货 能买到国货就不要买外国货 促进内需 钱要给自己人赚&nbsp;&nbsp; <br />
4、努力工作 多开发和制造更好的产品&nbsp; 实业才是救国之本<br />
5、尊重自己 尊重国人 不要崇洋媚外&nbsp; <br />
6、告诉台湾 西藏 包括其他民族的青年 为什么我们现在还这么痛苦别的国家看不起，因为我们的祖辈太喜欢窝里斗，。&nbsp; <br />
7、告诉身边的每一个人 中国只有强大才会有更好的家 ，落后就要挨打挨骂&nbsp; <br />
8、政府在进步 督促政府更快的进步 而不是推到他 那样高兴的是美日 痛苦的是自己<br />
</font></strong></p>
 <img src ="http://www.blogjava.net/mark1207/aggbug/194081.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mark1207/" target="_blank">Mark</a> 2008-04-18 17:37 <a href="http://www.blogjava.net/mark1207/archive/2008/04/18/194081.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java语言中的参数传递(转)</title><link>http://www.blogjava.net/mark1207/archive/2008/04/18/194071.html</link><dc:creator>Mark</dc:creator><author>Mark</author><pubDate>Fri, 18 Apr 2008 09:01:00 GMT</pubDate><guid>http://www.blogjava.net/mark1207/archive/2008/04/18/194071.html</guid><wfw:comment>http://www.blogjava.net/mark1207/comments/194071.html</wfw:comment><comments>http://www.blogjava.net/mark1207/archive/2008/04/18/194071.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mark1207/comments/commentRss/194071.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mark1207/services/trackbacks/194071.html</trackback:ping><description><![CDATA[在实际的开发过程中，方法调用是一种很常见的操作，在方法调用中，关于参数的处理可能很多进行实际开发的程序员都不一定理解的很清楚，下面系统的介绍一下Java语言中参数传递的规则，以及和参数传递相关的一些问题。
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>和其它程序设计语言类似，Java语言的参数传递也分为两种：</div>
<div style="margin-left: 39pt; text-indent: -18pt"><span>1、&nbsp;</span>按值传递(by value)</div>
<div style="margin-left: 39pt">适用范围：8种基本数据类型、String对象</div>
<div style="margin-left: 39pt">特点：在内存中复制一份数据，把复制后的数据传递到方法内部</div>
<div style="margin-left: 39pt">作用：在方法内部改变参数的值，外部数据不会跟着发生改变</div>
<div style="margin-left: 39pt; text-indent: -18pt"><span>2、&nbsp;</span>按址传递(by address)</div>
<div style="margin-left: 39pt">适用范围：数组、除String以外的其他所有类型的对象</div>
<div style="margin-left: 39pt">特点：将对象的地址传递到方法内部</div>
<div style="margin-left: 39pt">作用：在方法内部修改对象的内容，外部数据也会跟着发生改变</div>
<div style="margin-left: 17.95pt">基础示例代码：</div>
<div style="margin-left: 21pt"><span>&nbsp;&nbsp;&nbsp; public class Test1{</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp; public static void t1(int n){</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n = 10;</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp; }</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp; public static void t2(String s){</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;s = "123";</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp; }</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp; public static void t3(int[] array){</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; array[0] = 2;</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp; }</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp; public static void main(String[] args){</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m = 5;</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t1(m);</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(m);</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s1 = "abc";</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t2(s1);</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(s1);</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int[] arr = {1,2,3,4};</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t3(arr);</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(arr[0]);</span></div>
<div style="margin-left: 52.5pt"><span>&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; </span></div>
<div style="margin-left: 21pt"><span>&nbsp;&nbsp; }</span></div>
<div style="margin-left: 21pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>按照上面的参数传递规则，该代码的输出结果应该是：5&nbsp;abc&nbsp;2。因为int类型是按值传递，所以把参数m传递到方法t1时，相当于又复制了一份m的值，在方法t 1内部修改的是复制后的值，所以m的值不变，s1的输出和m类似。而arr是数组，属于按址传递，也就是把arr的地址传递到了方法t3内部，在方法t3内部修改数组中的值时，原来的内容也发生改变。</div>
<div style="margin-left: 21pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>以上特性是Java语言中的规定，在语法上无法指定参数传递是按值传递还是按址传递，但是可以通过下面的变换实现：</div>
<div style="margin-left: 60pt; text-indent: -18pt"><span>1、&nbsp;</span>对于按值传递的参数，如果需要在方法调用以后修改参数的值，可以利用返回值来实现。</div>
<div style="margin-left: 60pt; text-indent: -18pt"><span>2、&nbsp;</span>对于按值传递的参数，如果需要在方法内部修改时原来的参数不改变，则可以在方法内部重新创建该对象实现。</div>
<div style="margin-left: 38.95pt">示例代码如下：</div>
<div style="margin-left: 63pt">public class Test2{</div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp; public static int t1(int n){</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n = 10;</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return n;</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp; }</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp; public static String t2(String s){</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s = "123";</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp; s;</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp; }</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp; public static void t3(int[] array){</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //</span>创建新的数组并赋值</div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int[] newArray = new int[array.length];</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //</span>数据拷贝</div>
<div style="margin-left: 63pt">&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.arraycopy(array,0,newArray,0,array.length);</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newArray[0] = 2;</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp; }</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp; public static void main(String[] args){</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m = 5;</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //</span>重新赋值</div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m = t1(m);</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(m);</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s1 = "abc";</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //</span>重新赋值</div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s1 = t2(s1);</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(s1);</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int[] arr = {1,2,3,4};</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t3(arr);</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(arr[0]);</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; </span></div>
<div style="margin-left: 63pt">}</div>
<div style="margin-left: 42pt">这样，程序的输出结果就将是：10&nbsp;123<span>&nbsp;&nbsp; 1</span>。</div>
<div style="margin-left: 42pt">在实际的程序开发中，可以根据需要使用类似的结构来进行实现。</div>
<div style="margin-left: 21pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>下面再介绍一个参数传递的常见应用，利用参数传递实现返回值，这样的功能在IO类设计的read方法中大量使用。示例代码如下：</div>
<div style="margin-left: 63pt">public class Test3{</div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp; public static void initArray(int[] array){</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i = 0;i &lt; array.length;i++){</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; array[i] = i;</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp; }</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp; public static void main(String[] args){</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int[] a = new int[10];</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; initArray(a);</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i = 0;i &lt; a.length;i++){</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(a[i]);</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></div>
<div style="margin-left: 63pt"><span>&nbsp;&nbsp;&nbsp; }</span></div>
<div style="margin-left: 63pt">}</div>
<div style="margin-left: 21pt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>在该示例代码中，在initArray方法内部修改了数组的值以后，外部数组a的值也会发生改变，间接实现了返回值的效果。当然，在该示例代码中，因为只返回一个参数，所以作用体现的不明显，如果需要返回多个参数时，使用按址传递是一种不错的主意。</div>
<div style="margin-left: 21pt"><span>&nbsp;&nbsp;&nbsp; </span>因时间仓促，疏漏之处难免，请大家积极补充和指正。</div>
<img src ="http://www.blogjava.net/mark1207/aggbug/194071.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mark1207/" target="_blank">Mark</a> 2008-04-18 17:01 <a href="http://www.blogjava.net/mark1207/archive/2008/04/18/194071.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ObjectOutputStream和ObjectInputStream</title><link>http://www.blogjava.net/mark1207/archive/2008/04/14/192751.html</link><dc:creator>Mark</dc:creator><author>Mark</author><pubDate>Mon, 14 Apr 2008 05:53:00 GMT</pubDate><guid>http://www.blogjava.net/mark1207/archive/2008/04/14/192751.html</guid><wfw:comment>http://www.blogjava.net/mark1207/comments/192751.html</wfw:comment><comments>http://www.blogjava.net/mark1207/archive/2008/04/14/192751.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mark1207/comments/commentRss/192751.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mark1207/services/trackbacks/192751.html</trackback:ping><description><![CDATA[<p>ObjectOutputStream和ObjectInputStream</p>
<p>--ObjectOutputStream</p>
<p>ObjectInputStream 类恢复以前使用 ObjectOutputStream 类序列化后的基本类型数据和对象。 </p>
<p>ObjectOutputStream 和 ObjectInputStream 分别利用 FileOutputStream 和 FileInputStream 能支持应用程序实现对象图象的稳定存储。</p>
<p>ObjectInputStream 可用于恢复以前序列化过的对象。另外其它一些情况也使用此类，诸如使用一个 Socket 在主机间传递对象时，</p>
<p>或在远程通讯系统中为实现参数和参变量的通讯而进行对象传递时。 </p>
<p>ObjectInputStream 保证从流中创建的图象中的所有对象的类型与 Java 虚拟机中出现的类匹配。使用标准机制按需装载相应类。 </p>
<p>只有支持 java.io.Serializable 或 java.io.Externalizable 接口的对象才能从流中读取。使用 readObject 方法从该流中</p>
<p>读取一个对象。 Java 的安全造型应该用于获取期望类型。在 Java 中, 串和数组都是对象且可当作是序列化过程中的对象。</p>
<p>读取时，它们需要转换为所需类型。 </p>
<p>另外基类型也可使用 DataInput 中的正确方法从该流中读取。 </p>
<p>对象的缺省逆序列化机制将每个域的内容恢复为它被写入时的值和类型。逆序列化过程中忽略申明为暂时的或静态的域。</p>
<p>对其它对象的引用促使那些对象必须从流中读取。使用引用共享机制正确地恢复对象的图象。逆序列化时总是分配新对象，</p>
<p>防止重写已存在的对象。 </p>
<p>读取一个对象同运行一个新对象的构造子类似。为该对象分配的内存初始化为空(NULL)。为非序列化类调用无参构造子，</p>
<p>然后将序列化类的域从该流中恢复，恢复从最接近 java.lang.object 的序列化对象开始，到指定对象结束。 </p>
<p>例如读取在示例中写入 ObjectOutputStream 中的流：</p>
<p><br />
&nbsp;FileInputStream istream = new FileInputStream("t.tmp");<br />
&nbsp;ObjectInputStream p = new ObjectInputStream(istream);<br />
&nbsp;int i = p.readInt();<br />
&nbsp;String today = (String)p.readObject();<br />
&nbsp;Date date = (Date)p.readObject();<br />
&nbsp;istream.close();<br />
&nbsp;<br />
类通过实现 java.io.Serializable 或 java.io.Externalizable 接口来控制它们的序列化。</p>
<p>实现序列化接口可以使对象能保存和恢复它的完整状态，可以使类在写入流和从流中读取的期间内进行改进。</p>
<p>它自动地遍历对象间的引用，保存和恢复完整图象。在序列化和逆序列化处理过程中需要特定句柄的可序列化类，</p>
<p>必须实现如下这两个方法： </p>
<p><br />
&nbsp;private void writeObject(java.io.ObjectOutputStream stream)<br />
&nbsp;&nbsp;&nbsp;&nbsp; throws IOException;<br />
&nbsp;private void readObject(java.io.ObjectInputStream stream)<br />
&nbsp;&nbsp;&nbsp;&nbsp; throws IOException, ClassNotFoundException; <br />
&nbsp;<br />
利用 writeObjectmethod 方法将一个特殊类的对象的状态写入某流后，相应的 readObject 方法将负责读取和恢复这些数据。</p>
<p>此方法不必关心状态是属于它的父类还是子类。 从 ObjectInputStream 读取数据恢复单个域的状态，并将之赋给该对象的恰当域。</p>
<p>使用 DataInput 方法读取基本数据类型。</p>
<p>序列化操作对没有实现 java.io.Serializable 接口的对象，不读取或分配它的域值。非序列化对象的子类可以是序列化的。</p>
<p>在这种情况下，非序列化类必须有一个无参构造子，使它的域能使用此构造子完成初始化。 在此情况下，</p>
<p>子类负责保存和恢复非序列化类的状态。通常情况父类的域是可存储的(公有的、包或保护的)，</p>
<p>或存在用于恢复它的状态的可使用的获取或设置方法。 </p>
<p>ObjectInputStream 能获取逆序列化一个对象期间出现的任一异常，一旦出现异常，则放弃读过程。 </p>
<p>实现外部接口可以使对象完全控制此对象序列化形式的内容和格式。</p>
<p>调用外部接口的方法：writeExternal 和 readExternal 保存和恢复对象状态。当一个类实现了这些方法时，</p>
<p>它们就能使用 ObjectOutput 和 ObjectInput 方法的所有方法写入或读取它们自己的状态。对象负责管理它出现的相应版本。 </p>
<p><br />
ObjectOutputStream</p>
<p>public class ObjectOutputStream <br />
extends OutputStream <br />
implements ObjectOutput, ObjectStreamConstants <br />
类 ObjectOutputStream 将 Java 对象中的基本数据类型和图元写入到一个 OutputStream 对象中。可使用 ObjectInputStream 读取这些对象。</p>
<p>另外使用此流对应的文件能存储这些对象。如果该流是一个网络通讯流，则在另一台主机或另一个处理机上可重建这些对象。 </p>
<p>只有支持 java.io.Serializable 接口的对象才能被写入该流。对每个可序列化的对象进行编码，包括相应类的名称和标记，</p>
<p>对象的属性和数组值，以及初始化对象时引用的任何其它对象等。 </p>
<p>使用 writeObject 将一个对象写入该流。任一对象，包括串和数组，均采用 writeObject 方法被写入。</p>
<p>也能将多个对象或基类型对象写入此流。反过来，必须以这些对象被写入的相同类型和相同顺序，</p>
<p>从相应的 ObjectInputstream 流中读回这些对象。 </p>
<p>基类型也可使用 DataOutput 中的正确方法写入此流。串对象也可使用 writeUTF 方法写入。</p>
<p>一个对象的缺省序列化机制将写入对象的类，类标记和所有的非暂时的和非静态的属性值。</p>
<p>其它对象(除暂时的或静态的属性)的引用也将促使以上这些对象被写入。 使用共享机制，对单一对象的多次引用进行编码，</p>
<p>以至对象的图元能被存储为与它原来写入时有相同的形状。 </p>
<p>例如写入一个对象，此对象能从 ObjectInputStream 中读出：</p>
<p><br />
&nbsp;FileOutputStream ostream = new FileOutputStream("t.tmp");<br />
&nbsp;ObjectOutputStream p = new ObjectOutputStream(ostream);<br />
&nbsp;p.writeInt(12345);<br />
&nbsp;p.writeObject("Today");<br />
&nbsp;p.writeObject(new Date());<br />
&nbsp;p.flush();<br />
&nbsp;ostream.close();<br />
&nbsp;<br />
在序列化处理过程中需要特定句柄的类，必须使用如下这些恰当的标记实现特定的方法： </p>
<p>&nbsp;private void readObject(java.io.ObjectInputStream stream)<br />
&nbsp;&nbsp;&nbsp;&nbsp; throws IOException, ClassNotFoundException; <br />
&nbsp;private void writeObject(java.io.ObjectOutputStream stream)<br />
&nbsp;&nbsp;&nbsp;&nbsp; throws IOException<br />
&nbsp;<br />
writeObject 方法负责写特定类的对象的状态，以使相应的 readObject 方法能存储它。</p>
<p>此方法不必关心写入对象的父类或子类的状态。使用 writeObject 方法或基本类型支持的 DataOutput </p>
<p>方法将每个域的状态保存到 ObjectOutputStream 中。 </p>
<p>序列化操作不能输出没有实现 java.io.Serializable 接口的任一对象的域。非序列化对象的子类可以是序列化的。 </p>
<p>在这种情况下，非序列化类必须有一个无参构造子，使它的域能被初始化。 在此情况下，子类负责保存和恢复非序列化类的状态。 </p>
<p>通常情况父类的域是可存储的(公有的、包或保护的)，或存在用于恢复它的状态的可使用的获取或设置方法。 </p>
<p>实现抛出 NotSerializableException 异常的 writeObject 和 readObject 方法能阻止一个对象的序列化。 </p>
<p>ObjectOutputStream 将获取这个异常，并放弃这个序列化过程。实现外部接口可以使对象完全控制此对象序列化形式的内容和格式。 </p>
<p>调用外部接口的方法：writeExternal 和 readExternal 保存和恢复对象状态。当一个类实现了这些方法时，</p>
<p>它们就能使用 ObjectOutput 和 ObjectInput 方法的所有方法写入或读取它们自己的状态。对象负责管理它出现的相应版本。 </p>
<p><br />
import java.io.*;<br />
import java.util.*;</p>
<p>public class Logon implements Serializable {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Date date = new Date();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private String username;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private transient String password;</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Logon(String name, String pwd) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; username = name;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; password = pwd;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String toString() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pwd = (password == null) ? "(n/a)" : password;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "logon info: \n " + "username: " + username + "\n date: " + date + "\n password: " + pwd;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws IOException, ClassNotFoundException {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Logon a = new Logon("Morgan", "morgan83");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println( "logon a = " + a);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectOutputStream o = new ObjectOutputStream( new FileOutputStream("Logon.out"));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o.writeObject(a);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o.close();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int seconds = 5;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long t = System.currentTimeMillis() + seconds * 1000;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(System.currentTimeMillis() &lt; t) ;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectInputStream in = new ObjectInputStream( new FileInputStream("Logon.out"));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println( "Recovering object at " + new Date());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a = (Logon)in.readObject();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("logon a = " + a); <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
}<br />
&nbsp;</p>
<p>类Logon是一个记录登录信息的类，包括用户名和密码。首先它实现了接口Serializable，这就标志着它可以被序列化。</p>
<p>之后再main方法里ObjectOutputStream o = new ObjectOutputStream( new FileOutputStream("Logon.out"));</p>
<p>新建一个对象输出流包装一个文件流，表示对象序列化的目的地是文件Logon.out。然后用方法writeObject开始写入。</p>
<p>想要还原的时候也很简单ObjectInputStream in = new ObjectInputStream( new FileInputStream("Logon.out"));</p>
<p>新建一个对象输入流以文件流Logon.out为参数，之后调用readObject方法就可以了。</p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/mark1207/aggbug/192751.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mark1207/" target="_blank">Mark</a> 2008-04-14 13:53 <a href="http://www.blogjava.net/mark1207/archive/2008/04/14/192751.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>