﻿<?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-adidas1981-文章分类-java部分 </title><link>http://www.blogjava.net/adidas1981/category/2031.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 03 Mar 2007 00:44:06 GMT</lastBuildDate><pubDate>Sat, 03 Mar 2007 00:44:06 GMT</pubDate><ttl>60</ttl><item><title>JAVA下中文乱码问题的一些解决方案</title><link>http://www.blogjava.net/adidas1981/articles/7373.html</link><dc:creator>小浩</dc:creator><author>小浩</author><pubDate>Fri, 08 Jul 2005 08:14:00 GMT</pubDate><guid>http://www.blogjava.net/adidas1981/articles/7373.html</guid><wfw:comment>http://www.blogjava.net/adidas1981/comments/7373.html</wfw:comment><comments>http://www.blogjava.net/adidas1981/articles/7373.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/adidas1981/comments/commentRss/7373.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/adidas1981/services/trackbacks/7373.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp; 1.字节和unicodejava内核是unicode的，就连class文件也是，但是很多媒体，包括文件/流的保存方式是使用字节流的。因此java要对这些字节流经行转化。char是unicode的，而byte是字节。java中byte/char互转的函数在sun.io的包中间有。其中ByteToCharConverter类是中调度，可以用来告诉你，你...&nbsp;&nbsp;<a href='http://www.blogjava.net/adidas1981/articles/7373.html'>阅读全文</a><img src ="http://www.blogjava.net/adidas1981/aggbug/7373.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/adidas1981/" target="_blank">小浩</a> 2005-07-08 16:14 <a href="http://www.blogjava.net/adidas1981/articles/7373.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ArrayList中的数据排序--java对象排序</title><link>http://www.blogjava.net/adidas1981/articles/7217.html</link><dc:creator>小浩</dc:creator><author>小浩</author><pubDate>Wed, 06 Jul 2005 09:59:00 GMT</pubDate><guid>http://www.blogjava.net/adidas1981/articles/7217.html</guid><wfw:comment>http://www.blogjava.net/adidas1981/comments/7217.html</wfw:comment><comments>http://www.blogjava.net/adidas1981/articles/7217.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/adidas1981/comments/commentRss/7217.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/adidas1981/services/trackbacks/7217.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=6 width="98%" background=/images/data_title_bg.gif border=0>
<TBODY>
<TR>
<TD align=middle><FONT class=f18 color=#339900 size=2><B>ArrayList中的数据排序--java对象排序</B></FONT></TD></TR>
<TR>
<TD align=middle><FONT color=#a20010 size=2></FONT></TD></TR></TBODY></TABLE>
<P><FONT size=2></FONT></P>
<P align=center><FONT size=2>
<SCRIPT src="http://www.21tx.com/images/ad/ad_dev_c_3.js"></SCRIPT>
</FONT></P>
<TABLE cellSpacing=0 cellPadding=0 width="98%" border=0>
<TBODY>
<TR>
<TD class=content>
<P><FONT size=2>常常遇到数组排序的问题.比如我有一个Person类,它的实例对象存储在ArrayList数组中,现在要把ArrayList数组中的Person对象按照年龄排序.<BR>其实这种情况经常遇到.<BR>下面给出源代码:</FONT></P>
<P><FONT size=2>1:Person.java文件:-------------------------------<BR>public class Person{<BR>&nbsp;String name;<BR>&nbsp;int age;<BR>&nbsp;<BR>&nbsp;public Person(String name,int age){<BR>&nbsp;&nbsp;this.name = name;<BR>&nbsp;&nbsp;this.age = age;<BR>&nbsp;&nbsp;<BR>&nbsp;}</FONT></P>
<P><FONT size=2>&nbsp;public int getAge() {<BR>&nbsp;&nbsp;return age;<BR>&nbsp;}</FONT></P>
<P><FONT size=2>&nbsp;public void setAge(int age) {<BR>&nbsp;&nbsp;this.age = age;<BR>&nbsp;}</FONT></P>
<P><FONT size=2>&nbsp;public String getName() {<BR>&nbsp;&nbsp;return name;<BR>&nbsp;}</FONT></P>
<P><FONT size=2>&nbsp;public void setName(String name) {<BR>&nbsp;&nbsp;this.name = name;<BR>&nbsp;}</FONT></P>
<P><FONT size=2>}</FONT></P>
<P><BR><FONT size=2>2:Mycomparator.java-------------------------------<BR>//实现Comparator接口,也就是定义排序规则,你几乎可以定义任何规则<BR>package com.infoearth;<BR>import java.util.*;<BR>public class Mycomparator implements Comparator{</FONT></P>
<P><FONT size=2>&nbsp;public int compare(Object o1,Object o2) {<BR>&nbsp;&nbsp;Person p1=(Person)o1;<BR>&nbsp;&nbsp;Person p2=(Person)o2;&nbsp;&nbsp;<BR>&nbsp;&nbsp;if(p1.age&lt;p2.age)<BR>&nbsp;&nbsp;&nbsp;return 1;<BR>&nbsp;&nbsp;else<BR>&nbsp;&nbsp;&nbsp;return 0;<BR>&nbsp;}</FONT></P>
<P><FONT size=2>}</FONT></P>
<P><FONT size=2>3:ListSort.java------------------------------------</FONT></P>
<P><FONT size=2>package com.infoearth;</FONT></P>
<P><FONT size=2>import java.util.ArrayList;<BR>import java.util.Collections;<BR>import java.util.Comparator;</FONT></P>
<P><FONT size=2>public class ListSort {<BR>&nbsp;public static void main(String[] args){<BR>&nbsp;&nbsp;ArrayList list = new ArrayList();<BR>&nbsp;&nbsp;list.add(new Person("lcl",28));<BR>&nbsp;&nbsp;list.add(new Person("fx",23));<BR>&nbsp;&nbsp;list.add(new Person("wqx",29));<BR>&nbsp;&nbsp;Comparator comp = new Mycomparator();<BR>&nbsp;&nbsp;Collections.sort(list,comp);&nbsp;&nbsp;<BR>&nbsp;&nbsp;for(int i = 0;i&lt;list.size();i++){<BR>&nbsp;&nbsp;&nbsp;Person p = (Person)list.get(i);<BR>&nbsp;&nbsp;&nbsp;System.out.println(p.getName());<BR>&nbsp;&nbsp;}&nbsp;&nbsp;<BR>&nbsp;&nbsp;<BR>&nbsp;}</FONT></P>
<P><FONT size=2>}</FONT></P></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/adidas1981/aggbug/7217.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/adidas1981/" target="_blank">小浩</a> 2005-07-06 17:59 <a href="http://www.blogjava.net/adidas1981/articles/7217.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java语言的异常类使用讨论 (转)</title><link>http://www.blogjava.net/adidas1981/articles/7184.html</link><dc:creator>小浩</dc:creator><author>小浩</author><pubDate>Wed, 06 Jul 2005 03:56:00 GMT</pubDate><guid>http://www.blogjava.net/adidas1981/articles/7184.html</guid><wfw:comment>http://www.blogjava.net/adidas1981/comments/7184.html</wfw:comment><comments>http://www.blogjava.net/adidas1981/articles/7184.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/adidas1981/comments/commentRss/7184.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/adidas1981/services/trackbacks/7184.html</trackback:ping><description><![CDATA[<H4>
<P><FONT color=#0000ff size=2>&nbsp;&nbsp;&nbsp; Java异常的语法应该是很简单的，一个try，catch，finally，一个throws，throw，两分钟就可学完了。我相信许多人和我一样，对于异常是这样处理的：<BR>1.写程序时就等编译器检查，一旦通不过就加try，catch;<BR>2.自己抛异常常常忘了在方法声明时加throws，而且又不明白为什么有的异常需要throws，而有的又不需要;<BR>3.从来不写自己的异常类；<BR>4.catch到异常不知道怎么办，通通加一行printStackTrace拉倒；<BR>如果属于以上这几种情况的，我觉得有必要和我一起讨论一下Java的异常使用方法。</FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;&nbsp;&nbsp; 查阅资料可以得知，Java最主要的异常类包括4种：Throwable、Error、Exception和RuntimeException；其中Throwable是所有异常类的父类，它继承Object类并实现Serializable接口；Error和Exception都是Throwable的子类；而RuntimeException是Exception的子类。Exception的子类非常多，但是RuntimeException是一个特殊的子类，需要单独讨论。<BR>&nbsp;&nbsp;&nbsp; 一般当程序员在某个方法中抛出一个Exception异常（或者其子类）时，需在方法头部声明此方法抛出了一个异常，就是用throws关键字来声明；但是如果在方法中抛出一个RuntimeException或者一个Error时，则不需要声明此方法抛出了异常，这是为什么呢？<BR>&nbsp;&nbsp;&nbsp; 语法上的约束必然有其背后的道理；如果不去弄明白这些道理而是一味的依赖编辑器来帮忙，则事倍功半。事实上，Java语言的这种语法含义是：Java编译器要求Java程序必须捕获或声明所有非运行时的异常，也就是说，Exception异常是需查异常，必须由程序员对它严格的负责，如果在方法中抛出，必须声明，如果抛出的异常没有被catch，则会出现语法错误，编译都不能通过。这是强制性的让程序员遵守Java的异常规则。这样规定的原因是当Exception异常出现时，运行的程序还有补救的余地，通过异常处理代码，可以让程序恢复运行，如果不捕捉这种异常，则白白浪费了补救程序的机会。而且，这种异常应让程序员可见，所以必须在方法头部声明此方法抛出了某种Exception异常。<BR>&nbsp;&nbsp;&nbsp; 那么，Error和RuntimeException都是不需查异常，在方法中抛出这两种异常都不需要声明，在程序中不catch它们也不会造成语法错误。我的理解是，当出现这样的异常时，运行的程序已经没有补救的余地了，于是直接抛出异常让程序结束是比较合理的安排。如果在程序运行时出现了Error或者RuntimeException，那么程序员也无能为力，所以它们可以对程序员透明，也不需要特意声明让程序员来处理它们。<BR>&nbsp;&nbsp;&nbsp; 现在我们知道，try和catch一般对Exception及其子类使用，throws也是。而对于Error和RuntimeException则不需要throws，不过还是可以catch的，但是catch到它们一般也就是释放资源，退出程序而已。<BR>&nbsp;&nbsp;&nbsp; 对于catch到的异常的处理，最经常犯的错误就是丢失异常，catch到旧的异常抛出新的异常，等到程序出错时就找不到旧异常的信息了。其实JDK1.4已经提供了这个问题的解决方案，就是用Exception的构造函数形成异常链，用旧异常作为参数构造新异常，这样就可以在出错时一步步跟踪到所有出现过的异常了，这两个构造函数就是：<BR>&nbsp;&nbsp;&nbsp; public Exception(String message, Throwable cause) {<BR>&nbsp;&nbsp;&nbsp; super(message, cause);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public Exception(Throwable cause) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(cause); <BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; 就想到这么多，以后有了新体会再续。</FONT></P>
<P>&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;&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#0000ff size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2005-03-02 15:40 作者: </FONT><A class=clsSubText id=RecentPostsRepeater_RecentPostsRepeater__ctl10_Hyperlink3 HREF="/wxb_nudt/"><FONT color=#0000ff size=2>wxb_nudt</FONT></A></P></H4><img src ="http://www.blogjava.net/adidas1981/aggbug/7184.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/adidas1981/" target="_blank">小浩</a> 2005-07-06 11:56 <a href="http://www.blogjava.net/adidas1981/articles/7184.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>最安全的加密算法 </title><link>http://www.blogjava.net/adidas1981/articles/7181.html</link><dc:creator>小浩</dc:creator><author>小浩</author><pubDate>Wed, 06 Jul 2005 03:11:00 GMT</pubDate><guid>http://www.blogjava.net/adidas1981/articles/7181.html</guid><wfw:comment>http://www.blogjava.net/adidas1981/comments/7181.html</wfw:comment><comments>http://www.blogjava.net/adidas1981/articles/7181.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/adidas1981/comments/commentRss/7181.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/adidas1981/services/trackbacks/7181.html</trackback:ping><description><![CDATA[<FONT size=2>在密码学里，有一种理想的加密方案，叫做一次一密乱码本（one-time pad）。<BR><BR>one-time pad的算法有以下要求：<BR>1、密钥必须随机产生<BR>2、密钥不能重复使用<BR>3、密钥和密文的长度是一样的。<BR><BR>one-time pad是最安全的加密算法，双方一旦安全交换了密钥，之后交换信息的过程就是绝对安全的啦。这种算法一直在一些要求高度机密的场合使用，据说美国和前苏联之间的热线电话、前苏联的间谍都是使用One-time pad的方式加密的。不管超级计算机工作多久，也不管多少人，用什么方法和技术，具有多大的计算能力，都不可能破解。<BR><BR>一次一密的一种实现方式，如下：<BR></FONT>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><FONT size=2><IMG id=Codehighlighter1_28_356_Open_Image onclick="this.style.display='none'; Codehighlighter1_28_356_Open_Text.style.display='none'; Codehighlighter1_28_356_Closed_Image.style.display='inline'; Codehighlighter1_28_356_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_28_356_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_28_356_Closed_Text.style.display='none'; Codehighlighter1_28_356_Open_Image.style.display='inline'; Codehighlighter1_28_356_Open_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ContractedBlock.gif" align=top><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;OneTimePadUtil&nbsp;</SPAN><SPAN id=Codehighlighter1_28_356_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cnblogs.com/images/dot.gif"></SPAN></FONT><SPAN id=Codehighlighter1_28_356_Open_Text><FONT size=2><SPAN style="COLOR: #000000">{<BR><IMG id=Codehighlighter1_87_354_Open_Image onclick="this.style.display='none'; Codehighlighter1_87_354_Open_Text.style.display='none'; Codehighlighter1_87_354_Closed_Image.style.display='inline'; Codehighlighter1_87_354_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_87_354_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_87_354_Closed_Text.style.display='none'; Codehighlighter1_87_354_Open_Image.style.display='inline'; Codehighlighter1_87_354_Open_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">[]&nbsp;xor(</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">[]&nbsp;bytes,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">[]&nbsp;keyBytes)&nbsp;</SPAN><SPAN id=Codehighlighter1_87_354_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cnblogs.com/images/dot.gif"></SPAN></FONT><SPAN id=Codehighlighter1_87_354_Open_Text><FONT size=2><SPAN style="COLOR: #000000">{<BR><IMG id=Codehighlighter1_128_173_Open_Image onclick="this.style.display='none'; Codehighlighter1_128_173_Open_Text.style.display='none'; Codehighlighter1_128_173_Closed_Image.style.display='inline'; Codehighlighter1_128_173_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_128_173_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_128_173_Closed_Text.style.display='none'; Codehighlighter1_128_173_Open_Image.style.display='inline'; Codehighlighter1_128_173_Open_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(keyBytes.length&nbsp;</SPAN><SPAN style="COLOR: #000000">!=</SPAN><SPAN style="COLOR: #000000">&nbsp;bytes.length)&nbsp;</SPAN><SPAN id=Codehighlighter1_128_173_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cnblogs.com/images/dot.gif"></SPAN></FONT><SPAN id=Codehighlighter1_128_173_Open_Text><FONT size=2><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throw</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN></FONT><SPAN style="COLOR: #000000"><FONT size=2>&nbsp;IllegalArgumentException();<BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</FONT></SPAN></SPAN><SPAN style="COLOR: #000000"><BR><FONT size=2><IMG src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</FONT></SPAN><FONT size=2><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">[]&nbsp;resultBytes&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">[bytes.length];<BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG id=Codehighlighter1_271_328_Open_Image onclick="this.style.display='none'; Codehighlighter1_271_328_Open_Text.style.display='none'; Codehighlighter1_271_328_Closed_Image.style.display='inline'; Codehighlighter1_271_328_Closed_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_271_328_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_271_328_Closed_Text.style.display='none'; Codehighlighter1_271_328_Open_Image.style.display='inline'; Codehighlighter1_271_328_Open_Text.style.display='inline';" src="http://www.cnblogs.com/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;resultBytes.length;&nbsp;</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">i)&nbsp;</SPAN><SPAN id=Codehighlighter1_271_328_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.cnblogs.com/images/dot.gif"></SPAN></FONT><SPAN id=Codehighlighter1_271_328_Open_Text><FONT size=2><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resultBytes[i]&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">)&nbsp;(keyBytes[i]&nbsp;</SPAN><SPAN style="COLOR: #000000">^</SPAN></FONT><SPAN style="COLOR: #000000"><FONT size=2>&nbsp;bytes[i]);<BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</FONT></SPAN></SPAN><SPAN style="COLOR: #000000"><BR><FONT size=2><IMG src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</FONT></SPAN><SPAN style="COLOR: #0000ff"><FONT size=2>return</FONT></SPAN><SPAN style="COLOR: #000000"><FONT size=2>&nbsp;resultBytes;<BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</FONT></SPAN></SPAN><SPAN style="COLOR: #000000"><BR><FONT size=2><IMG src="http://www.cnblogs.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</FONT></SPAN></SPAN></DIV></DIV><BR><FONT size=2>使用例子：<BR></FONT>
<DIV style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><FONT size=2><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">String&nbsp;plainText&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">温少</SPAN><SPAN style="COLOR: #000000">"</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top>String&nbsp;keyText&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">密码</SPAN><SPAN style="COLOR: #000000">"</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">[]&nbsp;plainBytes&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">&nbsp;plainText.getBytes();<BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">[]&nbsp;keyBytes&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">&nbsp;keyText.getBytes();<BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top>assert&nbsp;plainBytes.length&nbsp;</SPAN><SPAN style="COLOR: #000000">==</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">&nbsp;keyBytes.length;<BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">加密</SPAN></FONT><SPAN style="COLOR: #008000"><BR><FONT size=2><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top></FONT></SPAN><FONT size=2><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">[]&nbsp;cipherBytes&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">&nbsp;OneTimePadUtil.xor(plainBytes,&nbsp;keyBytes);<BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top></SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">解密</SPAN></FONT><SPAN style="COLOR: #008000"><BR><FONT size=2><IMG src="http://www.cnblogs.com/images/OutliningIndicators/None.gif" align=top></FONT></SPAN><FONT size=2><SPAN style="COLOR: #0000ff">byte</SPAN><SPAN style="COLOR: #000000">[]&nbsp;cipherPlainBytes&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;OneTimePadUtil.xor(cipherBytes,&nbsp;keyBytes);</SPAN></FONT></DIV></DIV>
<P><BR><FONT size=2>这是最简单的加密算法，但也是最安全的机密算法。前天和朋友讨论到了这个问题，所以写了这篇文章。</FONT></P><img src ="http://www.blogjava.net/adidas1981/aggbug/7181.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/adidas1981/" target="_blank">小浩</a> 2005-07-06 11:11 <a href="http://www.blogjava.net/adidas1981/articles/7181.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何使用JCE的DES进行加密解密 </title><link>http://www.blogjava.net/adidas1981/articles/7179.html</link><dc:creator>小浩</dc:creator><author>小浩</author><pubDate>Wed, 06 Jul 2005 02:47:00 GMT</pubDate><guid>http://www.blogjava.net/adidas1981/articles/7179.html</guid><wfw:comment>http://www.blogjava.net/adidas1981/comments/7179.html</wfw:comment><comments>http://www.blogjava.net/adidas1981/articles/7179.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/adidas1981/comments/commentRss/7179.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/adidas1981/services/trackbacks/7179.html</trackback:ping><description><![CDATA[<FONT size=2><SPAN style="COLOR: #000000">package&nbsp;sample;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>import&nbsp;java.security.</SPAN><SPAN style="COLOR: #000000">*</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top>import&nbsp;javax.crypto.</SPAN><SPAN style="COLOR: #000000">*</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR><IMG id=Codehighlighter1_65_224_Open_Image onclick="this.style.display='none'; Codehighlighter1_65_224_Open_Text.style.display='none'; Codehighlighter1_65_224_Closed_Image.style.display='inline'; Codehighlighter1_65_224_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_65_224_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_65_224_Closed_Text.style.display='none'; Codehighlighter1_65_224_Open_Image.style.display='inline'; Codehighlighter1_65_224_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top></SPAN><SPAN id=Codehighlighter1_65_224_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</SPAN></FONT><SPAN id=Codehighlighter1_65_224_Open_Text><SPAN style="COLOR: #008000"><FONT size=2>/*</FONT></SPAN><FONT size=2><SPAN style="COLOR: #008000">*<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*&nbsp;&lt;p&gt;Title:&nbsp;&lt;/p&gt;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*&nbsp;&lt;p&gt;Description:&nbsp;&lt;/p&gt;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*&nbsp;&lt;p&gt;Copyright:&nbsp;Copyright&nbsp;(c)&nbsp;2005&lt;/p&gt;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*&nbsp;&lt;p&gt;Company:&nbsp;&lt;/p&gt;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*&nbsp;@author&nbsp;George&nbsp;Hill<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;*&nbsp;@version&nbsp;1.0<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN></FONT></SPAN><SPAN style="COLOR: #000000"><BR><FONT size=2><IMG src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align=top><BR><IMG id=Codehighlighter1_245_1490_Open_Image onclick="this.style.display='none'; Codehighlighter1_245_1490_Open_Text.style.display='none'; Codehighlighter1_245_1490_Closed_Image.style.display='inline'; Codehighlighter1_245_1490_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_245_1490_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_245_1490_Closed_Text.style.display='none'; Codehighlighter1_245_1490_Open_Image.style.display='inline'; Codehighlighter1_245_1490_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align=top></FONT></SPAN><FONT size=2><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;Test&nbsp;</SPAN><SPAN id=Codehighlighter1_245_1490_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN></FONT><SPAN id=Codehighlighter1_245_1490_Open_Text><FONT size=2><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;加密使用的Key</SPAN></FONT><SPAN style="COLOR: #008000"><BR><FONT size=2><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top></FONT></SPAN><FONT size=2><SPAN style="COLOR: #000000">&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">&nbsp;SecretKey&nbsp;key;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;加密算法，JCE可用DES,DESede和Blowfish</SPAN></FONT><SPAN style="COLOR: #008000"><BR><FONT size=2><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top></FONT></SPAN><FONT size=2><SPAN style="COLOR: #000000">&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">private</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;final&nbsp;String&nbsp;algorithm&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">DES</SPAN><SPAN style="COLOR: #000000">"</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;<BR><IMG id=Codehighlighter1_427_532_Open_Image onclick="this.style.display='none'; Codehighlighter1_427_532_Open_Text.style.display='none'; Codehighlighter1_427_532_Closed_Image.style.display='inline'; Codehighlighter1_427_532_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_427_532_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_427_532_Closed_Text.style.display='none'; Codehighlighter1_427_532_Open_Image.style.display='inline'; Codehighlighter1_427_532_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;Test()&nbsp;throws&nbsp;NoSuchAlgorithmException&nbsp;</SPAN><SPAN id=Codehighlighter1_427_532_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN></FONT><SPAN id=Codehighlighter1_427_532_Open_Text><FONT size=2><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;KeyGenerator&nbsp;generator&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">&nbsp;KeyGenerator.getInstance(algorithm);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;key&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN></FONT><SPAN style="COLOR: #000000"><FONT size=2>&nbsp;generator.generateKey();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;}</FONT></SPAN></SPAN><SPAN style="COLOR: #000000"><BR><FONT size=2><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;<BR><IMG id=Codehighlighter1_539_643_Open_Image onclick="this.style.display='none'; Codehighlighter1_539_643_Open_Text.style.display='none'; Codehighlighter1_539_643_Closed_Image.style.display='inline'; Codehighlighter1_539_643_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_539_643_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_539_643_Closed_Text.style.display='none'; Codehighlighter1_539_643_Open_Image.style.display='inline'; Codehighlighter1_539_643_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</FONT></SPAN><SPAN id=Codehighlighter1_539_643_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><FONT size=2>/**/</FONT></SPAN><SPAN id=Codehighlighter1_539_643_Open_Text><SPAN style="COLOR: #008000"><FONT size=2>/*</FONT></SPAN><FONT size=2><SPAN style="COLOR: #008000">*<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;利用DES算法加密<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;s&nbsp;String&nbsp;需要加密的字符串<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;String&nbsp;加密后的字符串<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;@throws&nbsp;Exception<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN></FONT></SPAN><SPAN style="COLOR: #000000"><BR><FONT size=2><IMG id=Codehighlighter1_700_837_Open_Image onclick="this.style.display='none'; Codehighlighter1_700_837_Open_Text.style.display='none'; Codehighlighter1_700_837_Closed_Image.style.display='inline'; Codehighlighter1_700_837_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_700_837_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_700_837_Closed_Text.style.display='none'; Codehighlighter1_700_837_Open_Image.style.display='inline'; Codehighlighter1_700_837_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</FONT></SPAN><FONT size=2><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;String&nbsp;encryptData(String&nbsp;s)&nbsp;throws&nbsp;Exception&nbsp;</SPAN><SPAN id=Codehighlighter1_700_837_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN></FONT><SPAN id=Codehighlighter1_700_837_Open_Text><FONT size=2><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Cipher&nbsp;c&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">&nbsp;Cipher.getInstance(algorithm);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;c.init(Cipher.ENCRYPT_MODE,&nbsp;key);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN></FONT><SPAN style="COLOR: #000000"><FONT size=2>&nbsp;String(c.doFinal(s.getBytes()));<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;}</FONT></SPAN></SPAN><SPAN style="COLOR: #000000"><BR><FONT size=2><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;<BR><IMG id=Codehighlighter1_844_948_Open_Image onclick="this.style.display='none'; Codehighlighter1_844_948_Open_Text.style.display='none'; Codehighlighter1_844_948_Closed_Image.style.display='inline'; Codehighlighter1_844_948_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_844_948_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_844_948_Closed_Text.style.display='none'; Codehighlighter1_844_948_Open_Image.style.display='inline'; Codehighlighter1_844_948_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</FONT></SPAN><SPAN id=Codehighlighter1_844_948_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><FONT size=2>/**/</FONT></SPAN><SPAN id=Codehighlighter1_844_948_Open_Text><SPAN style="COLOR: #008000"><FONT size=2>/*</FONT></SPAN><FONT size=2><SPAN style="COLOR: #008000">*<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;利用DES算法解密<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;s&nbsp;String&nbsp;需要解密的字符串<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;String&nbsp;解密后的字符串<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;@throws&nbsp;Exception<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN></FONT></SPAN><SPAN style="COLOR: #000000"><BR><FONT size=2><IMG id=Codehighlighter1_1005_1142_Open_Image onclick="this.style.display='none'; Codehighlighter1_1005_1142_Open_Text.style.display='none'; Codehighlighter1_1005_1142_Closed_Image.style.display='inline'; Codehighlighter1_1005_1142_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_1005_1142_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1005_1142_Closed_Text.style.display='none'; Codehighlighter1_1005_1142_Open_Image.style.display='inline'; Codehighlighter1_1005_1142_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</FONT></SPAN><FONT size=2><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;String&nbsp;decryptData(String&nbsp;s)&nbsp;throws&nbsp;Exception&nbsp;</SPAN><SPAN id=Codehighlighter1_1005_1142_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN></FONT><SPAN id=Codehighlighter1_1005_1142_Open_Text><FONT size=2><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Cipher&nbsp;c&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">&nbsp;Cipher.getInstance(algorithm);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;c.init(Cipher.DECRYPT_MODE,&nbsp;key);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top><BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN></FONT><SPAN style="COLOR: #000000"><FONT size=2>&nbsp;String(c.doFinal(s.getBytes()));<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;}</FONT></SPAN></SPAN><SPAN style="COLOR: #000000"><BR><FONT size=2><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;<BR><IMG id=Codehighlighter1_1149_1216_Open_Image onclick="this.style.display='none'; Codehighlighter1_1149_1216_Open_Text.style.display='none'; Codehighlighter1_1149_1216_Closed_Image.style.display='inline'; Codehighlighter1_1149_1216_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_1149_1216_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1149_1216_Closed_Text.style.display='none'; Codehighlighter1_1149_1216_Open_Image.style.display='inline'; Codehighlighter1_1149_1216_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</FONT></SPAN><SPAN id=Codehighlighter1_1149_1216_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><FONT size=2>/**/</FONT></SPAN><SPAN id=Codehighlighter1_1149_1216_Open_Text><SPAN style="COLOR: #008000"><FONT size=2>/*</FONT></SPAN><FONT size=2><SPAN style="COLOR: #008000">*<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;测试程序<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;args&nbsp;String[]<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;*&nbsp;@throws&nbsp;Exception<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN></FONT></SPAN><SPAN style="COLOR: #000000"><BR><FONT size=2><IMG id=Codehighlighter1_1276_1488_Open_Image onclick="this.style.display='none'; Codehighlighter1_1276_1488_Open_Text.style.display='none'; Codehighlighter1_1276_1488_Closed_Image.style.display='inline'; Codehighlighter1_1276_1488_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_1276_1488_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1276_1488_Closed_Text.style.display='none'; Codehighlighter1_1276_1488_Open_Image.style.display='inline'; Codehighlighter1_1276_1488_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;</FONT></SPAN><FONT size=2><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;throws&nbsp;Exception&nbsp;</SPAN><SPAN id=Codehighlighter1_1276_1488_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG src="http://www.blogjava.net/images/dot.gif"></SPAN></FONT><SPAN id=Codehighlighter1_1276_1488_Open_Text><FONT size=2><SPAN style="COLOR: #000000">{<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Hello</SPAN><SPAN style="COLOR: #000000">"</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">;<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Test&nbsp;test&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">&nbsp;Test();<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;encrypt&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">&nbsp;test.encryptData(s);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;System.</SPAN><SPAN style="COLOR: #0000ff">out</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">.println(encrypt);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;decrypt&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN></FONT><FONT size=2><SPAN style="COLOR: #000000">&nbsp;test.decryptData(encrypt);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;System.</SPAN><SPAN style="COLOR: #0000ff">out</SPAN></FONT><SPAN style="COLOR: #000000"><FONT size=2>.println(decrypt);<BR><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;}</FONT></SPAN></SPAN><SPAN style="COLOR: #000000"><BR><FONT size=2><IMG src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</FONT></SPAN></SPAN><SPAN style="COLOR: #000000"><BR></SPAN><img src ="http://www.blogjava.net/adidas1981/aggbug/7179.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/adidas1981/" target="_blank">小浩</a> 2005-07-06 10:47 <a href="http://www.blogjava.net/adidas1981/articles/7179.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>项目开发规范</title><link>http://www.blogjava.net/adidas1981/articles/7132.html</link><dc:creator>小浩</dc:creator><author>小浩</author><pubDate>Tue, 05 Jul 2005 05:44:00 GMT</pubDate><guid>http://www.blogjava.net/adidas1981/articles/7132.html</guid><wfw:comment>http://www.blogjava.net/adidas1981/comments/7132.html</wfw:comment><comments>http://www.blogjava.net/adidas1981/articles/7132.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/adidas1981/comments/commentRss/7132.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/adidas1981/services/trackbacks/7132.html</trackback:ping><description><![CDATA[<P><FONT color=#0000ff size=2>项目开发规范</FONT></P>
<P><FONT color=#0000ff size=2>一、目的&nbsp;&nbsp;&nbsp; </FONT></P>
<P><FONT color=#0000ff size=2>　　对于代码，首要要求是它必须正确，能够按照程序员的真实思想去运行；第二个的要求是代码必须清晰易懂，使别的程序员能够容易理解代码所进行的实际工作。在软件工程领域，源程序的风格统一标志着可维护性、可读性，是软件项目的一个重要组成部分。而目前还没有成文的编码风格文档，以致于很多时候，程序员没有一个共同的标准可以遵守，编码风格各异，程序可维护性差、可读性也很差。通过建立代码编写规范，形成开发小组编码约定，提高程序的可靠性、可读性、可修改性、可维护性、可继承性和一致性，可以保证程序代码的质量，继承软件开发成果，充分利用资源，使开发人员之间的工作成果可以共享。</FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;&nbsp;&nbsp; 本文在参考业界已有的编码风格的基础上，描述了一个基于 JBuilder 的项目风格，力求一种统一的编程风格，并从整体编码风格、代码文件风格、函数编写风格、变量风格、注释风格等几个方面进行阐述。（这些规范并不是一定要绝对遵守，但是一定要让程序有良好的可读性）</FONT></P>
<P><BR><FONT color=#0000ff size=2>二、整体编码风格</FONT></P>
<P><FONT color=#0000ff size=2>1、缩进</FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;&nbsp;&nbsp; 缩进建议以4个空格为单位。建议在 Tools/Editor Options 中设置 Editor 页面的Block ident为4，Tab Size 为8。预处理语句、全局数据、标题、附加说明、函数说明、标号等均顶格书写。语句块的"{"、"}"配对对齐，并与其前一行对齐，语句块类的语句缩进建议每个"{"、"}"单独占一行，便于匹对。JBuilder 中的默认方式是开始的"{"不是单独一行，建议更改成上述格式（在 Project/Default Project Properties 中设置 Code Style 中选择 Braces 为 Next line）。</FONT></P>
<P><FONT color=#0000ff size=2>2、空格</FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;&nbsp;&nbsp; 原则上变量、类、常量数据和函数在其类型，修饰名称之间适当空格并据情况对齐。关键字原则上空一格，如：if ( ...&nbsp; 等。运算符的空格规定如下："::"、"-&gt;"、"["、"]"、"++"、"--"、"~"、"!"、"+"、"-"（指正负号）、"&amp;"（引用）等几个运算符两边不加空格（其中单目运算符系指与操作数相连的一边），其它运算符（包括大多数二目运算符和三目运算符"?:"两边均加一空格，在作函数定义时还可据情况多空或不空格来对齐，但在函数实现时可以不用。","运算符只在其后空一格，需对齐时也可不空或多空格。不论是否有括号，对语句行后加的注释应用适当空格与语句隔开并尽可能对齐。个人认为此项可以依照个人习惯决定遵循与否。</FONT></P>
<P><FONT color=#0000ff size=2>3、对齐</FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;&nbsp;&nbsp; 原则上关系密切的行应对齐，对齐包括类型、修饰、名称、参数等各部分对齐。另每一行的长度不应超过屏幕太多，必要时适当换行，换行时尽可能在","处或运算符处，换行后最好以运算符打头，并且以下各行均以该语句首行缩进，但该语句仍以首行的缩进为准，即如其下一行为“{”应与首行对齐。</FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;&nbsp;&nbsp; 变量定义最好通过添加空格形成对齐，同一类型的变量最好放在一起。如下例所示：<BR>int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Value;<BR>int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result;<BR>int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Length;<BR>DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Size;<BR>DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BufSize;</FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;个人认为此项可以依照个人习惯决定遵循与否。</FONT></P>
<P><FONT color=#0000ff size=2>4、空行</FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;不得存在无规则的空行，比如说连续十个空行。程序文件结构各部分之间空两行，若不必要也可只空一行，各函数实现之间一般空两行，由于每个函数还要有函数说明注释，故通常只需空一行或不空，但对于没有函数说明的情况至少应再空一行。对自己写的函数，建议也加上“//------”做分隔。函数内部数据与代码之间应空至少一行，代码中适当处应以空行空开，建议在代码中出现变量声明时，在其前空一行。类中四个“p”之间至少空一行，在其中的数据与函数之间也应空行。</FONT></P>
<P><FONT color=#0000ff size=2>5、注释</FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;注释是软件可读性的具体体现。程序注释量一般占程序编码量的20%，软件工程要求不少于20%。程序注释不能用抽象的语言，类似于"处理"、"循环"这样的计算机抽象语言，要精确表达出程序的处理说明。例如："计算净需求"、"计算第一道工序的加工工时"等。避免每行程序都使用注释，可以在一段程序的前面加一段注释，具有明确的处理逻辑。</FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;注释必不可少，但也不应过多，不要被动的为写注释而写注释。以下是四种必要的注释：<BR>&nbsp;<BR>A. 标题、附加说明。</FONT></P>
<P><FONT color=#0000ff size=2>B. 函数、类等的说明。对几乎每个函数都应有适当的说明，通常加在函数实现之前，在没有函数实现部分的情况下则加在函数原型前，其内容主要是函数的功能、目的、算法等说明，参数说明、返回值说明等，必要时还要有一些如特别的软硬件要求等说明。公用函数、公用类的声明必须由注解说明其使用方法和设计思路，当然选择恰当的命名格式能够帮助你把事情解释得更清楚。</FONT></P>
<P><FONT color=#0000ff size=2>C. 在代码不明晰或不可移植处必须有一定的说明。</FONT></P>
<P><FONT color=#0000ff size=2>D. 及少量的其它注释，如自定义变量的注释、代码书写时间等。</FONT></P>
<P><FONT color=#0000ff size=2>&nbsp; 注释有块注释和行注释两种，分别是指："/**/"和"//"建议对A用块注释，D用行注释，B、C则视情况而定，但应统一，至少在一个单元中B类注释形式应统一。具体对不同文件、结构的注释会在后面详细说明。</FONT></P>
<P><FONT color=#0000ff size=2>6、代码长度</FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;对于每一个函数建议尽可能控制其代码长度为53行左右，超过53行的代码要重新考虑将其拆分为两个或两个以上的函数。函数拆分规则应该一不破坏原有算法为基础，同时拆分出来的部分应该是可以重复利用的。对于在多个模块或者窗体中都要用到的重复性代码，完全可以将起独立成为一个具备公用性质的函数，放置于一个公用模块中。</FONT></P>
<P><FONT color=#0000ff size=2>7、页宽</FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;页宽应该设置为80字符。源代码一般不会超过这个宽度, 并导致无法完整显示, 但这一设置也可以灵活调整. 在任何情况下, 超长的语句应该在一个逗号或者一个操作符后折行. 一条语句折行后, 应该比原来的语句再缩进2个字符. </FONT></P>
<P><FONT color=#0000ff size=2>8、行数</FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;一般的集成编程环境下，每屏大概只能显示不超过50行的程序，所以这个函数大概要5-6屏显示，在某些环境下要8屏左右才能显示完。这样一来，无论是读程序还是修改程序，都会有困难。因此建议把完成比较独立功能的程序块抽出，单独成为一个函数。把完成相同或相近功能的程序块抽出，独立为一个子函数。可以发现，越是上层的函数越简单，就是调用几个子函数，越是底层的函数完成的越是具体的工作。这是好程序的一个标志。这样，我们就可以在较上层函数里容易控制整个程序的逻辑，而在底层的函数里专注于某方面的功能的实现了。</FONT></P>
<P><BR><FONT color=#0000ff size=2>三、代码文件风格</FONT></P>
<P><FONT color=#0000ff size=2>所有的 Java(*.java) 文件都必须遵守如下的样式规则：</FONT></P>
<P><FONT color=#0000ff size=2>. 文件生成</FONT></P>
<P><FONT color=#0000ff size=2>对于规范的 JAVA 派生类，尽量用 JBuilder 的 Object Gallery 工具来生成文件格式，避免用手工制作的头文件/实现文件。<BR>&nbsp;<BR>. package/import </FONT></P>
<P><FONT color=#0000ff size=2>package 行要在 import 行之前，import 中标准的包名要在本地的包名之前，而且按照字母顺序排列。如果 import 行中包含了同一个包中的不同子目录，则应该用 * 来处理。 </FONT></P>
<P><FONT color=#0000ff size=2>package hotlava.net.stats;</FONT></P>
<P><FONT color=#0000ff size=2>import java.io.*;<BR>import java.util.Observable;<BR>import hotlava.util.Application;&nbsp; <BR>&nbsp;<BR>这里 java.io.* 使用来代替InputStream and OutputStream 的。</FONT></P>
<P><FONT color=#0000ff size=2>. 文件头部注释</FONT></P>
<P><FONT color=#0000ff size=2>文件头部注释主要是表明该文件的一些信息，是程序的总体说明，可以增强程序的可读性和可维护性。文件头部注释一般位于 package/imports 语句之后，Class 描述之前。要求至少写出文件名、创建者、创建时间和内容描述。JBuilder 的 Object Gallery 工具生成的代码中会在类、工程文件中等自动添加注释，我们也要添加一些注释，其格式应该尽量约束如下：</FONT></P>
<P><FONT color=#0000ff size=2>/**<BR>&nbsp;* Title:&nbsp; 确定鼠标位置类<BR>&nbsp;* Description: 确定鼠标当前在哪个作业栏位中并返回作业号<BR>&nbsp;* @Copyright: Copyright (c) 2002<BR>&nbsp;* @Company: HIT<BR>&nbsp;* @author: rivershan<BR>&nbsp;* @version: 1.0<BR>&nbsp;* @time: 2002.10.30<BR>&nbsp;*/<BR>&nbsp;<BR>. Class </FONT></P>
<P><FONT color=#0000ff size=2>接下来的是类的注释，一般是用来解释类的。 </FONT></P>
<P><FONT color=#0000ff size=2>/**<BR>&nbsp;* A class representing a set of packet and byte counters<BR>&nbsp;* It is observable to allow it to be watched, but only<BR>&nbsp;* reports changes when the current set is complete<BR>&nbsp;*/ <BR>&nbsp;<BR>接下来是类定义，包含了在不同的行的 extends 和 implements </FONT></P>
<P><FONT color=#0000ff size=2>public class CounterSet<BR>&nbsp; extends Observable<BR>&nbsp; implements Cloneable </FONT></P>
<P><FONT color=#0000ff size=2>.Class Fields </FONT></P>
<P><FONT color=#0000ff size=2>接下来是类的成员变量： </FONT></P>
<P><FONT color=#0000ff size=2>/**<BR>&nbsp;* Packet counters<BR>&nbsp;*/<BR>&nbsp;<BR>protected int[] packets;<BR>&nbsp;<BR>public 的成员变量必须生成文档（JavaDoc）。proceted、private和 package 定义的成员变量如果名字含义明确的话，可以没有注释。</FONT></P>
<P><FONT color=#0000ff size=2>. 存取方法<BR>&nbsp;<BR>接下来是类变量的存取的方法。它只是简单的用来将类的变量赋值获取值的话，可以简单的写在一行上。（个人认为尽量分行写）</FONT></P>
<P><FONT color=#0000ff size=2>/**<BR>&nbsp;* Get the counters<BR>&nbsp;* @return an array containing the statistical data.&nbsp; This array has been<BR>&nbsp;* freshly allocated and can be modified by the caller.<BR>&nbsp;*/<BR>&nbsp;<BR>public int[] getPackets() <BR>{<BR>&nbsp; return copyArray(packets, offset); <BR>}</FONT></P>
<P><FONT color=#0000ff size=2>public int[] getBytes() <BR>{ <BR>&nbsp;return copyArray(bytes, offset); <BR>}</FONT></P>
<P><FONT color=#0000ff size=2>public int[] getPackets() <BR>{ <BR>&nbsp;return packets; <BR>}</FONT></P>
<P><FONT color=#0000ff size=2>public void setPackets(int[] packets) <BR>{ <BR>&nbsp;this.packets = packets; <BR>}<BR>&nbsp;<BR>其它的方法不要写在一行上</FONT></P>
<P><FONT color=#0000ff size=2>. 构造函数 </FONT></P>
<P><FONT color=#0000ff size=2>接下来是构造函数，它应该用递增的方式写（比如：参数多的写在后面）。 </FONT></P>
<P><FONT color=#0000ff size=2>访问类型("public","private" 等.)和任何"static","final"或"synchronized"应该在一行中，并且方法和参数另写一行，这样可以使方法和参数更易读。 </FONT></P>
<P><FONT color=#0000ff size=2>public<BR>CounterSet(int size)<BR>{<BR>&nbsp;&nbsp; this.size = size;<BR>}</FONT></P>
<P><FONT color=#0000ff size=2>. 克隆方法<BR>&nbsp;<BR>如果这个类是可以被克隆的，那么下一步就是 clone 方法： </FONT></P>
<P><FONT color=#0000ff size=2>public<BR>Object clone()<BR>{<BR>&nbsp;try <BR>&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp; CounterSet obj = (CounterSet)super.clone();<BR>&nbsp;&nbsp;&nbsp;&nbsp; obj.packets = (int[])packets.clone();<BR>&nbsp;&nbsp;&nbsp;&nbsp; obj.size = size;<BR>&nbsp;&nbsp;&nbsp;&nbsp; return obj;<BR>&nbsp;&nbsp; }&nbsp; <BR>&nbsp;&nbsp; catch(CloneNotSupportedException e) <BR>&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp; throw new InternalError("Unexpected CloneNotSUpportedException: " <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + e.getMessage());<BR>&nbsp;&nbsp; }<BR>} </FONT></P>
<P><FONT color=#0000ff size=2>. 类方法 </FONT></P>
<P><FONT color=#0000ff size=2>下面开始写类的方法： </FONT></P>
<P><FONT color=#0000ff size=2>/**<BR>&nbsp;* Set the packet counters<BR>&nbsp;* (such as when restoring from a database)<BR>&nbsp;*/<BR>protected final<BR>void setArray(int[] r1, int[] r2, int[] r3, int[] r4)<BR>&nbsp; throws IllegalArgumentException<BR>{<BR>&nbsp;//<BR>&nbsp;&nbsp; // Ensure the arrays are of equal size<BR>&nbsp;&nbsp; //<BR>&nbsp;&nbsp; if (r1.length != r2.length || r1.length != r3.length || r1.length != r4.length)<BR>&nbsp; throw new IllegalArgumentException("Arrays must be of the same size";<BR>&nbsp;&nbsp; System.arraycopy(r1, 0, r3, 0, r1.length);<BR>&nbsp;&nbsp; System.arraycopy(r2, 0, r4, 0, r1.length);<BR>} </FONT></P>
<P><FONT color=#0000ff size=2>. toString 方法 </FONT></P>
<P><FONT color=#0000ff size=2>无论如何，每一个类都应该定义 toString 方法： </FONT></P>
<P><FONT color=#0000ff size=2>public<BR>String toString()<BR>{<BR>&nbsp;String retval = "CounterSet: ";<BR>&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; data.length(); i++) <BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval += data.bytes.toString();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retval += data.packets.toString();<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; return retval;<BR>}</FONT></P>
<P><FONT color=#0000ff size=2>. main 方法 </FONT></P>
<P><FONT color=#0000ff size=2>如果main(String[]) 方法已经定义了, 那么它应该写在类的底部. </FONT></P>
<P><BR><FONT color=#0000ff size=2>四、函数编写风格</FONT></P>
<P><FONT color=#0000ff size=2>. 函数的命名</FONT></P>
<P><FONT color=#0000ff size=2>通常，函数的命名也是以能表达函数的动作意义为原则的，一般是由动词打头，然后跟上表示动作对象的名词，各单词的首字母应该大写。另外，还有一些函数命名的通用规则。如取数，则用Get打头，然后跟上要取的对象的名字；设置数，则用Set打头，然后跟上要设的对象的名字；而对象中为了响应消息进行动作的函数，可以命名为On打头，然后是相应的消息的名称；进行主动动作的函数，可以命名为Do打头，然后是相应的动作名称。类似的规则还有很多，需要程序员多读优秀的程序，逐渐积累经验，才能作出好的函数命名。</FONT></P>
<P><FONT color=#0000ff size=2>. 函数注释</FONT></P>
<P><FONT color=#0000ff size=2>系统自动生成的函数，如鼠标动作响应函数等，不必太多的注释和解释；</FONT></P>
<P><FONT color=#0000ff size=2>对于自行编写的函数，若是系统关键函数，则必须在函数实现部分的上方标明该函数的信息，格式如下：</FONT></P>
<P><FONT color=#0000ff size=2>/**<BR>* 函数名：<BR>* 编写者：<BR>* 参考资料：<BR>* 功&nbsp; 能：<BR>* 输入参数：<BR>* 输出参数：<BR>* 备&nbsp; 注：<BR>*/</FONT></P>
<P><FONT color=#0000ff size=2>希望尽量遵循以上格式。</FONT></P>
<P><BR><FONT color=#0000ff size=2>五、符号风格</FONT></P>
<P><FONT color=#0000ff size=2>. 总体要求</FONT></P>
<P><FONT color=#0000ff size=2>对于各种符号的定义，都有一个共通点，就是应该使用有实际意义的英文单词或英文单词的缩写，不要使用简单但没有意义的字串，尽可能不使用阿拉伯数字，更切忌使用中文拼音的首字母。如这样的名称是不提倡的：Value1,Value2,Value3,Value4 …。</FONT></P>
<P><FONT color=#0000ff size=2>例如：<BR>file(文件),code(编号),data(数据),pagepoint(页面指针), faxcode(传真号) ,address(地址),bank(开户银行),……</FONT></P>
<P><FONT color=#0000ff size=2>. 变量名称</FONT></P>
<P><FONT color=#0000ff size=2>变量命名由（前缀+修饰语）构成。现在比较流行的是一套由微软的一个匈牙利软件工程师首先使用，并且在微软推广开来，现在被称之为匈牙利命名法的命名规则。匈牙利命名法规定，使用表示标识符所对应的变量类型的英文小写缩写作为标识符的前缀，后面在使用表示变量意义的英文单词或缩写进行命名。下面是匈牙利命名法中的一些命名方式：</FONT></P>
<P><FONT color=#0000ff size=2>（1）生存期修饰：用l(local)表示局域变量，p(public)表示全局变量，s(send)表示参数变量</FONT></P>
<P><FONT color=#0000ff size=2>（2）类型修饰：用s(AnsiString)表示字符串,c(char)表示字符,n(number)数值,i(intger)表示整数,d(double)表示双精度,f(float)浮点型,b(bool)布尔型,d(date)表示日期型.</FONT></P>
<P><FONT color=#0000ff size=2>例如：<BR>li_length表示整形的局域变量,是用来标识长度的.ls_code表示字符型的局域变量,用来标识代码.</FONT></P>
<P><FONT color=#0000ff size=2>. 控件名称</FONT></P>
<P><FONT color=#0000ff size=2>控件命名由（前缀+修饰语）构成。前缀即为控件的名称。</FONT></P>
<P><FONT color=#0000ff size=2>按钮变量&nbsp; Button+Xxxxxxx&nbsp;&nbsp;&nbsp; 例如：ButtonSave,ButtonExit,ButtonPrint等<BR>题标变量&nbsp; Label+Xxxxxxxx&nbsp;&nbsp;&nbsp; 例如：LabelName,LabelSex等<BR>数据表变量 Table+Xxxxxx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例如：TableFile,TableCount等<BR>查询变量&nbsp; Query+Xxxxxx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例如：QueryFile,QueryCeneter等<BR>数据源变量 DataSource+Xxx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例如：DataSourceFile,DataSourceCenter等<BR>。。。。。。。。。。。。。。。。<BR>(注：对于与表有关的控件“修饰语”部分最好直接用表名。)</FONT></P>
<P><FONT color=#0000ff size=2>. Package 的命名 </FONT></P>
<P><FONT color=#0000ff size=2>Package 的名字应该都是由一个小写单词组成。 </FONT></P>
<P><FONT color=#0000ff size=2>. Class 的命名 </FONT></P>
<P><FONT color=#0000ff size=2>Class 的名字必须由一个或数个能表达该类的意思的大写字母开头而其它字母都小写的单词或缩写组成，这样能使这个 Class 的名称能更容易被理解。</FONT></P>
<P><FONT color=#0000ff size=2>. Class 变量的命名 </FONT></P>
<P><FONT color=#0000ff size=2>变量的名字必须用一个小写字母开头。后面的单词用大写字母开头。对于类的成员变量，在对其标识符命名时，要加上代表member（成员）的前缀m_。例如一个标识符为m_dwFlag，则它表示的变量是一个类型为双字的成员变量，它是代表一个标志。</FONT></P>
<P><FONT color=#0000ff size=2>. Static Final 变量的命名 </FONT></P>
<P><FONT color=#0000ff size=2>Static Final 变量的名字应该都大写，并且指出完整含义。 </FONT></P>
<P><FONT color=#0000ff size=2>. 参数的命名 </FONT></P>
<P><FONT color=#0000ff size=2>参数的名字必须和变量的命名规范一致。 </FONT></P>
<P><FONT color=#0000ff size=2>. 数组的命名 </FONT></P>
<P><FONT color=#0000ff size=2>数组应该总是用下面的方式来命名：<BR>byte[] buffer;&nbsp; <BR>&nbsp;<BR>而不是： <BR>byte buffer[]; </FONT></P>
<P><FONT color=#0000ff size=2>. 方法的参数<BR>&nbsp;<BR>使用有意义的参数命名，如果可能的话，使用和要赋值的字段一样的名字： </FONT></P>
<P><FONT color=#0000ff size=2>SetCounter(int size)<BR>{<BR>&nbsp;this.size = size;<BR>} </FONT></P>
<P><FONT color=#0000ff size=2>. 神秘的数</FONT></P>
<P><FONT color=#0000ff size=2>首先要说什么是神秘的数。我们在程序里经常会用到一些量，它是有特定的含义的。例如，现在我们写一个薪金统计程序，公司员工有50人，我们在程序里就会用50这个数去进行各种各样的运算。在这里，50就是"神秘的数"。为什么称它为神秘呢？因为别的程序员在程序里看到50这个数，不知道它的含义，只能靠猜了。</FONT></P>
<P><FONT color=#0000ff size=2>在程序里出现"神秘的数"会降低程序的可读性，应该尽量避免。避免的方法是把神秘的数定义为一个常量。注意这个常量的命名应该能表达该数的意义，并且应该全部大写，以与对应于变量的标识符区别开来。例如上面50这个数，我们可以定义为一个名为NUMOFEMPLOYEES的常量来代替。这样，别的程序员在读程序的时候就可以容易理解了。</FONT></P>
<P><FONT color=#0000ff size=2>六、程序编写风格</FONT></P>
<P><FONT color=#0000ff size=2>. exit() </FONT></P>
<P><FONT color=#0000ff size=2>exit 除了在 main 中可以被调用外，其他的地方不应该调用。因为这样做不给任何代码代码机会来截获退出。一个类似后台服务地程序不应该因为某一个库模块决定了要退出就退出。 </FONT></P>
<P><FONT color=#0000ff size=2>. 异常 </FONT></P>
<P><FONT color=#0000ff size=2>申明的错误应该抛出一个RuntimeException或者派生的异常。 <BR>顶层的main()函数应该截获所有的异常，并且打印（或者记录在日志中）在屏幕上。 </FONT></P>
<P><FONT color=#0000ff size=2>. 垃圾收集 </FONT></P>
<P><FONT color=#0000ff size=2>JAVA使用成熟的后台垃圾收集技术来代替引用计数。但是这样会导致一个问题：你必须在使用完对象的实例以后进行清场工作。比如一个prel的程序员可能这么写： </FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;...<BR>&nbsp;{<BR>&nbsp; FileOutputStream fos = new FileOutputStream(projectFile);<BR>&nbsp; project.save(fos, "IDE Project File"; <BR>&nbsp;}<BR>&nbsp;...<BR>&nbsp;<BR>除非输出流一出作用域就关闭，非引用计数的程序语言，比如JAVA，是不能自动完成变量的清场工作的。必须象下面一样写： </FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;FileOutputStream fos = new FileOutputStream(projectFile);<BR>&nbsp;project.save(fos, "IDE Project File"; <BR>&nbsp;fos.close();</FONT></P>
<P><FONT color=#0000ff size=2>. Clone </FONT></P>
<P><FONT color=#0000ff size=2>下面是一种有用的方法： <BR>implements Cloneable</FONT></P>
<P><FONT color=#0000ff size=2>public<BR>Object clone()<BR>{<BR>&nbsp;try <BR>&nbsp;{<BR>&nbsp; ThisClass obj = (ThisClass)super.clone();<BR>&nbsp; obj.field1 = (int[])field1.clone();<BR>&nbsp; obj.field2 = field2;<BR>&nbsp; return obj;<BR>&nbsp;} <BR>&nbsp;catch(CloneNotSupportedException e) <BR>&nbsp;{<BR>&nbsp; throw new InternalError("Unexpected CloneNotSUpportedException: " + e.getMessage());<BR>&nbsp;}<BR>} </FONT></P>
<P><FONT color=#0000ff size=2>. final 类 </FONT></P>
<P><FONT color=#0000ff size=2>绝对不要因为性能的原因将类定义为 final 的（除非程序的框架要求） <BR>如果一个类还没有准备好被继承，最好在类文档中注明，而不要将她定义为 final 的。这是因为没有人可以保证会不会由于什么原因需要继承她。<BR>&nbsp;<BR>. 访问类的成员变量<BR>&nbsp;<BR>大部分的类成员变量应该定义为 protected 的来防止继承类使用他们。 <BR>注意，要用"int[] packets"，而不是"int packets[]"，后一种永远也不要用。 </FONT></P>
<P><FONT color=#0000ff size=2>public void setPackets(int[] packets) <BR>{ <BR>&nbsp;this.packets = packets; <BR>}<BR>CounterSet(int size)<BR>{<BR>&nbsp;this.size = size;<BR>}</FONT></P>
<P><FONT color=#0000ff size=2>. byte 数组转换到 characters </FONT></P>
<P><FONT color=#0000ff size=2>为了将 byte 数组转换到 characters，你可以这么做： </FONT></P>
<P><FONT color=#0000ff size=2>"Hello world!".getBytes(); </FONT></P>
<P><FONT color=#0000ff size=2>. Utility 类 </FONT></P>
<P><FONT color=#0000ff size=2>Utility 类（仅仅提供方法的类）应该被申明为抽象的来防止被继承或被初始化。 </FONT></P>
<P><FONT color=#0000ff size=2>. 初始化<BR>&nbsp;<BR>下面的代码是一种很好的初始化数组的方法： </FONT></P>
<P><FONT color=#0000ff size=2>objectArguments = new Object[] <BR>{ <BR>&nbsp;arguments <BR>}; </FONT></P>
<P><FONT color=#0000ff size=2>. 枚举类型<BR>&nbsp;<BR>JAVA 对枚举的支持不好，但是下面的代码是一种很有用的模板： </FONT></P>
<P><FONT color=#0000ff size=2>class Colour <BR>{<BR>&nbsp;&nbsp; public static final Colour BLACK = new Colour(0, 0, 0);<BR>&nbsp;&nbsp; public static final Colour RED = new Colour(0xFF, 0, 0);<BR>&nbsp;&nbsp; public static final Colour GREEN = new Colour(0, 0xFF, 0);<BR>&nbsp;&nbsp; public static final Colour BLUE = new Colour(0, 0, 0xFF);<BR>&nbsp;&nbsp; public static final Colour WHITE = new Colour(0xFF, 0xFF, 0xFF);<BR>}<BR>&nbsp;<BR>这种技术实现了RED, GREEN, BLUE 等可以象其他语言的枚举类型一样使用的常量。 他们可以用 '==' 操作符来比较。 <BR>但是这样使用有一个缺陷：如果一个用户用这样的方法来创建颜色 BLACK </FONT></P>
<H1><FONT color=#0000ff>new Colour(0,0,0) </FONT></H1>
<P><FONT color=#0000ff size=2>那么这就是另外一个对象，'=='操作符就会产生错误。她的 equal() 方法仍然有效。由于这个原因，这个技术的缺陷最好注明在文档中，或者只在自己的包中使用。</FONT></P>
<P><FONT color=#0000ff size=2>. 混合使用 AWT 和 Swing 组件 </FONT></P>
<P><FONT color=#0000ff size=2>如果要将 AWT 组件和 Swing 组件混合起来使用的话，请小心使用。实际上，尽量不要将他们混合起来使用。 </FONT></P>
<P><FONT color=#0000ff size=2>. 滚动的 AWT 组件 </FONT></P>
<P><FONT color=#0000ff size=2>AWT 组件绝对不要用 JscrollPane 类来实现滚动。滚动 AWT 组件的时候一定要用 AWT ScrollPane 组件来实现。</FONT></P>
<P><FONT color=#0000ff size=2>. 避免在 InternalFrame 组件中使用 AWT 组件<BR>&nbsp;<BR>尽量不要这么做，要不然会出现不可预料的后果。 </FONT></P>
<P><FONT color=#0000ff size=2>. Z-Order 问题 </FONT></P>
<P><FONT color=#0000ff size=2>AWT 组件总是显示在 Swing 组件之上。当使用包含 AWT 组件的 POP-UP 菜单的时候要小心，尽量不要这样使用。 </FONT></P>
<P><BR><FONT color=#0000ff size=2>八、性能 </FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;在写代码的时候，从头至尾都应该考虑性能问题。这不是说时间都应该浪费在优化代码上，而是我们时刻应该提醒自己要注意代码的效率。比如：如果没有时间来实现一个高效的算法，那么我们应该在文档中记录下来，以便在以后有空的时候再来实现她。 </FONT></P>
<P><FONT color=#0000ff size=2>&nbsp;不是所有的人都同意在写代码的时候应该优化性能这个观点的，他们认为性能优化的问题应该在项目的后期再去考虑，也就是在程序的轮廓已经实现了以后。 </FONT></P>
<P><FONT color=#0000ff size=2>. 不必要的对象构造 </FONT></P>
<P><FONT color=#0000ff size=2>不要在循环中构造和释放对象 </FONT></P>
<P><FONT color=#0000ff size=2>. 使用 StringBuffer 对象 </FONT></P>
<P><FONT color=#0000ff size=2>在处理 String 的时候要尽量使用 StringBuffer 类，StringBuffer 类是构成 String 类的基础。String 类将 StringBuffer 类封装了起来，（以花费更多时间为代价）为开发人员提供了一个安全的接口。当我们在构造字符串的时候，我们应该用 StringBuffer 来实现大部分的工作，当工作完成后将 StringBuffer 对象再转换为需要的 String 对象。比如：如果有一个字符串必须不断地在其后添加许多字符来完成构造，那么我们应该使用 StringBuffer 对象和她的 append() 方法。如果我们用 String 对象代替 StringBuffer 对象的话，会花费许多不必要的创建和释放对象的 CPU 时间。 </FONT></P>
<P><FONT color=#0000ff size=2>. 避免太多的使用 synchronized 关键字 </FONT></P>
<P><FONT color=#0000ff size=2>避免不必要的使用关键字 synchronized，应该在必要的时候再使用她，这是一个避免死锁的好方法。</FONT></P>
<P><FONT color=#0000ff size=2>&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;&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;&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;&nbsp;&nbsp;&nbsp; rivershan 原创于2002.11.5<BR></FONT></P><img src ="http://www.blogjava.net/adidas1981/aggbug/7132.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/adidas1981/" target="_blank">小浩</a> 2005-07-05 13:44 <a href="http://www.blogjava.net/adidas1981/articles/7132.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSP/Servlet 中的汉字编码问题(转）</title><link>http://www.blogjava.net/adidas1981/articles/7115.html</link><dc:creator>小浩</dc:creator><author>小浩</author><pubDate>Tue, 05 Jul 2005 01:39:00 GMT</pubDate><guid>http://www.blogjava.net/adidas1981/articles/7115.html</guid><wfw:comment>http://www.blogjava.net/adidas1981/comments/7115.html</wfw:comment><comments>http://www.blogjava.net/adidas1981/articles/7115.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/adidas1981/comments/commentRss/7115.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/adidas1981/services/trackbacks/7115.html</trackback:ping><description><![CDATA[<CENTER>
<TABLE height=170 width="80%" border=0>
<TBODY>
<TR>
<TD width="80%" height=10></TD></TR>
<TR>
<TD width="80%" bgColor=#7b28bd><FONT size=2><A href="http://ub1010.51.net/"><FONT color=#32a4b8><IMG height=26 src="http://ub1010.51.net/BBS/images/zilongtan.jpg" width=61 border=0></FONT></A> <FONT color=#32a4b8>&nbsp;&nbsp;<IMG height=16 src="http://ub1010.51.net/BBS/user_file/images/folder1.gif" width=16 border=0> <A href="http://ub1010.51.net/BBS/"><FONT color=#32a4b8>论坛 </A>&gt;&gt; 编程探讨&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</FONT><FONT color=#32a4b8><IMG src="http://ub1010.51.net/BBS/user_file/images/view.gif" border=0>&nbsp;阅读数：
<SCRIPT language=javascript src="../../view_count.php?file_ID=1024023069"></SCRIPT>
 1735</FONT></FONT></FONT></TD></TR>
<TR>
<TD width="80%" height=156><FONT size=2>
<CENTER><B><FONT size=3><B>JSP/Servlet 中的汉字编码问题(转）</B></FONT></B></CENTER><BR>作者：UB&nbsp;&nbsp;&nbsp;&nbsp;时间：2002-06-14 10:51:10&nbsp;<BR><BR>JSP/Servlet中的汉字编码问题(1) <BR><BR>[作者:不详添加时间:2001-9-68:12:47&gt; <BR><BR><BR> <BR><BR>网上就JSP/Servlet中DBCS字符编码问题有许多优秀的文章和讨论，本文对它们作一些整理，并结合IBMWebSphereApplicationServer3.5（WAS）的解决方法作一些说明，希望它不是多余的。 <BR><BR>内容： <BR>问题的起源 <BR>GB2312-80，GBK，GB18030-2000汉字字符集及Encoding <BR>中文转码时'?'、乱码的由来 <BR>JSP/Servlet汉字编码问题及在WAS中的解决办法 <BR>结束语 <BR><BR><BR>1.问题的起源 <BR><BR>每个国家（或区域）都规定了计算机信息交换用的字符编码集，如美国的扩展ASCII码,中国的GB2312-80，日本的JIS等，作为该国家/区域内信息处理的基础，有着统一编码的重要作用。字符编码集按长度分为SBCS（单字节字符集），DBCS（双字节字符集）两大类。早期的软件（尤其是操作系统），为了解决本地字符信息的计算机处理，出现了各种本地化版本（L10N），为了区分，引进了LANG,Codepage等概念。但是由于各个本地字符集代码范围重叠，相互间信息交换困难；软件各个本地化版本独立维护成本较高。因此有必要将本地化工作中的共性抽取出来，作一致处理，将特别的本地化处理内容降低到最少。这也就是所谓的国际化（I18N）。各种语言信息被进一步规范为Locale信息。处理的底层字符集变成了几乎包含了所有字形的Unicode。 <BR><BR>现在大部分具有国际化特征的软件核心字符处理都是以Unicode为基础的，在软件运行时根据当时的Locale/Lang/Codepage设置确定相应的本地字符编码设置，并依此处理本地字符。在处理过程中需要实现Unicode和本地字符集的相互转换，甚或以Unicode为中间的两个不同本地字符集的相互转换。这种方式在网络环境下被进一步延伸，任何网络两端的字符信息也需要根据字符集的设置转换成可接受的内容。 <BR><BR>Java语言内部是用Unicode表示字符的，遵守UnicodeV2.0。Java程序无论是从/往文件系统以字符流读/写文件，还是往URL连接写HTML信息，或从URL连接读取参数值，都会有字符编码的转换。这样做虽然增加了编程的复杂度，容易引起混淆，但却是符合国际化的思想的。 <BR><BR>从理论上来说，这些根据字符集设置而进行的字符转换不应该产生太多问题。而事实是由于应用程序的实际运行环境不同，Unicode和各个本地字符集的补充、完善，以及系统或应用程序实现的不规范，转码时出现的问题时时困扰着程序员和用户。 <BR><BR>2.GB2312-80，GBK，GB18030-2000汉字字符集及Encoding <BR><BR>其实解决JAVA程序中的汉字编码问题的方法往往很简单，但理解其背后的原因，定位问题，还需要了解现有的汉字编码和编码转换。 <BR><BR>GB2312-80是在国内计算机汉字信息技术发展初始阶段制定的，其中包含了大部分常用的一、二级汉字，和9区的符号。该字符集是几乎所有的中文系统和国际化的软件都支持的中文字符集，这也是最基本的中文字符集。其编码范围是高位0xa1－0xfe，低位也是0xa1-0xfe；汉字从0xb0a1开始，结束于0xf7fe； <BR><BR>GBK是GB2312-80的扩展，是向上兼容的。它包含了20902个汉字，其编码范围是0x8140-0xfefe，剔除高位0x80的字位。其所有字符都可以一对一映射到Unicode2.0，也就是说JAVA实际上提供了GBK字符集的支持。这是现阶段Windows和其它一些中文操作系统的缺省字符集，但并不是所有的国际化软件都支持该字符集，感觉是他们并不完全知道GBK是怎么回事。值得注意的是它不是国家标准，而只是规范。随着GB18030-2000国标的发布，它将在不久的将来完成它的历史使命。 <BR><BR>GB18030-2000(GBK2K)在GBK的基础上进一步扩展了汉字，增加了藏、蒙等少数民族的字形。GBK2K从根本上解决了字位不够，字形不足的问题。它有几个特点， <BR><BR>它并没有确定所有的字形，只是规定了编码范围，留待以后扩充。 <BR>编码是变长的，其二字节部分与GBK兼容；四字节部分是扩充的字形、字位，其编码范围是首字节0x81-0xfe、二字节0x30-0x39、三字节0x81-0xfe、四字节0x30-0x39。 <BR>它的推广是分阶段的，首先要求实现的是能够完全映射到Unicode3.0标准的所有字形。 <BR>它是国家标准，是强制性的。 <BR>现在还没有任何一个操作系统或软件实现了GBK2K的支持，这是现阶段和将来汉化的工作内容。 <BR>Unicode的介绍......就免了吧。 <BR><BR>JAVA支持的encoding中与中文编程相关的有：(有几个在JDK文档中未列出)ASCII7-bit,同ascii7 <BR>ISO8859-18-bit,同8859_1,ISO-8859-1,ISO_8859-1,latin1... <BR>GB2312-80同gb2312,gb2312-1980,EUC_CN,euccn,1381,Cp1381,1383,Cp1383,ISO2022CN,ISO2022CN_GB...... <BR>GBK(注意大小写),同MS936 <BR>UTF8UTF-8 <BR>GB18030(现在只有IBMJDK1.3.?有支持),同Cp1392,1392 <BR><BR><BR>JAVA语言采用Unicode处理字符.但从另一个角度来说，在java程序中也可以采用非Unicode的转码，重要的是保证程序入口和出口的汉字信息不失真。如完全采用ISO-8859-1来处理汉字也能达到正确的结果。网络上流行的许多解决方法，都属于这种类型。为了不致引起混淆，本文不对这种方法作讨论。 <BR><BR>3.中文转码时'?'、乱码的由来 <BR><BR>两个方向转换都有可能得到错误的结果： <BR><BR>Unicode--&gt;Byte,如果目标代码集不存在对应的代码，则得到的结果是0x3f. <BR>如： <BR>"\u00d6\u00ec\u00e9\u0046\u00bb\u00f9".getBytes("GBK")的结果是"?ìéF?ù",Hex值是3fa8aca8a6463fa8b4. <BR>仔细看一下上面的结果，你会发现\u00ec被转换为0xa8ac,\u00e9被转换为\xa8a6...它的实际有效位变长了！这是因为GB2312符号区中的一些符号被映射到一些公共的符号编码，由于这些符号出现在ISO-8859-1或其它一些SBCS字符集中，故它们在Unicode中编码比较靠前，有一些其有效位只有8位，和汉字的编码重叠(其实这种映射只是编码的映射，在显示时仔细不是一样的。Unicode中的符号是单字节宽，汉字中的符号是双字节宽).在Unicode\u00a0--\u00ff之间这样的符号有20个。了解这个特征非常重要！由此就不难理解为什么JAVA编程中，汉字编码的错误结果中常常会出现一些乱码(其实是符号字符),而不全是'?'字符,就比如上面的例子。 <BR><BR>Byte--&gt;Unicode,如果Byte标识的字符在源代码集不存在，则得到的结果是0xfffd. <BR>如： <BR>Byteba[&gt;={(byte)0x81,(byte)0x40,(byte)0xb0,(byte)0xa1};newString(ba,"gb2312"); <BR>结果是"?啊",hex值是"\ufffd\u554a".0x8140是GBK字符，按GB2312转换表没有对应的值，取\ufffd.(请注意：在显示该uniCode时，因为没有对应的本地字符，所以也适用上一种情况，显示为一个"?".) <BR><BR>实际编程中，JSP/Servlet程序得到错误的汉字信息，往往是这两个过程的叠加，有时甚至是两个过程叠加后反复作用的结果. <BR><BR>4.JSP/Servlet汉字编码问题及在WAS中的解决办法 <BR><BR>4.1常见的encoding问题的现象 <BR>网上常出现的JSP/Servletencoding问题一般都表现在browser或应用程序端，如: <BR>浏览器中看到的Jsp/Servlet页面中的汉字怎么都成了’?’? <BR>浏览器中看到的Servlet页面中的汉字怎么都成了乱码？ <BR>JAVA应用程序界面中的汉字怎么都成了方块？ <BR>Jsp/Servlet页面无法显示GBK汉字。 <BR>JSP页面中内嵌在<%...%>,<%=...%>等Tag包含的JAVAcode中的中文成了乱码，但页面的其它汉字是对的。 <BR>Jsp/Servlet不能接收form提交的汉字。 <BR>JSP/Servlet数据库读写无法获得正确的内容。 <BR>隐藏在这些问题后面的是各种错误的字符转换和处理（除第3个外，是因为Javafont设置错误引起的）。解决类似的字符encoding问题，需要了解Jsp/Servlet的运行过程，检查可能出现问题的各个点。 <BR><BR>4.2JSP/Servletweb编程时的encoding问题 <BR>运行于Java应用服务器的JSP/Servlet为Browser提供HTML内容，其过程如下图所示： <BR> <BR><IMG src="http://ub1010.51.net/BBS/user_file/2002-06-14/1024023015.gif"> <BR><BR>其中有字符编码转换的地方有: <BR><BR>JSP编译。Java应用服务器将根据JVM的file.encoding值读取JSP源文件，编译生成JAVA源文件，再根据file.encoding值写回文件系统。如果当前系统语言支持GBK，那么这时候不会出现encoding问题。如果是英文的系统，如LANG是en_US的Linux,AIX或Solaris，则要将JVM的file.encoding值置成GBK。系统语言如果是GB2312，则根据需要，确定要不要设置file.encoding，将file.encoding设为GBK可以解决潜在的GBK字符乱码问题 <BR><BR><BR>Java需要被编译为.class才能在JVM中执行，这个过程存在与a.同样的file.encoding问题。从这里开始servlet和jsp的运行就类似了，只不过Servlet的编译不是自动进行的。对于JSP程序,对产生的JAVA中间文件的编译是自动进行的(在程序中直接调用sun.tools.javac.Main类).因此如果在这一步出现问题的话,也要检查encoding和OS的语言环境，或者将内嵌在JSPJAVACode中的静态汉字转为Unicode,要么静态文本输出不要放在JAVAcode中。对于Servlet,javac编译时手工指定-encoding参数就可以了。 <BR><BR><BR>Servlet需要将HTML页面内容转换为browser可接受的encoding内容发送出去。依赖于各JAVAAppServer的实现方式，有的将查询Browser的accept-charset和accept-language参数或以其它猜的方式确定encoding值，有的则不管。因此采用固定encoding也许是最好的解决方法。对于中文网页，可在JSP或Servlet中设置contentType="text/html;charset=GB2312"；如果页面中有GBK字符，则设置为contentType="text/html;charset=GBK"，由于IE和Netscape对GBK的支持程度不一样，作这种设置时需要测试一下。 <BR>因为16位JAVAchar在网络传送时高8位会被丢弃，也为了确保Servlet页面中的汉字（包括内嵌的和servlet运行过程中得到的）是期望的内码，可以用PrintWriterout=res.getWriter()取代ServletOutputStreamout=res.getOutputStream().PrinterWriter将根据contentType中指定的charset作转换(ContentType需在此之前指定！);也可以用OutputStreamWriter封装ServletOutputStream类并用write(String)输出汉字字符串。 <BR>对于JSP，JAVAApplicationServer应当能够确保在这个阶段将嵌入的汉字正确传送出去。 <BR><BR><BR>这是解释URL字符encoding问题。如果通过get/post方式从browser返回的参数值中包含汉字信息，servlet将无法得到正确的值。SUN的J2SDK中，HttpUtils.parseName在解析参数时根本没有考虑browser的语言设置，而是将得到的值按byte方式解析。这是网上讨论得最多的encoding问题。因为这是设计缺陷，只能以bin方式重新解析得到的字符串；或者以hackHttpUtils类的方式解决。参考文章2均有介绍，不过最好将其中的中文encodingGB2312、CP1381都改为GBK，否则遇到GBK汉字时，还是会有问题。 <BR>ServletAPI2.3提供一个新的函数HttpServeletRequest.setCharacterEncoding用于在调用request.getParameter(“param_name”)前指定应用程序希望的encoding，这将有助于彻底解决这个问题。 <BR>4.3IBMWebsphereApplicationServer中的解决方法 <BR><BR>WebSphereApplicationServer对标准的ServletAPI2.x作了扩展，提供较好的多语言支持。运行在中文的操作系统中，可以不作任何设置就可以很好地处理汉字。下面的说明只是对WAS是运行在英文的系统中，或者需要有GBK支持时有效。 <BR><BR>上述c,d情况，WAS都要查询Browser的语言设置，在缺省状况下，zh,zh-cn等均被映射为JAVAencodingCP1381（注意：CP1381只是等同于GB2312的一个codepage，没有GBK支持）。这样做我想是因为无法确认Browser运行的操作系统是支持GB2312,还是GBK，所以取其小。但是实际的应用系统还是要求页面中出现GBK汉字，最著名的是朱总理名字中的“镕"(rong2，0xe946，\u9555)，所以有时还是需要将Encoding/Charset指定为GBK。当然WAS中变更缺省的encoding没有上面说的那么麻烦，针对a,b，参考文章5，在ApplicationServer的命令行参数中指定-Dfile.encoding=GBK即可；针对d，在ApplicationServer的命令行参数中指定-Ddefault.client.encoding=GBK。如果指定了-Ddefault.client.encoding=GBK，那么c情况下可以不再指定charset。 <BR><BR>上面列出的问题中还有一个关于Tag<%...%>,<%=...%>中的JAVA代码里包含的静态文本未能正确显示的问题，在WAS中的解决方法是除了设置正确的file.encoding,还需要以相同方法设置-Duser.language=zh-Duser.region=CN。这与JAVAlocale的设置有关。 <BR><BR>4.4数据库读写时的encoding问题 <BR><BR>JSP/Servlet编程中经常出现encoding问题的另一个地方是读写数据库中的数据。 <BR><BR>流行的关系数据库系统都支持数据库encoding，也就是说在创建数据库时可以指定它自己的字符集设置，数据库的数据以指定的编码形式存储。当应用程序访问数据时，在入口和出口处都会有encoding转换。对于中文数据，数据库字符编码的设置应当保证数据的完整性.GB2312，GBK，UTF-8等都是可选的数据库encoding；也可以选择ISO8859-1(8-bit)，那么应用程序在写数据之前须将16Bit的一个汉字或Unicode拆分成两个8-bit的字符，读数据之后则需将两个字节合并起来，同时还要判别其中的SBCS字符。没有充分利用数据库encoding的作用，反而增加了编程的复杂度，ISO8859-1不是推荐的数据库encoding。JSP/Servlet编程时，可以先用数据库管理系统提供的管理功能检查其中的中文数据是否正确。 <BR><BR>然后应当注意的是读出来的数据的encoding，JAVA程序中一般得到的是Unicode。写数据时则相反。 <BR><BR>4.5定位问题时常用的技巧 <BR><BR>定位中文encoding问题通常采用最笨的也是最有效的办法——在你认为有嫌疑的程序处理后打印字符串的内码。通过打印字符串的内码，你可以发现什么时候中文字符被转换成Unicode，什么时候Unicode被转回中文内码，什么时候一个中文字成了两个Unicode字符，什么时候中文字符串被转成了一串问号，什么时候中文字符串的高位被截掉了…… <BR><BR>取用合适的样本字符串也有助于区分问题的类型。如：”aa啊aa丂aa”等中英相间、GB、GBK特征字符均有的字符串。一般来说，英文字符无论怎么转换或处理，都不会失真（如果遇到了，可以尝试着增加连续的英文字母长度）。 <BR><BR>5.结束语 <BR><BR>其实JSP/Servlet的中文encoding并没有想像的那么复杂，虽然定位和解决问题没有定规，各种运行环境也各不尽然，但后面的原理是一样的。了解字符集的知识是解决字符问题的基础。不过，随着中文字符集的变化，不仅仅是java编程，中文信息处理中的问题还是会存在一段时间的。 <BR><BR><BR><FONT size=2>...........................UB修改于2002-06-14 10:52:07</FONT> <BR></FONT>
<HR>
<FONT size=2><BR><BR>
<CENTER><B><FONT size=3><B><FONT color=blue>RE:</FONT>JAVA编程技术中汉字问题的分析及解决(转)</B></FONT></B></CENTER><BR>作者：UB&nbsp;&nbsp;&nbsp;&nbsp;时间：2002-07-22 17:04:00&nbsp;&nbsp;&nbsp;&nbsp;<A href="http://ub1010.51.net/BBS/article_update.php?file_ID=1024023069&amp;respond_ID=1027328640&amp;path_re=2002-06-14">[修改]</A>&nbsp;&nbsp;&nbsp;&nbsp;<A href="http://ub1010.51.net/BBS/article_respond.php?file_ID=1024023069&amp;user=UB&amp;bid=11&amp;subject=编程探讨&amp;path_re=2002-06-14">[回复]</A>&nbsp;&nbsp;&nbsp;&nbsp;<A onclick="javascript: if(confirm('你确定要删除吗？'))&#9;&#9;&#9;&#9;  return;&#9;&#9;  return false;" href="http://ub1010.51.net/BBS/del_respond.php?file_ID=1024023069&amp;user=UB&amp;bid=11&amp;subject=编程探讨&amp;path_re=2002-06-14&amp;respond_ID=1027328640">[删除]</A><BR><BR>JAVA编程技术中汉字问题的分析及解决 <BR>文章来源：www.ibm.com <BR>在基于Java语言的编程中，我们经常碰到汉字的处理及显示的问题。一大堆看不懂的乱码肯定不是我们愿意看到的显示效果，怎样才能够让那些汉字正确显示呢？Java语言默认的编码方式是UNICODE，而我们中国人通常使用的文件和数据库都是基于GB2312或者BIG5等方式编码的，怎样才能够恰当地选择汉字编码方式并正确地处理汉字的编码呢？本文将从汉字编码的常识入手，结合Java编程实例，分析以上两个问题并提出解决它们的方案。 <BR><BR>现在Java编程语言已经广泛应用于互联网世界，早在Sun公司开发Java语言的时候，就已经考虑到对非英文字符的支持了。Sun公司公布的Java运行环境（JRE）本身就分英文版和国际版，但只有国际版才支持非英文字符。不过在Java编程语言的应用中，对中文字符的支持并非如同JavaSoft的标准规范中所宣称的那样完美，因为中文字符集不只一个，而且不同的操作系统对中文字符的支持也不尽相同，所以会有许多和汉字编码处理有关的问题在我们进行应用开发中困扰着我们。有很多关于这些问题的解答，但都比较琐碎，并不能够满足大家迫切解决问题的愿望，关于Java中文问题的系统研究并不多，本文从汉字编码常识出发，分析Java中文问题，希望对大家解决这个问题有所帮助。 <BR><BR>汉字编码的常识 <BR>我们知道，英文字符一般是以一个字节来表示的，最常用的编码方法是ASCII。但一个字节最多只能区分256个字符，而汉字成千上万，所以现在都以双字节来表示汉字，为了能够与英文字符分开，每个字节的最高位一定为1，这样双字节最多可以表示64K格字符。我们经常碰到的编码方式有GB2312、BIG5、UNICODE等。关于具体编码方式的详细资料，有兴趣的读者可以查阅相关资料。我肤浅谈一下和我们关系密切的GB2312和UNICODE。GB2312码，中华人民共和国国家标准汉字信息交换用编码，是一个由中华人民共和国国家标准总局发布的关于简化汉字的编码，通行于中国大陆地区及新加坡，简称国标码。两个字节中，第一个字节（高字节）的值为区号值加32（20H），第二个字节（低字节）的值为位号值加32（20H），用这两个值来表示一个汉字的编码。UNICODE码是微软提出的解决多国字符问题的多字节等长编码，它对英文字符采取前面加“0”字节的策略实现等长兼容。如“A”的ASCII码为0x41，UNICODE就为0x00，0x41。利用特殊的工具各种编码之间可以互相转换。 <BR><BR>Java中文问题的初步认识 <BR>我们基于Java编程语言进行应用开发时，不可避免地要处理中文。Java编程语言默认的编码方式是UNICODE，而我们通常使用的数据库及文件都是基于GB2312编码的，我们经常碰到这样的情况：浏览基于JSP技术的网站看到的是乱码，文件打开后看到的也是乱码，被Java修改过的数据库的内容在别的场合应用时无法继续正确地提供信息。 <BR><BR>StringsEnglish=“apple”; <BR>StringsChinese=“苹果”; <BR>Strings=“苹果apple”; <BR><BR>sEnglish的长度是5，sChinese的长度是4，而s默认的长度是14。对于sEnglish来说，Java中的各个类都支持得非常好，肯定能够正确显示。但对于sChinese和s来说，虽然JavaSoft声明Java的基本类已经考虑到对多国字符的支持（默认UNICODE编码），但是如果操作系统的默认编码不是UNICODE，而是国标码等。从Java源代码到得到正确的结果，要经过“Java源代码-&gt;Java字节码-&gt;;虚拟机-&gt;操作系统-&gt;显示设备”的过程。在上述过程中的每一步骤，我们都必须正确地处理汉字的编码，才能够使最终的显示结果正确。 <BR><BR>“Java源代码-&gt;Java字节码”，标准的Java编译器javac使用的字符集是系统默认的字符集，比如在中文Windows操作系统上就是GBK,而在Linux操作系统上就是ISO-8859-1，所以大家会发现在Linux操作系统上编译的类中源文件中的中文字符都出了问题，解决的办法就是在编译的时候添加encoding参数，这样才能够与平台无关。用法是 <BR><BR>javac–encodingGBK。 <BR><BR>“Java字节码-&gt;虚拟机-&gt;操作系统”，Java运行环境（JRE）分英文版和国际版，但只有国际版才支持非英文字符。Java开发工具包（JDK）肯定支持多国字符，但并非所有的计算机用户都安装了JDK。很多操作系统及应用软件为了能够更好的支持Java，都内嵌了JRE的国际版本，为自己支持多国字符提供了方便。 <BR><BR>“操作系统-&gt;显示设备”，对于汉字来说，操作系统必须支持并能够显示它。英文操作系统如果不搭配特殊的应用软件的话，是肯定不能够显示中文的。 <BR><BR>还有一个问题，就是在Java编程过程中，对中文字符进行正确的编码转换。例如，向网页输出中文字符串的时候，不论你是用 <BR><BR>out.println(string);//string是含中文的字符串 <BR><BR>还是用 <BR><BR><%=string%>，都必须作UNICODE到GBK的转换，或者手动，或者自动。在JSP1.0中，可以定义输出字符集，从而实现内码的自动转换。用法是 <BR><BR><%@pageContentType=”text/html;charset=gb2312”%><BR><BR>但是在一些JSP版本中并没有提供对输出字符集的支持，（例如JSP0.92），这就需要手动编码输出了，方法非常多。最常用的方法是 <BR><BR>Strings1=request.getParameter(“keyword”); <BR>Strings2=newString(s1.getBytes(“ISO-8859-1”),”GBK”); <BR><BR>getBytes方法用于将中文字符以“ISO-8859-1”编码方式转化成字节数组，而“GBK”是目标编码方式。我们从以ISO-8859-1方式编码的数据库中读出中文字符串s1，经过上述转换过程，在支持GBK字符集的操作系统和应用软件中就能够正确显示中文字符串s2。 <BR><BR>Java中文问题的表层分析及处理 <BR><BR>背景 <BR>开发环境JDK1.15Vcafe2.0JPadPro <BR>服务器端NTIISSybaseSystemJconnect（JDBC） <BR>客户端IE5.0Pwin98 <BR><BR>CLASS文件存放在服务器端，由客户端的浏览器运行APPLET，APPLET只起调入FRAME类等主程序的作用。界面包括Textfield，TextArea，List，Choice等。 <BR><BR>I.取中文 <BR>用JDBC执行SELECT语句从服务器端读取数据（中文）后，将数据用APPEND方法加到TextArea（TA），不能正确显示。但加到List中时，大部分汉字却可正确显示。 <BR>将数据按“ISO-8859-1”编码方式转化为字节数组，再按系统缺省编码方式（DefaultCharacterEncoding）转化为STRING，即可在TA和List中正确显示。 <BR>程序段如下： <BR><BR>dbstr2=results.getString(1); <BR>//AfterreadingtheresultfromDBserver，convertingittostring. <BR>dbbyte1=dbstr2.getBytes(“iso-8859-1”); <BR>dbstr1=newString(dbbyte1); <BR><BR>在转换字符串时不采用系统默认编码方式，而直接采用“GBK”或者“GB2312”,在A和B两种情况下，从数据库取数据都没有问题。 <BR><BR>II.写中文到数据库 <BR>处理方式与“取中文”相逆，先将SQL语句按系统缺省编码方式转化为字节数组，再按“ISO-8859-1”编码方式转化为STRING，最后送去执行，则中文信息可正确写入数据库。 <BR><BR>程序段如下： <BR>sqlstmt=tf_input.getText(); <BR>//BeforesendingstatementtoDBserver，convertingittosqlstatement. <BR>dbbyte1=sqlstmt.getBytes(); <BR>sqlstmt=newString(dbbyte1,”iso-8859-1”); <BR>_stmt=_con.createStatement(); <BR>_stmt.executeUpdate(sqlstmt); <BR>…… <BR><BR>问题：如果客户机上存在CLASSPATH指向JDK的CLASSES.ZIP时（称为A情况），上述程序代码可正确执行。但是如果客户机只有浏览器，而没有JDK和CLASSPATH时（称为B情况），则汉字无法正确转换。 <BR><BR>我们的分析： <BR>1.经过测试，在A情况下，程序运行时系统的缺省编码方式为GBK或者GB2312。在B情况下，程序启动时浏览器的JAVA控制台中出现如下错误信息： <BR>Can'tfindresourceforsun.awt.windows.awtLocalization_zh_CN <BR>然后系统的缺省编码方式为“8859-1”。 <BR><BR>2.如果在转换字符串时不采用系统缺省编码方式，而是直接采用“GBK”或“GB2312”，则在A情况下程序仍然可正常运行，在B情况下，系统出现错误： <BR>UnsupportedEncodingException。 <BR><BR>3.在客户机上，把JDK的CLASSES.ZIP解压后，放在另一个目录中，CLASSPATH只包含该目录。然后一边逐步删除该目录中的.CLASS文件，另一边运行测试程序，最后发现在一千多个CLASS文件中，只有一个是必不可少的，该文件是：sun.io.CharToByteDoubleByte.class。 <BR><BR>将该文件拷到服务器端和其它的类放在一起，并在程序的开头IMPORT它，在B情况下程序仍然无法正常运行。 <BR><BR>4.在A情况下，如果在CLASSPTH中去掉sun.io.CharToByteDoubleByte.class，则程序运行时测得默认编码方式为“8859-1”，否则为“GBK”或“GB2312”。 <BR>如果JDK的版本为1.2以上的话，在B情况下遇到的问题得到了很好的解决，测试的步骤同上，有兴趣的读者可以尝试一下。 <BR><BR>Java中文问题的根源分析及解决 <BR>在简体中文MSWindows98+JDK1.3下，可以用System.getProperties()得到Java运行环境的一些基本属性，类PoorChinese可以帮助我们得到这些属性。 <BR>类PoorChinese的源代码： <BR><BR>publicclassPoorChinese{ <BR>publicstaticvoidmain(String[&gt;args){ <BR>System.getProperties().list(System.out); <BR>} <BR>} <BR><BR>执行javaPoorChinese后，我们会得到: <BR><BR>系统变量file.encoding的值为GBK，user.language的值为zh，user.region的值为CN，这些系统变量的值决定了系统默认的编码方式是GBK。 <BR><BR>在上述系统中，下面的代码将GB2312文件转换成Big5文件，它们能够帮助我们理解Java中汉字编码的转化: <BR><BR>importjava.io.*; <BR>importjava.util.*; <BR><BR>publicclassgb2big5{ <BR><BR>staticintiCharNum=0; <BR><BR>publicstaticvoidmain(String[&gt;args){ <BR>System.out.println("InputGB2312file,outputBig5file."); <BR>if(args.length!=2){ <BR>System.err.println("Usage:jviewgb2big5gbfilebig5file"); <BR>System.exit(1); <BR>} <BR>StringinputString=readInput(args[0&gt;); <BR>writeOutput(inputString,args[1&gt;); <BR>System.out.println("NumberofCharactersinfile:"+iCharNum+"."); <BR>} <BR><BR>staticvoidwriteOutput(Stringstr,StringstrOutFile){ <BR>try{ <BR>FileOutputStreamfos=newFileOutputStream(strOutFile); <BR>Writerout=newOutputStreamWriter(fos,"Big5"); <BR>out.write(str); <BR>out.close(); <BR>} <BR>catch(IOExceptione){ <BR>e.printStackTrace(); <BR>e.printStackTrace(); <BR>} <BR>} <BR><BR>staticStringreadInput(StringstrInFile){ <BR>StringBufferbuffer=newStringBuffer(); <BR>try{ <BR>FileInputStreamfis=newFileInputStream(strInFile); <BR>InputStreamReaderisr=newInputStreamReader(fis,"GB2312"); <BR>Readerin=newBufferedReader(isr); <BR>intch; <BR>while((ch=in.read())&gt;-1){ <BR>iCharNum+=1; <BR>buffer.append((char)ch); <BR>} <BR>in.close(); <BR>returnbuffer.toString(); <BR>} <BR>catch(IOExceptione){ <BR>e.printStackTrace(); <BR>returnnull; <BR>} <BR>} <BR>} <BR><BR>编码转化的过程如下： <BR><BR>ByteToCharGB2312CharToByteBig5 <BR>GB2312------------------&gt;Unicode-------------&gt;Big5 <BR><BR>执行javagb2big5gb.txtbig5.txt，如果gb.txt的内容是“今天星期三”，则得到的文件big5.txt中的字符能够正确显示；而如果gb.txt的内容是“情人节快乐”，则得到的文件big5.txt中对应于“节”和“乐”的字符都是符号“？”（0x3F），可见sun.io.ByteToCharGB2312和sun.io.CharToByteBig5这两个基本类并没有编好。 <BR><BR>正如上例一样，Java的基本类也可能存在问题。由于国际化的工作并不是在国内完成的，所以在这些基本类发布之前，没有经过严格的测试，所以对中文字符的支持并不像JavaSoft所声称的那样完美。前不久，我的一位技术上的朋友发信给我说，他终于找到了JavaServlet中文问题的根源。两周以来，他一直为JavaServlet的中文问题所困扰，因为每面对一个含有中文字符的字符串都必须进行强制转换才能够得到正确的结果（这好象是大家公认的唯一的解决办法）。后来，他确实不想如此继续安分下去了，因为这样的事情确实不应该是高级程序员所要做的工作，他就找出Servlet解码的源代码进行分析，因为他怀疑问题就出在解码这部分。经过四个小时的奋斗，他终于找到了问题的根源所在。原来他的怀疑是正确的，Servlet的解码部分完全没有考虑双字节，直接把%XX当作一个字符。（原来JavaSoft也会犯这幺低级的错误！） <BR>如果你对这个问题有兴趣或者遇到了同样的烦恼的话，你可以按照他的步骤对Servlet.jar进行修改： <BR><BR>找到源代码HttpUtils中的staticprivateStringparseName，在返回前将sb（StringBuffer）复制成bytebs[&gt;，然后returnnewString(bs,”GB2312”)。作上述修改后就需要自己解码了： <BR><BR>HashTableform=HttpUtils.parseQueryString(request.getQueryString())或者 <BR>form=HttpUtils.parsePostData(……) <BR><BR>千万别忘了编译后放到Servlet.jar里面。 <BR><BR>五、关于Java中文问题的总结 <BR>Java编程语言成长于网络世界，这就要求Java对多国字符有很好的支持。Java编程语言适应了计算的网络化的需求，为它能够在网络世界迅速成长奠定了坚实的基础。Java的缔造者（JavaSoft）已经考虑到Java编程语言对多国字符的支持，只是现在的解决方案有很多缺陷在里面，需要我们付诸一些补偿性的措施。而世界标准化组织也在努力把人类所有的文字统一在一种编码之中，其中一种方案是ISO10646，它用四个字节来表示一个字符。当然，在这种方案未被采用之前，还是希望JavaSoft能够严格地测试它的产品，为用户带来更多的方便。 <BR><BR>附一个用于从数据库和网络中取出中文乱码的处理函数，入参是有问题的字符串，出参是问题已经解决了的字符串。 <BR>StringparseChinese(Stringin) <BR>{ <BR>Strings=null; <BR>bytetemp[&gt;; <BR>if(in==null) <BR>{ <BR>System.out.println("Warn:Chinesenullfounded!"); <BR>returnnewString(""); <BR>} <BR>try <BR>{ <BR>temp=in.getBytes("iso-8859-1"); <BR>s=newString(temp); <BR>} <BR>catch(UnsupportedEncodingExceptione) <BR>{ <BR>System.out.println(e.toString()); <BR>} <BR>returns; <BR>} <BR> <BR>
<HR>
<BR><BR>
<CENTER><TITLE_RESPOND></CENTER><BR><TIME_USER_RESPOND><BR><BR><CONTENT_RESPOND></FONT></TD></TR></TBODY></TABLE></CENTER><img src ="http://www.blogjava.net/adidas1981/aggbug/7115.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/adidas1981/" target="_blank">小浩</a> 2005-07-05 09:39 <a href="http://www.blogjava.net/adidas1981/articles/7115.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>