??xml version="1.0" encoding="utf-8" standalone="yes"?>91久久亚洲,欧洲激情一区二区,午夜国产精品视频免费体验区http://www.aygfsteel.com/matthew2006/category/12638.htmlNo Buddha tree at all,And bright mirror nor.Now nothing at all,How dusts any more ? zh-cnTue, 27 Feb 2007 10:31:06 GMTTue, 27 Feb 2007 10:31:06 GMT60Java的内存泄漏-转脓(chung)http://www.aygfsteel.com/matthew2006/archive/2007/01/16/94114.htmlmatthewmatthewTue, 16 Jan 2007 01:56:00 GMThttp://www.aygfsteel.com/matthew2006/archive/2007/01/16/94114.htmlhttp://www.aygfsteel.com/matthew2006/comments/94114.htmlhttp://www.aygfsteel.com/matthew2006/archive/2007/01/16/94114.html#Feedback0http://www.aygfsteel.com/matthew2006/comments/commentRss/94114.htmlhttp://www.aygfsteel.com/matthew2006/services/trackbacks/94114.htmlJava的一个重要优点就是通过垃圾攉?Garbage CollectionQGC)自动理内存的回ӞE序员(sh)需要通过调用函数来释攑ֆ存。因此,很多E序员认为Java不存在内存泄漏问题,或者认为即使有内存泄漏也不是程序的责QQ而是GC或JVM的问题。其实,q种x(chng)是不正确的,因ؓ(f)Java也存在内存泄Ԍ但它的表CC++不同?随着来多的服务器E序采用Java技术,例如JSPQServletQ?EJB{,服务器程序往往长期q行。另外,在很多嵌入式pȝ中,内存的总量非常有限。内存泄露问题(sh)变得十分关键,即每次q行量泄漏Q长期运行之后,pȝ也是面(f)崩溃的危险?Java是如何管理内?Z(jin)判断Java中是否有内存泄露Q我们首先必M(jin)解Java是如何管理内存的。Java的内存管理就是对象的分配和释N题。在Java中,E序员需要通过关键字new为每个对象申请内存空?(基本cd除外)Q所有的对象都在?(Heap)中分配空间。另外,对象的释放是由GC军_和执行的。在Java中,内存的分配是q序完成的Q而内存的释放是有GC完成的,q种收支两条U的Ҏ(gu)实化了(jin)E序员的工作。但同时Q它也加重了(jin)JVM的工作。这也是JavaE序q行速度较慢的原因之一。因为,GCZ(jin)能够正确释放对象QGC必须监控每一个对象的q行状态,包括对象的申诗引用、被引用、赋值等QGC都需要进行监控?监视对象状态是Z(jin)更加准确地、及(qing)时地释放对象Q而释攑֯象的Ҏ(gu)原则是该对象不再被引用?Z(jin)更好理解GC的工作原理,我们可以对象考虑为有向图的顶点,引用关p考虑为图的有向边Q有向边从引用者指向被引对象。另外,每个U程对象可以作ؓ(f)一个图的v始顶点,例如大多E序从mainq程开始执行,那么该图是以mainq程点开始的一|?wi)。在q个有向图中Q根点可达的对象都是有效对象,GC不回收q些对象。如果某个对?(q通子?与这个根点不可?注意Q该图ؓ(f)有向?Q那么我们认?q些)对象不再被引用,可以被GC回收?以下Q我们D一个例子说明如何用有向图表C内存管理。对于程序的每一个时刻,我们都有一个有向图表示JVM的内存分配情c(din)以下右图,是左边E序q行到第6行的C意图?Java使用有向囄方式q行内存理Q可以消除引用@环的问题Q例如有三个对象Q相互引用,只要它们和根q程不可辄Q那么GC也是可以回收它们的。这U方式的优点是管理内存的_ֺ很高Q但是效率较低。另外一U常用的内存理技术是使用计数器,例如COM模型采用计数器方式管理构Ӟ它与有向囄比,_ֺ行低(很难处理循环引用的问?Q但执行效率很高?

什么是Java中的内存泄露
下面Q我们就可以描述什么是内存泄漏。在Java中,内存泄漏是存在一些被分配的对象,q些对象有下面两个特点,首先Q这些对象是可达的,卛_有向图中Q存在通\可以与其相连Q其ơ,q些对象是无用的Q即E序以后不会(x)再用这些对象。如果对象满两个条gQ这些对象就可以判定为Java中的内存泄漏Q这些对象不?x)被GC所回收Q然而它却占用内存?在C++中,内存泄漏的范围更大一些。有些对象被分配?jin)内存空_(d)然后却不可达Q由于C++中没有GCQ这些内存将永远收不回来。在Java中,q些不可辄对象都由GC负责回收Q因此程序员?sh)需要考虑q部分的内存泄露?通过分析Q我们得知,对于C++Q程序员需要自q理边和顶点,而对于JavaE序员只需要管理边可以了(jin)(不需要管理顶点的释放)。通过q种方式QJava提高?sh)(jin)编E的效率?因此Q通过以上分析Q我们知道在Java中也有内存泄漏,但范围比C++要小一些。因为Java从语a上保证,M对象都是可达的,所有的不可辑֯象都由GC理?对于E序员来_(d)GC基本是透明的,不可见的。虽?dng)我们只有几个函数可以讉KGCQ例如运行GC的函数System.gc()Q但是根据Java语言规范定义Q?该函C保证JVM的垃圾收集器一定会(x)执行。因为,不同的JVM实现者可能用不同的法理GC。通常QGC的线E的优先U别较低。JVM调用GC的策略也有很多种Q有的是内存?sh)用到达一定程度时QGC才开始工作,也有定时执行的,有的是^~执行GCQ有的是中断式执行GC。但通常来说Q我们不需要关?j)这些。除非在一些特定的场合QGC的执行媄(jing)响应用程序的性能Q例如对于基于Web的实时系l,如网l游戏等Q用户不希望GCH然中断应用E序执行而进行垃圑֛Ӟ那么我们需要调整GC的参敎ͼ让GC能够通过q缓的方式释攑ֆ存,例如垃圑֛收分解ؓ(f)一pd的小步骤执行QSun提供的HotSpot JVM支持这一Ҏ(gu)?

下面l出?jin)一个简单的内存泄露的例子。在q个例子中,我们循环甌Object对象Qƈ所甌的对象放入一个Vector中,如果我们仅仅释放引用本nQ那么Vector仍然引用该对象,所以这个对象对GC来说是不可回收的。因此,如果对象加入到Vector后,q必MVector中删除,最单的Ҏ(gu)是Vector对象讄为null?Vector v=new Vector(10); for (int i=1;i<100; i++) { Object o=new Object(); v.add(o); o=null; } //此时Q所有的Object对象都没有被释放Q因为变量v引用q些对象?如何(g)内存泄?最后一个重要的问题Q就是如何检Java的内存泄漏。目前,我们通常使用一些工h(g)查JavaE序的内存泄漏问题。市(jng)Z已有几种专业(g)查Java内存泄漏的工P它们的基本工作原理大同小异,都是通过监测JavaE序q行Ӟ所有对象的甌、释攄动作Q将内存理的所有信息进行统计、分析、可视化。开发h员将Ҏ(gu)q些信息判断E序是否有内存泄漏问题。这些工具包括Optimizeit ProfilerQJProbe ProfilerQJinSight , Rational 公司的Purify{?br /> (tng)
下面Q我们将单介lOptimizeit的基本功能和工作原理?Optimizeit Profiler版本4.11支持ApplicationQAppletQServlet和Romote Application四类应用Qƈ且可以支持大多数cd的JVMQ包括SUN JDKpdQIBM的JDKpdQ和Jbuilder的JVM{。ƈ且,该Y件是由Java~写Q因此它支持多种操作pȝ。Optimizeitpdq包括Thread Debugger和Code Coverage两个工具Q分别用于监运行时的线E状态和代码覆盖面?当设|好所有的参数?jin),我们可以在OptimizeIt环境下运行被程序,在程序运行过E中QOptimizeit可以监视内存的用曲U?如下?Q包括JVM甌的堆(heap)的大,和实际用的内存大小。另外,在运行过E中Q我们可以随时暂停程序的q行Q甚臛_行调用GCQ让GCq行内存回收。通过内存?sh)用曲线Q我们可以整体了(jin)解程序用内存的情况。这U监对于长期运行的应用E序非常有必要,也很Ҏ(gu)发现内存泄露?在运行过E中Q我们还可以从不同视角观查内存的使用情况QOptimizeit提供?jin)四U方式:(x) 堆视角?q是一个全面的视角Q我们可以了(jin)解堆中的所有的对象信息(数量和种c?Qƈq行l计、排序,qo(h)。了(jin)解相兛_象的变化情况?Ҏ(gu)视角。通过Ҏ(gu)视角Q我们可以得知每一U类的对象,都分配在哪些Ҏ(gu)中,以及(qing)它们的数量?对象视角。给定一个对象,通过对象视角Q我们可以显C它的所有出引用和入引用对象Q我们可以了(jin)解这个对象的所有引用关pR?引用图?l定一个根Q通过引用图,我们可以昄从该点出发的所有出引用?在运行过E中Q我们可以随时观察内存的使用情况Q通过q种方式Q我们可以很快找到那些长期不被释放,q且不再使用的对象。我们通过(g)查这些对象的生存周期Q确认其是否为内存泄霌Ӏ在实践当中Q寻扑ֆ存泄露是一仉帔R?ch)的事情Q它需要程序员Ҏ(gu)个程序的代码比较清楚Qƈ且需要丰富的调试l验Q但是这个过E对于很多关键的JavaE序都是十分重要的?lg所qͼJava也存在内存泄露问题,其原因主要是一些对象虽然不再被使用Q但它们仍然被引用。ؓ(f)?jin)解册些问题,我们可以通过软g工具来检查内存泄Ԍ(g)查的主要原理是暴露出所有堆中的对象Q让E序员寻N些无用但仍被引用的对象?

作者简?
Ƨ阳辎ͼ北京大学计算机硕士毕业,98qv开始研I基于java的Y件开发、测试,参与开发、测试过多个ZJava的应用程序和W(xu)eb服务目?
周欣Q北京大学计机pdd士生Q主要研I方向:(x)E序理解、逆向工程?qing)Y件度量,联系方式 zhouxin@sei.pku.edu.cn

matthew 2007-01-16 09:56 发表评论
]]>
Servlet容器工作原理讲解(2)Q{?/title><link>http://www.aygfsteel.com/matthew2006/archive/2006/12/06/85799.html</link><dc:creator>matthew</dc:creator><author>matthew</author><pubDate>Wed, 06 Dec 2006 04:37:00 GMT</pubDate><guid>http://www.aygfsteel.com/matthew2006/archive/2006/12/06/85799.html</guid><wfw:comment>http://www.aygfsteel.com/matthew2006/comments/85799.html</wfw:comment><comments>http://www.aygfsteel.com/matthew2006/archive/2006/12/06/85799.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/matthew2006/comments/commentRss/85799.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/matthew2006/services/trackbacks/85799.html</trackback:ping><description><![CDATA[HttpServer1 (tng)c?br /><br />此应用程序内的?tng)HttpServer1c?tng)与前文单的 (tng)WEB (tng)服务器应用程序中的HttpServer (tng)十分怼。但是,此应用程序内的?tng)HttpServer1 (tng)能服务静(rn)态资源和 (tng)servlet。如果要h一个静(rn)态资源,误入以下?tng)URLQ?br /><br /><b><a href="http://machinename:port/staticResource">http://machineName:port/staticResource</a> (tng)</b><br /><br />它就是前文中提到的怎样在?tng)WEB (tng)服务器应用程序里h?rn)态资源。如果要h一个?tng)servletQ请输入以下 (tng)URLQ?br /><br /><b><a href="http://machinename:port/servlet/servletClass">http://machineName:port/servlet/servletClass</a> (tng)</b><br /><br />如果(zhn)想在本地浏览器h一个?tng)PrimitiveServle (tng)servlet (tng)Q请输入以下 (tng)URLQ?br /><br /><b><a href="http://localhost:8080/servlet/PrimitiveServlet">http://localhost:8080/servlet/PrimitiveServlet</a></b> (tng)<br /><br />下面 (tng)Listing (tng)2.2 (tng)cȝ (tng)await (tng)Ҏ(gu)Q是{待一个?tng)HTTP (tng)hQ直C个发布?tng)shutdown (tng)命o(h)。与前文的?tng)await (tng)Ҏ(gu)怼。?br /><br /><b>Listing (tng)2.2. (tng)HttpServer1 (tng)cȝ (tng)await (tng)Ҏ(gu)<br />public (tng)void (tng)await() (tng){<br />ServerSocket (tng)serverSocket (tng)= (tng)null;<br />int (tng) (tng) (tng) (tng) (tng) (tng) (tng)port (tng) (tng)= (tng)8080;<br />try (tng){<br />serverSocket (tng)= (tng) (tng)new (tng)ServerSocket(port, (tng)1,InetAddress.getByName("127.0.0.1"));<br /> (tng) (tng) (tng) (tng)}catch (tng)(IOException (tng)e) (tng){<br />e.printStackTrace();<br />System.exit(1);<br /> (tng) (tng) (tng) (tng)}<br />// (tng)循环Q等待一个请?br />while (tng)(!shutdown) (tng){<br />Socket (tng)socket (tng) (tng) (tng) (tng) (tng) (tng) (tng)= (tng)null;<br />InputStream (tng)input (tng) (tng) (tng)= (tng)null;<br />OutputStream (tng)output (tng)= (tng)null;<br />try (tng){<br />socket (tng)= (tng)serverSocket.accept();<br />input (tng) (tng)= (tng)socket.getInputStream();<br />output (tng)= (tng)socket.getOutputStream();<br />// (tng)创徏h对象q解?br />Request (tng)request (tng)= (tng)new (tng)Request(input);<br />request.parse();<br />// (tng)创徏回应对象<br />Response (tng)response (tng)= (tng)new (tng)Response(output);<br />response.setRequest(request);<br />//(g)是否是 (tng)servlet (tng)或静(rn)态资源的h<br />//servlet (tng)h以?/servlet/" (tng)开始?br />if (tng)(request.getUri().startsWith("/servlet/")) (tng){<br />ServletProcessor1 (tng)processor (tng)= (tng)new (tng)ServletProcessor1();<br />processor.process(request, (tng)response);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br />else (tng){<br />StaticResourceProcessor (tng)processor (tng)=new (tng)StaticResourceProcessor();<br />processor.process(request, (tng)response);<br /> (tng) (tng) (tng) (tng) (tng) (tng)}<br />// (tng)关闭socket<br />socket.close();<br />//(g)是否前面的 (tng)URI (tng)是一个?tng)shutdown (tng)命o(h)<br />shutdown (tng)= (tng)request.getUri().equals(SHUTDOWN_COMMAND);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}catch (tng)(Exception (tng)e) (tng){<br />e.printStackTrace();System.exit(1);<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)} (tng) (tng) (tng) (tng)<br />}<br />}</b> (tng)<br /><br />此文 (tng)await (tng)Ҏ(gu)和前文的不同点就是,此文的?tng)await (tng)Ҏ(gu)中的h调度到StaticResourceProcessor (tng)或?tng)ervletProcessor (tng)。?br />如果 (tng)URI中包含?/servlet/."Q请求推q到后面Q否则,h传递到 (tng)StaticResourceProcessor (tng)实例 (tng)<br /><br />Request (tng)c?br /><br />Servlet (tng)service (tng)Ҏ(gu)接受 (tng)servlet (tng)容器的?tng)javax.servlet.ServletRequest (tng)和javax.servlet.ServletResponse (tng)实例。因此,容器必须构徏 (tng)ServletRequest和ServletResponse对象Q然后将其传递到正在被服务的service (tng)Ҏ(gu)。?br /><br />ex02.pyrmont.Request (tng)cM表一个请求对象传递到 (tng)service (tng)Ҏ(gu)。同样地Q它必须实现 (tng)javax.servlet.ServletRequest (tng)接口。这个类必须提供接口内所有方法的实现。这里尽量简化它q只实现几个Ҏ(gu)。要~译 (tng)Request (tng)cȝ话,必须提供q些Ҏ(gu)的空实现。再来看看?tng)request (tng)c,内部所有需要返回一个对象实例都q回nullQ如下:(x) (tng)<br /><br /><b>public (tng)Object (tng)getAttribute(String (tng)attribute) (tng){<br /> (tng) (tng) (tng) (tng) (tng)return (tng)null;<br /> (tng) (tng)}<br />public (tng)Enumeration (tng)getAttributeNames() (tng){<br /> (tng) (tng) (tng) (tng) (tng)return (tng)null;<br /> (tng) (tng)}<br />public (tng)String (tng)getRealPath(String (tng)path) (tng){<br /> (tng) (tng) (tng) (tng) (tng)return (tng)null;<br /> (tng) (tng)}</b><br />另外Qrequest (tng)cM需有前文有介绍的?tng)parse (tng)和getUri (tng)Ҏ(gu)。?br /><br />Response (tng)c?br /><br />response (tng)cd玊Wjavax.servlet.ServletResponseQ同P该类也必L供接口内所有方法的实现。类g (tng)Request (tng)c,除?tng)getWriter (tng)Ҏ(gu)外,其他Ҏ(gu)的实现都为空。?br /><br /><b>public (tng)PrintWriter (tng)getWriter() (tng){<br />// (tng)autoflush (tng)is (tng)true, (tng)println() (tng)will (tng)flush,<br />// (tng)but (tng)print() (tng)will (tng)not.<br />writer (tng)= (tng)new (tng)PrintWriter(output, (tng)true);<br />return (tng)writer;<br />}</b><br /><br />PrintWriter (tng)cL建器的第二个参数是一个代表是否启用?tng)autoflush (tng)布尔|如果为真Q所有调用println (tng)Ҏ(gu)qflush (tng)输出。而?tng)print (tng)调用则不 (tng)flush (tng)输出。因此,如果在servelt (tng)的service (tng)Ҏ(gu)的最后一行调用?tng)printҎ(gu)Q则从浏览器上看不到此输出?tng)。这个不完整性在后面的应用程序内?x)有调整。?br /><br />response (tng)cM包含有前文中介绍的?tng)sendStaticResourceҎ(gu)。?br /><br />StaticResourceProcessor (tng)c?br /><br />StaticResourceProcessor (tng)cȝ于服务静(rn)态资源的h。它唯一的方法是 (tng)process。?br /><br /><b>Listing (tng)2.3.StaticResourceProcessor (tng)cȝ (tng)processҎ(gu).<br />public (tng)void (tng)process(Request (tng)request, (tng)Response (tng)response) (tng){<br />try (tng){<br />response.sendStaticResource();<br /> (tng) (tng) (tng) (tng)}catch (tng)(IOException (tng)e) (tng){<br />e.printStackTrace();<br /> (tng) (tng) (tng) (tng)}<br />}</b><br />process (tng)Ҏ(gu)接受两个参数QRequest (tng)和?tng)Response (tng)实例。它仅仅是调用?tng)response (tng)cȝ (tng)sendStaticResource (tng)Ҏ(gu)?img src ="http://www.aygfsteel.com/matthew2006/aggbug/85799.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/matthew2006/" target="_blank">matthew</a> 2006-12-06 12:37 <a href="http://www.aygfsteel.com/matthew2006/archive/2006/12/06/85799.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java调用存储q程Q{?/title><link>http://www.aygfsteel.com/matthew2006/archive/2006/11/18/81950.html</link><dc:creator>matthew</dc:creator><author>matthew</author><pubDate>Sat, 18 Nov 2006 11:12:00 GMT</pubDate><guid>http://www.aygfsteel.com/matthew2006/archive/2006/11/18/81950.html</guid><wfw:comment>http://www.aygfsteel.com/matthew2006/comments/81950.html</wfw:comment><comments>http://www.aygfsteel.com/matthew2006/archive/2006/11/18/81950.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/matthew2006/comments/commentRss/81950.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/matthew2006/services/trackbacks/81950.html</trackback:ping><description><![CDATA[本文阐述?jin)怎么使用DBMS存储q程。我阐述?jin)用存储过E的基本的和高Ҏ(gu),比如q回ResultSet。本文假设你对DBMS和JDBC已经非常熟?zhn)Q也假设你能够毫无障地阅读其它语言写成的代码(即不是Java的语aQ,但是Qƈ不要求你有Q何存储过E的~程l历。?br /><br /> (tng) (tng) (tng) (tng)存储q程是指保存在数据库q在数据库端执行的程序。你可以使用Ҏ(gu)的语法在JavacM调用存储q程。在调用Ӟ存储q程的名U及(qing)指定的参数通过JDBCq接发送给DBMSQ执行存储过Eƈ通过q接Q如果有Q返回结果。?br />使用存储q程拥有和用基于EJB或CORBAq样的应用服务器一L(fng)好处。区别是存储q程可以从很多流行的DBMS中免费用,而应用服务器大都非常昂贵。这q不只是许可证费用的问题。用应用服务器所需要花费的理、编写代码的费用Q以?qing)客L(fng)序所增加的复杂性,都可以通过DBMS中的存储q程所整个地替代。?br /><br /> (tng) (tng) (tng) (tng)你可以用JavaQPythonQPerl或C~写存储q程Q但是通常使用你的DBMS所指定的特定语a。Oracle使用PL/SQLQPostgreSQL使用pl/pgsqlQDB2使用Procedural (tng)SQL。这些语a都非常相伹{在它们之间UL存储q程q不比在Sun的EJB规范不同实现版本之间ULSession (tng)Bean困难。ƈ且,存储q程是ؓ(f)嵌入SQL所设计Q这使得它们比Java或C{语a更加友好地方式表达数据库的机制。?br /><br /> (tng) (tng) (tng) (tng)因ؓ(f)存储q程q行在DBMS自nQ这可以帮助减少应用E序中的{待旉。不是在Java代码中执?个或5个SQL语句Q而只需要在服务器端执行1个存储过E。网l上的数据往q次数的减少可以戏剧性地优化性能。?br /><br />使用存储q程 (tng)<br /><br /> (tng) (tng) (tng) (tng)单的老的JDBC通过CallableStatementcL持存储过E的调用。该cd际上是PreparedStatement的一个子cR假设我们有一个poets数据库。数据库中有一个设|诗人逝世q龄的存储过E。下面是对老酒鬼Dylan (tng)ThomasQold (tng)soak (tng)Dylan (tng)ThomasQ不指定是否有关典故、文化,h评指正。译注)(j)q行调用的详l代码:(x) (tng)<br /><br />try{ (tng)<br />int (tng)age (tng)= (tng)39;<br />String (tng)poetName (tng)= (tng)"dylan (tng)thomas"; (tng)<br />CallableStatement (tng)proc (tng)= (tng)connection.prepareCall("{ (tng)call (tng)set_death_age?, (tng)?) (tng)}"); (tng)<br />proc.setString(1, (tng)poetName); (tng)<br />proc.setInt(2, (tng)age); (tng)<br />cs.execute(); (tng)<br />}catch (tng)(SQLException (tng)e){ (tng)// (tng)....} (tng)<br /><br /> (tng) (tng) (tng) (tng)传给prepareCallҎ(gu)的字串是存储q程调用的书写规范。它指定?jin)存储过E的名称Q?代表?jin)你需要指定的参数。?br />和JDBC集成是存储过E的一个很大的便利Qؓ(f)?jin)从应用中调用存储过E,不需要存根(stubQ类或者配|文Ӟ除了(jin)你的DBMS的JDBC驱动E序外什么也不需要。?br /><br /> (tng) (tng) (tng) (tng)当这D代码执行时Q数据库的存储过E就被调用。我们没有去获取l果Q因存储q程q不q回l果。执行成功或p|通过例外得知。失败可能意味着调用存储q程时的p|Q比如提供的一个参数的cd不正)(j)Q或者一个应用程序的p|Q比如抛Z个例外指C在poets数据库中q不存在“Dylan (tng)Thomas”)(j) (tng)<br /><br />l合SQL操作与存储过E?br /><br /> (tng) (tng) (tng) (tng)映射Java对象到SQL表中的行相当单,但是通常需要执行几个SQL语句Q可能是一个SELECT查找IDQ然后一个INSERT插入指定ID的数据。在高度规格化(W合更高的范式,译注Q的数据库模式中Q可能需要多个表的更斎ͼ因此需要更多的语句。Java代码?x)很快地膨胀Q每一个语句的|络开销也迅速增加。?br />这些SQL语句转移C个存储过E中大大简化代码,仅涉?qing)一ơ网l调用。所有关联的SQL操作都可以在数据库内部发生。ƈ且,存储q程语言Q例如PL/SQLQ允怋用SQL语法Q这比Java代码更加自然。下面是我们早期的存储过E,使用Oracle的PL/SQL语言~写Q?br /><br />create (tng)procedure (tng)set_death_age(poet (tng)VARCHAR2, (tng)poet_age (tng)NUMBER) (tng)<br />poet_id (tng)NUMBER; (tng)<br />begin (tng)SELECT (tng)id (tng)I(yng)NTO (tng)poet_id (tng)FROM (tng)poets (tng)WHERE (tng)name (tng)= (tng)poet; (tng)<br />INSERT (tng)I(yng)NTO (tng)deaths (tng)(mort_id, (tng)age) (tng)VALUES (tng)(poet_id, (tng)poet_age); (tng)<br />end (tng)set_death_age; (tng)<br /><br /> (tng) (tng) (tng) (tng)很独特?不。我打赌你一定期待看C个poets表上的UPDATE。这也暗CZ(jin)使用存储q程实现是多么容易的一件事情。set_death_age几乎可以肯定是一个很烂的实现。我们应该在poets表中d一列来存储逝世q龄。Java代码中ƈ不关?j)数据库模式是怎么实现的,因ؓ(f)它仅调用存储q程。我们以后可以改变数据库模式以提高性能Q但是我们不必修Ҏ(gu)们代码。?br /><br />下面是调用上面存储过E的Java代码Q?br /><br />public (tng)static (tng)void (tng)setDeathAge(Poet (tng)dyingBard, (tng)int (tng)age) (tng)throws (tng)SQLException{ (tng)<br />Connection (tng)con (tng)= (tng)null; (tng)<br />CallableStatement (tng)proc (tng)= (tng)null; (tng)<br />try (tng){ (tng)<br />con (tng)= (tng)connectionPool.getConnection(); (tng)<br />proc (tng)= (tng)con.prepareCall("{ (tng)call (tng)set_death_age(?, (tng)?) (tng)}"); (tng)<br />proc.setString(1, (tng)dyingBard.getName()); (tng)<br />proc.setInt(2, (tng)age); (tng)proc.execute(); (tng)<br />} (tng)finally (tng){ (tng)<br />try (tng){ (tng)<br />proc.close(); (tng)<br />} (tng)catch (tng)(SQLException (tng)e) (tng){ (tng)<br />con.close(); (tng) (tng)} (tng)}<br /><br /> (tng) (tng) (tng) (tng)Z(jin)保可维护性,使用像这儿这L(fng)staticҎ(gu)。这也得调用存储过E的代码集中在一个简单的模版代码中。如果你用到许多存储q程Q就?x)发C需要拷贝、粘贴就可以创徏新的Ҏ(gu)。因Z码的模版化,甚至也可以通过脚本自动生调用存储q程的代码。?br /><br />Functions (tng)<br /><br /> (tng) (tng) (tng) (tng)存储q程可以有返回|所以CallableStatementcLcMgetResultSetq样的方法来获取q回倹{当存储q程q回一个值时Q你必须使用registerOutParameterҎ(gu)告诉JDBC驱动器该值的SQLcd是什么。你也必调整存储过E调用来指示该过E返回一个倹{?br /><br />下面接着上面的例子。这ơ我们查询Dylan (tng)Thomas逝世时的q龄。这ơ的存储q程使用PostgreSQL的pl/pgsqlQ?br /><br />create (tng)function (tng)snuffed_it_when (tng)(VARCHAR) (tng)returns (tng)integer (tng)''declare (tng)<br />poet_id (tng)NUMBER; (tng)<br />poet_age (tng)NUMBER; (tng)<br />begin (tng)<br />--first (tng)get (tng)the (tng)id (tng)associated (tng)with (tng)the (tng)poet. (tng)<br />SELECT (tng)id (tng)I(yng)NTO (tng)poet_id (tng)FROM (tng)poets (tng)WHERE (tng)name (tng)= (tng)$1; (tng)<br />--get (tng)and (tng)return (tng)the (tng)age. (tng)<br />SELECT (tng)age (tng)I(yng)NTO (tng)poet_age (tng)FROM (tng)deaths (tng)WHERE (tng)mort_id (tng)= (tng)poet_id; (tng)<br />return (tng)age; (tng)<br />end;'' (tng)language (tng)''pl/pgsql''; (tng)<br /><br /> (tng) (tng) (tng) (tng)另外Q注意pl/pgsql参数名通过Unix和DOS脚本?n语法引用。同Ӟ也注意嵌入的注释Q这是和Java代码相比的另一个优性。在Java中写q样的注释当然是可以的,但是看v来很凌ؕQƈ且和SQL语句pQ必d入到Java (tng)String中。?br /><br />下面是调用这个存储过E的Java代码Q?br /><br />connection.setAutoCommit(false); (tng)<br />CallableStatement (tng)proc (tng)= (tng)connection.prepareCall("{ (tng)? (tng)= (tng)call (tng)snuffed_it_when(?) (tng)}"); (tng)<br />proc.registerOutParameter(1, (tng)Types.INTEGER); (tng)<br />proc.setString(2, (tng)poetName); (tng)<br />cs.execute(); (tng)<br />int (tng)age (tng)= (tng)proc.getInt(2); (tng)<br /><br /> (tng) (tng) (tng) (tng)如果指定?jin)错误的q回值类型会(x)怎样Q那么,当调用存储过E时抛Z个RuntimeExceptionQ正如你在ResultSet操作中用了(jin)一个错误的cd所到的一栗?br /><br />复杂的返回值?br /><br /> (tng) (tng) (tng) (tng)关于存储q程的知识,很多人好像就熟?zhn)我们所讨论的这些。如果这是存储过E的全部功能Q那么存储过E就不是其它q程执行机制的替换方案了(jin)。存储过E的功能比这强大得多。?br /> (tng) (tng) (tng) (tng)当你执行一个SQL查询ӞDBMS创徏一个叫做cursorQ游标)(j)的数据库对象Q用于在q回l果中P代每一行。ResultSet是当前时间点的游标的一个表C。这是Z么没有缓存或者特定数据库的支持,你只能在ResultSet中向前移动。?br /><br /> (tng) (tng) (tng) (tng)某些DBMS允许从存储过E中q回游标的一个引用。JDBCq不支持q个功能Q但是Oracle、PostgreSQL和DB2的JDBC驱动器都支持在ResultSet上打开到游标的指针QpointerQ。?br /><br /> (tng) (tng) (tng) (tng)设想列出所有没有活到退休年龄的诗hQ下面是完成q个功能的存储过E,q回一个打开的游标,同样也用PostgreSQL的pl/pgsql语言Q?br /><br />create (tng)procedure (tng)list_early_deaths (tng)() (tng)return (tng)refcursor (tng)as (tng)''declare (tng)<br />toesup (tng)refcursor; (tng)<br />begin (tng)open (tng)toesup (tng)for (tng)SELECT (tng)poets.name, (tng)deaths.age (tng)FROM (tng)poets, (tng)deaths (tng)<br />-- (tng)all (tng)entries (tng)in (tng)deaths (tng)are (tng)for (tng)poets. (tng)<br />-- (tng)but (tng)the (tng)table (tng)might (tng)become (tng)generic. (tng)<br />WHERE (tng)poets.id (tng)= (tng)deaths.mort_id (tng)AND (tng)deaths.age (tng)< (tng)60; (tng)<br />return (tng)toesup; (tng)<br />end;'' (tng)language (tng)''plpgsql''; (tng)<br /><br />下面是调用该存储q程的JavaҎ(gu)Q将l果输出到PrintWriterQ?br />PrintWriter: (tng)<br />static (tng)void (tng)sendEarlyDeaths(PrintWriter (tng)out){ (tng)<br />Connection (tng)con (tng)= (tng)null; (tng)<br />CallableStatement (tng)toesUp (tng)= (tng)null; (tng)<br />try (tng){ (tng)<br />con (tng)= (tng)ConnectionPool.getConnection(); (tng)// (tng)PostgreSQL (tng)needs (tng)a (tng)transaction (tng)to (tng)do (tng)this... (tng)con. (tng)<br />setAutoCommit(false); (tng)// (tng)Setup (tng)the (tng)call. (tng)<br />CallableStatement (tng)toesUp (tng)= (tng)connection.prepareCall("{ (tng)? (tng)= (tng)call (tng)list_early_deaths (tng)() (tng)}"); (tng)<br />toesUp.registerOutParameter(1, (tng)Types.OTHER); (tng)<br />toesUp.execute(); (tng)<br />ResultSet (tng)rs (tng)= (tng)(ResultSet) (tng)toesUp.getObject(1); (tng)<br />while (tng)(rs.next()) (tng){ (tng)<br />String (tng)name (tng)= (tng)rs.getString(1); (tng)<br />int (tng)age (tng)= (tng)rs.getInt(2); (tng)<br />out.println(name (tng)+ (tng)" (tng)was (tng)" (tng)+ (tng)age (tng)+ (tng)" (tng)years (tng)old."); (tng)<br />} (tng)<br />rs.close(); (tng)<br />} (tng)catch (tng)(SQLException (tng)e) (tng){ (tng)<br />// (tng)We (tng)should (tng)protect (tng)these (tng)calls. (tng)<br />toesUp.close(); (tng)<br />con.close(); (tng)<br />} (tng)<br />} (tng)<br /><br /> (tng) (tng) (tng) (tng)因ؓ(f)JDBCq不直接支持从存储过E中q回游标Q我们用Types.OTHER来指C存储过E的q回cdQ然后调用getObject()Ҏ(gu)q对q回D行强制类型{换。?br /><br /> (tng) (tng) (tng) (tng)q个调用存储q程的JavaҎ(gu)是mapping的一个好例子。Mapping是对一个集上的操作q行抽象的方法。不是在q个q程上返回一个集Q我们可以把操作传送进L行。本例中Q操作就是把ResultSet打印C个输出流。这是一个值得举例的很常用的例子,下面是调用同一个存储过E的另外一个方法实玎ͼ(x) (tng)<br /><br />public (tng)class (tng)ProcessPoetDeaths{ (tng)<br />public (tng)abstract (tng)void (tng)sendDeath(String (tng)name, (tng)int (tng)age); (tng)<br />} (tng)<br />static (tng)void (tng)mapEarlyDeaths(ProcessPoetDeaths (tng)mapper){ (tng)<br />Connection (tng)con (tng)= (tng)null; (tng)<br />CallableStatement (tng)toesUp (tng)= (tng)null; (tng)<br />try (tng){ (tng)<br />con (tng)= (tng)ConnectionPool.getConnection(); (tng)<br />con.setAutoCommit(false); (tng)<br />CallableStatement (tng)toesUp (tng)= (tng)connection.prepareCall("{ (tng)? (tng)= (tng)call (tng)list_early_deaths (tng)() (tng)}"); (tng)<br />toesUp.registerOutParameter(1, (tng)Types.OTHER); (tng)<br />toesUp.execute(); (tng)<br />ResultSet (tng)rs (tng)= (tng)(ResultSet) (tng)toesUp.getObject(1); (tng)<br />while (tng)(rs.next()) (tng){ (tng)<br />String (tng)name (tng)= (tng)rs.getString(1); (tng)<br />int (tng)age (tng)= (tng)rs.getInt(2); (tng)<br />mapper.sendDeath(name, (tng)age); (tng)<br />} (tng)<br />rs.close(); (tng)<br />} (tng)catch (tng)(SQLException (tng)e) (tng){ (tng)<br />// (tng)We (tng)should (tng)protect (tng)these (tng)calls. (tng)<br />toesUp.close(); (tng)<br />con.close(); (tng)<br />} (tng)<br />} (tng)<br /><br />q允许在ResultSet数据上执行Q意的处理Q而不需要改变或者复制获取ResultSet的方法:(x) (tng)<br /><br />static (tng)void (tng)sendEarlyDeaths(final (tng)PrintWriter (tng)out){ (tng)<br />ProcessPoetDeaths (tng)myMapper (tng)= (tng)new (tng)ProcessPoetDeaths() (tng){ (tng)<br />public (tng)void (tng)sendDeath(String (tng)name, (tng)int (tng)age) (tng){ (tng)<br />out.println(name (tng)+ (tng)" (tng)was (tng)" (tng)+ (tng)age (tng)+ (tng)" (tng)years (tng)old."); (tng)<br />} (tng)<br />}; (tng)<br />mapEarlyDeaths(myMapper); (tng)<br />} (tng)<br /><br /> (tng) (tng) (tng)q个Ҏ(gu)使用ProcessPoetDeaths的一个匿名实例调用mapEarlyDeaths。该实例拥有sendDeathҎ(gu)的一个实玎ͼ和我们上面的例子一L(fng)方式把结果写入到输出。当?dng)q个技巧ƈ不是存储q程Ҏ(gu)的,但是和存储过E中q回的ResultSetl合使用Q是一个非常强大的工具。?br /><br />l论 (tng)<br /><br />存储q程可以帮助你在代码中分逻辑Q这基本上L有益的。这个分ȝ好处有:(x) (tng)<br />•?tng)快速创建应用,使用和应用一h变和改善的数据库模式。?br />•?tng)数据库模式可以在以后改变而不影响Java对象Q当我们完成应用后,可以重新设计更好的模式。?br />•?tng)存储过E通过更好的SQL嵌入使得复杂的SQL更容易理解。?br />•?tng)编写存储过E比在Java中编写嵌入的SQL拥有更好的工PQ大部分~辑器都提供语法高(sh)Q?br />•?tng)存储过E可以在MSQL命o(h)行中试Q这使得调试更加Ҏ(gu)。?br /><br />q不是所有的数据库都支持存储q程Q但是存在许多很的实现Q包括免?开源的和非免费的,所以移植ƈ不是一个问题。Oracle、PostgreSQL和DB2都有cM的存储过E语aQƈ且有在线的社区很好地支持。?br />存储q程工具很多Q有像TOAD或TORAq样的编辑器、调试器和IDEQ提供了(jin)~写、维护PL/SQL或pl/pgsql的强大的环境。?br /><br />存储q程实增加?jin)你的代码的开销Q但是它们和大多数的应用服务器相比,开销得多?br /><br /><font color="#ff33cc"><a title="原文地质" >查看原文</a></font><img src ="http://www.aygfsteel.com/matthew2006/aggbug/81950.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/matthew2006/" target="_blank">matthew</a> 2006-11-18 19:12 <a href="http://www.aygfsteel.com/matthew2006/archive/2006/11/18/81950.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中文q问题Q{?/title><link>http://www.aygfsteel.com/matthew2006/archive/2006/11/16/81448.html</link><dc:creator>matthew</dc:creator><author>matthew</author><pubDate>Thu, 16 Nov 2006 02:09:00 GMT</pubDate><guid>http://www.aygfsteel.com/matthew2006/archive/2006/11/16/81448.html</guid><wfw:comment>http://www.aygfsteel.com/matthew2006/comments/81448.html</wfw:comment><comments>http://www.aygfsteel.com/matthew2006/archive/2006/11/16/81448.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/matthew2006/comments/commentRss/81448.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/matthew2006/services/trackbacks/81448.html</trackback:ping><description><![CDATA[1.字节和unicode<br /> (tng) (tng) (tng) (tng)java内核是unicode的,pclass文g也是Q但是很多媒体,包括文g/的保存方式是用字节流的。因此java要对q些字节经行{化。char是unicode的,而byte是字节。java中byte/char互{的函数在sun.io的包中间有。其中ByteToCharConvertercL中调度,可以用来告诉你,你用的convertor。其中两个很常用的静(rn)态函数是 (tng)<br />public (tng)static (tng)ByteToCharConverter (tng)getDefault(); (tng)<br />public (tng)static (tng)ByteToCharConverter (tng)getConverter(String (tng)encoding); (tng)<br />如果你不指定converterQ则pȝ?x)自动用当前的encoding,gbq_上用gbk,enq_上用8859_1?br />byte (tng)――〉charQ?br /> (tng)"?的gb码是Q?xc4e3 (tng),unicode?x4f60<br /> (tng) (tng)String (tng)encoding (tng)= (tng)"gb2312";<br /> (tng) (tng)byte (tng)b[] (tng)= (tng){(byte)'\u00c4',(byte)'\u00e3'};<br /> (tng) (tng)ByteToCharConverter (tng)converter (tng)= (tng)ByteToCharConverter.getConverter(encoding);<br /> (tng) (tng)char (tng)c[] (tng)= (tng)converter.convertAll(b);<br /> (tng) (tng)for (tng)(int (tng)i (tng)= (tng)0; (tng)i (tng)< (tng)c.length; (tng)i++) (tng){<br /> (tng) (tng) (tng) (tng) (tng) (tng)System.out.println(Integer.toHexString(c[i]));<br /> (tng) (tng)}<br /> (tng)l果是什么?0x4f60<br /> (tng)如果encoding (tng)="8859_1"Q结果又是什么?0x00c4,0x00e3<br /> (tng)如果代码改ؓ(f)<br /> (tng)byte (tng)b[] (tng)= (tng){(byte)'\u00c4',(byte)'\u00e3'};<br /> (tng)ByteToCharConverter (tng)converter (tng)= (tng)ByteToCharConverter. (tng)getDefault();<br /> (tng)char (tng)c[] (tng)= (tng)converter.convertAll(b);<br /> (tng)for (tng)(int (tng)i (tng)= (tng)0; (tng)i (tng)< (tng)c.length; (tng)i++) (tng){<br /> (tng) (tng) (tng) (tng)System.out.println(Integer.toHexString(c[i]));<br /> (tng)}<br /> (tng)l果又是什么?Ҏ(gu)q_的编码而定?br /><br /> (tng)char (tng)――〉byteQ?br /> (tng) (tng) (tng) (tng)String (tng)encoding (tng)= (tng)"gb2312";<br /> (tng) (tng) (tng) (tng)char (tng)c[] (tng)= (tng){'\u4f60'};<br /> (tng) (tng) (tng) (tng)CharToByteConverter (tng)converter (tng)= (tng)CharToByteConverter.getConverter(encoding);<br /> (tng) (tng) (tng) (tng)byte (tng)b[] (tng)= (tng)converter.convertAll(c);<br /> (tng) (tng) (tng) (tng)for (tng)(int (tng)i (tng)= (tng)0; (tng)i (tng)< (tng)b.length; (tng)i++) (tng){<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng)System.out.println(Integer.toHexString(b[i]));<br /> (tng) (tng) (tng) (tng)}<br />l果是什么?0x00c4,0x00e3<br />如果encoding (tng)="8859_1"Q结果又是什么?0x3f<br />如果代码改ؓ(f)<br />String (tng)encoding (tng)= (tng)"gb2312";<br /> (tng) (tng) (tng) (tng)char (tng)c[] (tng)= (tng){'\u4f60'};<br /> (tng) (tng) (tng) (tng)CharToByteConverter (tng)converter (tng)= (tng)CharToByteConverter.getDefault();<br /> (tng) (tng) (tng) (tng)byte (tng)b[] (tng)= (tng)converter.convertAll(c);<br /> (tng) (tng) (tng) (tng)for (tng)(int (tng)i (tng)= (tng)0; (tng)i (tng)< (tng)b.length; (tng)i++) (tng){<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng)System.out.println(Integer.toHexString(b[i]));<br /> (tng) (tng) (tng) (tng)}<br />l果又是什么?Ҏ(gu)q_的编码而定?br />很多中文问题是从这两个最单的cL生出来的。而却有很多类不直接支持把encoding输入Q这l我们带来诸多不ѝ很多程序难得用encoding?jin),直接用default的encodingQ这q我们UL带来?jin)很多困难?br /><br />2.utf-8<br />utf-8是和unicode一一对应的,其实现很?br />7位的unicode: (tng)0 (tng)_ (tng)_ (tng)_ (tng)_ (tng)_ (tng)_ (tng)_ (tng)<br />11位的unicode: (tng)1 (tng)1 (tng)0 (tng)_ (tng)_ (tng)_ (tng)_ (tng)_ (tng)1 (tng)0 (tng)_ (tng)_ (tng)_ (tng)_ (tng)_ (tng)_ (tng)<br />16位的unicode: (tng)1 (tng)1 (tng)1 (tng)0 (tng)_ (tng)_ (tng)_ (tng)_ (tng)1 (tng)0 (tng)_ (tng)_ (tng)_ (tng)_ (tng)_ (tng)_ (tng)1 (tng)0 (tng)_ (tng)_ (tng)_ (tng)_ (tng)_ (tng)_ (tng)<br />21位的unicode: (tng)1 (tng)1 (tng)1 (tng)1 (tng)0 (tng)_ (tng)_ (tng)_ (tng)1 (tng)0 (tng)_ (tng)_ (tng)_ (tng)_ (tng)_ (tng)_ (tng)1 (tng)0 (tng)_ (tng)_ (tng)_ (tng)_ (tng)_ (tng)_ (tng)1 (tng)0 (tng)_ (tng)_ (tng)_ (tng)_ (tng)_ (tng)_ (tng)<br />大多数情冉|只用到16位以下的unicode: (tng)<br />"?的gb码是Q?xc4e3 (tng),unicode?x4f60<br /> (tng) (tng) (tng) (tng)0xc4e3的二q制Q?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)1100 (tng)Q?100 (tng)Q?110 (tng)Q?011<br />׃只有两位我们按照两位的编码来排,但是我们发现q行不通,因ؓ(f)W7位不?因此Q返??"<br /> (tng) (tng) (tng) (tng)0x4f60的二q制Q?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)0100 (tng)Q?111 (tng)Q?110 (tng)Q?000<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)我们用utf-8补齐Q变成:(x)<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)1110 (tng)Q?100 (tng)Q?011 (tng)Q?101 (tng)Q?010 (tng)Q?000<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)e4--bd-- (tng)a0<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)于是q回Q?xe4,0xbd,0xa0?br /><br />3.string和byte[]<br />string其实核心(j)是char[],然而要把byte转化成stringQ必ȝq编码。string.length()其实是char数组的长度,如果使用不同的编码,很可能会(x)错分Q造成散字和ؕ码?br />例如Q?br />String (tng)encoding (tng)= (tng)“?<br />byte (tng)[] (tng)b={(byte)'\u00c4',(byte)'\u00e3'}; (tng)<br />String (tng)str=new (tng)String(b,encoding);  <br />如果encoding=8859_1Q会(x)有两个字Q但是encoding=gb2312只有一个字q个问题在处理分|l常发生 (tng)?br /><br />4.Reader,Writer (tng)/ (tng)I(yng)nputStream,OutputStream<br />Reader和W(xu)riter核心(j)是charQInputStream和OutputStream核心(j)是byte。但是Reader和W(xu)riter的主要目的是要把char?写InputStream/OutputStream?br />例如Q?br />文gtest.txt只有一??字,0xc4,0xe3<br />String (tng)encoding (tng)= (tng)"gb2312";<br /> (tng) (tng) (tng) (tng)I(yng)nputStreamReader (tng)reader (tng)= (tng)new (tng)I(yng)nputStreamReader(new (tng)FileInputStream(<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)"text.txt"), (tng)encoding);<br /> (tng) (tng) (tng) (tng)char (tng)c[] (tng)= (tng)new (tng)char[10];<br /> (tng) (tng) (tng) (tng)int (tng)length (tng)= (tng)reader.read(c);<br /> (tng) (tng) (tng) (tng)for (tng)(int (tng)i (tng)= (tng)0; (tng)i (tng)< (tng)length; (tng)i++) (tng){<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng)System.out.println(c[i]);<br /> (tng) (tng) (tng) (tng)}<br />l果是什么??br />如果encoding (tng)="8859_1"Q结果是什么???两个字符Q表CZ认识?br />反过来的例子自己做?br /><br />5.我们要对java的编译器有所?jin)解Q?br />javac (tng)?encoding<br />我们常常没有用到encodingq个参数。其实encodingq个参数对于跨^台的操作是很重要的。如果没有指定encodingQ则按照pȝ的默认encoding,gbq_上是gb2312Q英文^C是iso8859_1?br />java的编译器实际上是调用sun.tools.javac.main的类Q对文gq行~译Q这个类有compile函数中间有一个encoding的变?-encoding的参数其实直接传lencoding变量。编译器是Ҏ(gu)q个变量来读取java文g的,然后把用utf-8形式~译成class文g?br />例子代码Q?br />String (tng)str (tng)= (tng)"?;<br /> (tng) (tng) (tng) (tng)FileWriter (tng)writer (tng)= (tng)new (tng)FileWriter("text.txt");<br /> (tng) (tng) (tng) (tng)write.write(str);<br /> (tng) (tng) (tng) (tng)writer.close();<br /><br />如果用gb2312~译Q你?x)找到e4 (tng)bd (tng)a0的字D?tng)?br />如果?859_1~译Q?0c4 (tng)00e3的二q制Q?br />0000Q?000 (tng)Q?100Q?100 (tng)Q?000Q?000 (tng)Q?110Q?011<br />因ؓ(f)每个字符都大?位,因此?1位编码:(x) (tng)<br />1100Q?001Q?000Q?100Q?100Q?011Q?010Q?011 (tng)<br />c1-- (tng)84-- c3--  (tng)a3 (tng)<br />你会(x)扑ֈc1 (tng)84 (tng)c3 (tng)a3 (tng)?br /><br />但是我们往往忽略掉这个参敎ͼ因此q样往往?x)有跨^台的问题Q?br />样例代码在中文^C~译Q生成zhclass<br />样例代码在英文^C~译Q输出enclass<br /> (tng) (tng)(1).  (tng)zhclass在中文^C执行ok,但是在英文^C不行 (tng)<br /> (tng) (tng)(2). (tng) (tng) (tng) (tng)enclass在英文^C执行ok,但是在中文^C不行<br />原因Q?br /> (tng) (tng)(1). (tng) (tng) (tng) (tng)在中文^C~译后,其实str在运行态的char[]?x4f60, 在中文^Cq行Qfilewriter的缺省编码是gb2312,因此 (tng)chartobyteconverter?x)自动用调用gb2312的converter,把str转化成byte输入到fileoutputstream中,于是0xc4,0xe3放进?jin)文件。?br />但是如果是在英文q_下,chartobyteconverter的缺省值是8859_1, (tng)filewriter?x)自动调?859_1去{化str,但是他无法解释,因此他会(x)输出"?"<br /> (tng) (tng)(2). (tng) (tng) (tng) (tng)在英文^C~译后,其实str在运行态的char[]?x00c4 (tng)0x00e3, (tng)在中文^Cq行Q中文无法识别,因此?x)出??Q?br />在英文^CQ?x00c4-->0xc4,0x00e3->0xe3Q因?xc4,0xe3被放q了(jin)文g?br /><br />6. (tng) (tng) (tng) (tng)其它原因Q?lt;%@ (tng)page (tng)contentType="text/html; (tng)charset=GBK" (tng)%><br />讄览器的昄~码Q如果response的数据是utf8~码Q显C将是ؕ码,但是q和上q原因还?sh)一栗?br /><br />7. (tng) (tng) (tng) (tng)发生~码的地方:(x)<br />?tng) (tng) (tng) (tng)从数据库到javaE序 (tng)byte――〉char<br />?tng) (tng) (tng) (tng)从javaE序到数据库 (tng)char――〉byte<br />?tng) (tng) (tng) (tng)从文g到javaE序 (tng)byte――〉char<br />?tng) (tng) (tng) (tng)从javaE序到文件?tng)char――〉byte<br />?tng) (tng) (tng) (tng)从javaE序到页面显C?tng)char――〉byte<br />?tng) (tng) (tng) (tng)从面form提交数据到javaE序byte――〉char<br />?tng) (tng) (tng) (tng)从到javaE序byte――〉char<br />?tng) (tng) (tng) (tng)从javaE序到流char――〉byte<br /><br />谢志钢的解决Ҏ(gu)Q?br />我是使用配置qo(h)器的Ҏ(gu)解决中文q的:(x)<br /><br /><web-app><br /> (tng) (tng)<filter><br /> (tng) (tng) (tng) (tng)<filter-name>RequestFilter</filter-name><br /> (tng) (tng) (tng) (tng)<filter-class>net.golden.uirs.util.RequestFilter</filter-class><br /> (tng) (tng) (tng) (tng)<init-param><br /> (tng) (tng) (tng) (tng) (tng) (tng)<param-name>charset</param-name><br /> (tng) (tng) (tng) (tng) (tng) (tng)<param-value>gb2312</param-value><br /> (tng) (tng) (tng) (tng)</init-param><br /> (tng) (tng)</filter><br /> (tng) (tng)<filter-mapping><br /> (tng) (tng) (tng) (tng)<filter-name>RequestFilter</filter-name><br /> (tng) (tng) (tng) (tng)<url-pattern>*.jsp</url-pattern><br /> (tng) (tng)</filter-mapping><br /></web-app><br /><br /><br /> (tng) (tng)public (tng)void (tng)doFilter(ServletRequest (tng)req, (tng)ServletResponse (tng)res,<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)FilterChain (tng)fChain) (tng)throws (tng)I(yng)OException, (tng)ServletException (tng){<br /> (tng) (tng) (tng) (tng)HttpServletRequest (tng)request (tng)= (tng)(HttpServletRequest) (tng)req;<br /> (tng) (tng) (tng) (tng)HttpServletResponse (tng)response (tng)= (tng)(HttpServletResponse) (tng)res;<br /> (tng) (tng) (tng) (tng)HttpSession (tng)session (tng)= (tng)request.getSession();<br /> (tng) (tng) (tng) (tng)String (tng)userId (tng)= (tng)(String) (tng)session.getAttribute("userid");<br />req.setCharacterEncoding(this.filterConfig.getInitParameter("charset")); (tng)// (tng)讄字符集?<br />实际上是讄?jin)byte (tng)――〉char的encoding<br /> (tng) (tng) (tng) (tng)try (tng){<br /> (tng) (tng) (tng) (tng) (tng) (tng)if (tng)(userId (tng)== (tng)null (tng)|| (tng)userId.equals("")) (tng){<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)if (tng)(!request.getRequestURL().toString().matches(<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)".*/uirs/logon/logon(Controller){0,1}\\x2Ejsp$")) (tng){<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)session.invalidate();<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)response.sendRedirect(request.getContextPath() (tng)+<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)"/uirs/logon/logon.jsp");<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br /> (tng) (tng) (tng) (tng) (tng) (tng)}<br /> (tng) (tng) (tng) (tng) (tng) (tng)else (tng){ (tng)// (tng)看看是否h信息上报pȝ的权?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)if (tng)(!net.golden.uirs.util.UirsChecker.check(userId, (tng)"信息上报pȝ",<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)net.golden.uirs.util.UirsChecker.ACTION_DO)) (tng){<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)if (tng)(!request.getRequestURL().toString().matches(<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)".*/uirs/logon/logon(Controller){0,1}\\x2Ejsp$")) (tng){<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)response.sendRedirect(request.getContextPath() (tng)+<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)"/uirs/logon/logonController.jsp");<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}<br /> (tng) (tng) (tng) (tng) (tng) (tng)}<br /> (tng) (tng) (tng) (tng)}<br /> (tng) (tng) (tng) (tng)catch (tng)(Exception (tng)ex) (tng){<br /> (tng) (tng) (tng) (tng) (tng) (tng)response.sendRedirect(request.getContextPath() (tng)+<br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)"/uirs/logon/logon.jsp");<br /> (tng) (tng) (tng) (tng)}<br /> (tng) (tng) (tng) (tng)fChain.doFilter(req, (tng)res);<br /> (tng) (tng)}<br /><br /><font color="#99cc33"><a title="原文" >点击查看原文</a></font><img src ="http://www.aygfsteel.com/matthew2006/aggbug/81448.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/matthew2006/" target="_blank">matthew</a> 2006-11-16 10:09 <a href="http://www.aygfsteel.com/matthew2006/archive/2006/11/16/81448.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java变量cd间的怺转换Q{?/title><link>http://www.aygfsteel.com/matthew2006/archive/2006/11/15/81161.html</link><dc:creator>matthew</dc:creator><author>matthew</author><pubDate>Wed, 15 Nov 2006 01:14:00 GMT</pubDate><guid>http://www.aygfsteel.com/matthew2006/archive/2006/11/15/81161.html</guid><wfw:comment>http://www.aygfsteel.com/matthew2006/comments/81161.html</wfw:comment><comments>http://www.aygfsteel.com/matthew2006/archive/2006/11/15/81161.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/matthew2006/comments/commentRss/81161.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/matthew2006/services/trackbacks/81161.html</trackback:ping><description><![CDATA[我们知道QJava的数据类型分Z大类Q即布尔型、字W型和数值型Q而其中数值型又分为整型和点型;相对于数据类型,Java的变量类型ؓ(f)布尔型booleanQ字W型charQ整型byte、short、int、longQQ点型float、double。其中四U整型变量和两种点型变量分别对应于不同的精度和范围。此外,我们q经常用CU类变量Q即String和Date。对于这些变量类型之间的怺转换在我们编E中l常要用刎ͼ在我们今天的q篇文章中,我们来看看如何实现q些转换?br /><br />一、?tng)整型、实型、字W型变量中的怺转换<br />在Java中整型、实型、字W型被视为同一cL据,q些cd׃U到高分别?byteQshortQchar)??int??long??float??doubleQ低U变量可以直接{换ؓ(f)高变量Q例如,下面的语句可以在Java中直接通过Q?br />byte (tng)b;<br />int (tng)i=b;<br />而将高变量转换ZU变量时Q情况会(x)复杂一些,你可以用强制类型{换。即你必采用下面这U语句格式:(x)<br />int (tng)i;<br />byte (tng)b=(byte)i;<br />可以惌Q这U{换肯定可能会(x)D溢出或精度的下降Q因此我们ƈ不推荐用这U{换?br /><br />二、Java的包装类<br />在我们讨论其它变量类型之间的怺转换Ӟ我们需要了(jin)解一下Java的包装类Q所谓包装类Q就是可以直接将单类型的变量表示Z个类Q在执行变量cd的相互{换时Q我们会(x)大量使用q些包装cRJava共有六个包装c,分别是Boolean、Character、Integer、Long、Float和?tng)DoubleQ从字面上我们就可以看出它们分别对应于?tng)boolean、char、int、long、float和double。而String和Date本n是cR所以也׃存在什么包装类的概念了(jin)?br /><br />三、简单类型变量和包装cM间的怺转换<br />单类型的变量转换为相应的包装c,可以利用包装cȝ构造函数。即Q?br />Boolean(boolean (tng)value)、Character(char (tng)value)、Integer(int (tng)value)、Long(long (tng)value)、Float(float (tng)value)、Double(double (tng)value)<br />而在各个包装cMQL形ؓ(f)××Value()的方法,来得到其对应的简单类型数据。利用这U方法,也可以实C同数值型变量间的转换Q例如,对于一个双_ֺ实型c,intValue()可以得到其对应的整型变量Q而doubleValue()可以得到其对应的双精度实型变量?br /><br />四、Stringcd其它数据cd的相互{?br />对于上面的这些包装类Q除?jin)Character以外Q都有可以直接用字W串参数的构造函敎ͼq也׃得我们将Stringc{换ؓ(f)q些数据cd变得相当之简单,卻I(x)<br />Boolean(String (tng)s)、Integer(String (tng)s)、Long(String (tng)s)、Float(String (tng)s)、Double(String (tng)s)<br />而将Stringc{换ؓ(f)DatecM可以使用q样的构造函敎ͼ(x)Date(String (tng)s)<br />现在我们q剩下一个字W型变量Q事实上Stringcd以理解ؓ(f)一个char型数l,因此我们可以在StringcM扑ֈq样的方法来实现q种转换Q?tng)charAt(int (tng)index)可以得到StringcM某一位置上的字符QtoCharArray()更可以将整个Stringc{换成一个char的数l?br />对于所有的包装c都存在一个名为toString()的方法可以将其{换成对应的Stringc,而对于整型类和长整型c,q可以用?tng)toBinaryString(int (tng)i)、toHexString(int (tng)i)、toOctalString(int (tng)i)分别以二q制、十六进制和八进制的形式q行到Stringcȝ转换?br /><br />五、将字符型直接做为数D{换ؓ(f)其它数据cd<br />字W型变量转换为数值型变量实际上有两种对应关系Q在我们在第一部分所说的那种转换中,实际上是其转换成对应的ASCII码,但是我们有时q需要另一U{换关p,例如Q?’就是指的数?Q而不是其ASCII码,对于q种转换Q我们可以用Character的getNumericValue(char (tng)ch)Ҏ(gu)?br /><br />六、DatecM其它数据cd的相互{?br />整型和DatecM间ƈ不存在直接的对应关系Q只是你可以使用int型ؓ(f)分别表示q、月、日、时、分、秒Q这样就在两者之间徏立了(jin)一个对应关p,在作q种转换Ӟ你可以用DatecL造函数的三种形式Q?br />Date(int (tng)year, (tng)int (tng)month, (tng)int (tng)date)Q以int型表C年、月、日<br />Date(int (tng)year, (tng)int (tng)month, (tng)int (tng)date, (tng)int (tng)hrs, (tng)int (tng)min)Q以int型表C年、月、日、时、分<br />Date(int (tng)year, (tng)int (tng)month, (tng)int (tng)date, (tng)int (tng)hrs, (tng)int (tng)min, (tng)int (tng)sec)Q以int型表C年、月、日、时、分、秒<br />在长整型和DatecM间有一个很有趣的对应关p,是一个时间表CZؓ(f)距离格林治标准旉1970q?????U的毫秒数。对于这U对应关p,DatecM有其相应的构造函敎ͼ(x)Date(long (tng)date)<br />获取DatecM的年、月、日、时、分、秒以及(qing)星期你可以用DatecȝgetYear()、getMonth()、getDate()、?tng)getHours()、getMinutes()、getSeconds()、getDay()Ҏ(gu)Q你也可以将其理解ؓ(f)Datec{换成int?br />而DatecȝgetTime()Ҏ(gu)可以得到我们前面所说的一个时间对应的长整型数Q与包装cMPDatecM有一个toString()Ҏ(gu)可以其转换为StringcR?br />在Java的数据类型{换中Q你q有一些其它方法可用,但是Q上面所介绍的这些方法对于你的实际编E已l够了(jin)Q不是吗Q?br /><br /><br /><a title="原文地址" >原文地址</a><br /><img src ="http://www.aygfsteel.com/matthew2006/aggbug/81161.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/matthew2006/" target="_blank">matthew</a> 2006-11-15 09:14 <a href="http://www.aygfsteel.com/matthew2006/archive/2006/11/15/81161.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA字符集-转脓(chung)http://www.aygfsteel.com/matthew2006/archive/2006/11/15/81159.htmlmatthewmatthewWed, 15 Nov 2006 01:11:00 GMThttp://www.aygfsteel.com/matthew2006/archive/2006/11/15/81159.htmlhttp://www.aygfsteel.com/matthew2006/comments/81159.htmlhttp://www.aygfsteel.com/matthew2006/archive/2006/11/15/81159.html#Feedback0http://www.aygfsteel.com/matthew2006/comments/commentRss/81159.htmlhttp://www.aygfsteel.com/matthew2006/services/trackbacks/81159.html
本文主要包括以下几个斚wQ编码基本知识,javaQ系lYӞurlQ工兯Y件等。?br />
在下面的描述中,以"中文"两个字ؓ(f)例,l查表可以知道其GB2312~码?d6d0 (tng)cec4"QUnicode~码?4e2d (tng)6587"Q?tng)UTF~码是"e4b8ad (tng)e69687"。注意,q两个字没有iso8859-1~码Q但可以用iso8859-1~码?表示"。?br />
2. (tng)~码基本知识 (tng)

最早的~码是iso8859-1Q和ascii~码怼。但Z(jin)方便表示各种各样的语aQ逐渐出现?jin)很多标准编码,重要的有如下几个。?br />
2.1. (tng)iso8859-1 (tng)

属于单字节编码,最多能表示的字W范围是0-255Q应用于英文pd。比如,字母'a'的编码ؓ(f)0x61=97。?br />
很明显,iso8859-1~码表示的字W范围很H,无法表示中文字符。但是,׃是单字节~码Q和计算机最基础的表C单位一_(d)所以很多时候,仍旧使用 (tng)iso8859-1~码来表C。而且在很多协议上Q默认用该~码。比如,虽然"中文"两个字不存在iso8859-1~码Q以gb2312~码ZQ应该是"d6d0 (tng)cec4"两个字符Q用iso8859-1~码的时候则它拆开?个字节来表示Q?d6 (tng)d0 (tng)ce (tng)c4"Q事实上Q在q行存储的时候,也是以字节ؓ(f)单位处理的)(j)。而如果是UTF~码Q则?个字?e4 (tng)b8 (tng)ad (tng)e6 (tng)96 (tng)87"。很明显Q这U表C方法还需要以另一U编码ؓ(f)基础。?br />
2.2. (tng)GB2312/GBK (tng)

q就是汉子的国标码,专门用来表示汉字Q是双字节编码,而英文字母和iso8859-1一_(d)兼容iso8859-1~码Q。其中gbk~码能够用来同时表示J体字和体字Q而gb2312只能表示体字Qgbk是兼容gb2312~码的。?br />
2.3. (tng)unicode (tng)

q是最l一的编码,可以用来表示所有语a的字W,而且是定长双字节Q也有四字节的)(j)~码Q包括英文字母在内。所以可以说它是不兼容iso8859-1~码的,也不兼容M~码。不q,相对于iso8859-1~码来说Quniocode~码只是在前面增加了(jin)一?字节Q比如字?a'?00 (tng)61"。?br />
需要说明的是,定长~码便于计算机处理(注意GB2312/GBK不是定长~码Q,而unicode又可以用来表C所有字W,所以在很多软g内部是用unicode~码来处理的Q比如java。?br />
2.4. (tng)UTF (tng)

考虑到unicode~码不兼容iso8859-1~码Q而且Ҏ(gu)占用更多的空_(d)(x)因ؓ(f)对于英文字母Qunicode也需要两个字节来表示。所以?tng)unicode不便于传输和存储。因此而生了(jin)utf~码Qutf~码兼容iso8859-1~码Q同时也可以用来表示所有语a的字W,不过Qutf~码是不定长~码Q每一个字W的长度?-6个字节不{。另外,utf~码自带单的校验功能。一般来Ԍ英文字母都是用一个字节表C,而汉字用三个字节。?tng)?br />
注意Q虽然说utf是ؓ(f)?jin)用更的I间而用的Q但那只是相对于unicode~码来说Q如果已l知道是汉字Q则使用 (tng)GB2312/GBK无疑是最节省的。不q另一斚wQ值得说明的是Q虽然utf~码Ҏ(gu)字?个字节,但即使对于汉字网,utf~码也会(x)比?tng)unicode~码节省Q因为网中包含?jin)很多的英文字符。?br />
3. (tng)java对字W的处理 (tng)

在java应用软g中,?x)有多处涉?qing)到字W集~码Q有些地斚w要进行正的讄Q有些地斚w要进行一定程度的处理。?br />
3.1. (tng)getBytes(charset) (tng)

q是java字符串处理的一个标准函敎ͼ其作用是字W串所表示的字W按照charset~码Qƈ以字节方式表C。注意字W串在java内存?sh)L按?tng)unicode~码存储的。比?中文"Q正常情况下Q即没有错误的时候)(j)存储?4e2d (tng)6587"Q如果charset?gbk"Q则被编码ؓ(f) (tng)"d6d0 (tng)cec4"Q然后返回字?d6 (tng)d0 (tng)ce (tng)c4"。如果charset?utf8"则最后是"e4 (tng)b8 (tng)ad (tng)e6 (tng)96 (tng)87"。如果是"iso8859-1"Q则׃无法~码Q最后返回?3f (tng)3f"Q两个问P(j)。?br />
3.2. (tng)new (tng)String(charset) (tng)

q是java字符串处理的另一个标准函敎ͼ和上一个函数的作用相反Q将字节数组按照charset~码q行l合识别Q最后{换ؓ(f)unicode存储。参考上qgetBytes的例子,"gbk" (tng)?utf8"都可以得出正的l果"4e2d (tng)6587"Q但iso8859-1最后变成了(jin) (tng)"003f (tng)003f"Q两个问P(j)。?br />
因ؓ(f)utf8可以用来表示/~码所有字W,所以new (tng)String( (tng)str.getBytes( (tng)"utf8" (tng)), (tng)"utf8" (tng)) (tng)=== (tng)strQ即完全可逆。?br />
3.3. (tng)setCharacterEncoding() (tng)

该函数用来设|httph或者相应的~码。?br />
对于requestQ是指提交内容的~码Q指定后可以通过getParameter()则直接获得正的字符Ԍ如果不指定,则默认用iso8859-1 (tng)~码Q需要进一步处理。参见下q?表单输入"。值得注意的是在执行setCharacterEncoding()之前Q不能执行Q何?tng)getParameter()。java (tng)doc上说明:(x) (tng)This (tng)method (tng)must (tng)be (tng)called (tng)prior (tng)to (tng)reading (tng)request (tng)parameters (tng)or (tng)reading (tng)input (tng)using (tng)getReader (tng)()。而且Q该指定只对POSTҎ(gu)有效Q对GETҎ(gu)无效。分析原因,应该是在执行W一个getParameter()的时候,java会(x)按照~码分析所有的提交内容Q而后l的getParameter()不再q行分析Q所以setCharacterEncoding()无效。而对于GETҎ(gu)提交表单是,提交的内容在URL中,一开始就已经按照~码分析所有的提交内容QsetCharacterEncoding()自然无效。?br />
对于responseQ则是指定输出内容的~码Q同Ӟ该设|会(x)传递给览器,告诉览器输出内Ҏ(gu)采用的编码。?br />
3.4. (tng)处理q程 (tng)

下面分析两个有代表性的例子Q说明java对编码有关问题的处理Ҏ(gu)。?br />
3.4.1. (tng)表单输入 (tng)

User (tng)input (tng) (tng)* (tng)(gbk:d6d0 (tng)cec4) (tng) (tng)browser (tng) (tng)*(gbk:d6d0 (tng)cec4) (tng) (tng)web (tng)server (tng) (tng)iso8859-1(00d6 (tng)00d (tng)000ce (tng)00c4) (tng) (tng) (tng)classQ需要在class中进行处理:(x)getbytes("iso8859-1")为d6 (tng)d0 (tng)ce (tng)c4Qnew (tng)String (tng)("gbk")为d6d0 (tng)cec4Q内存(sh)以unicode~码则ؓ(f)4e2d (tng)6587。?br />
l (tng)用户输入的编码方式和面指定的编码有养I也和用户的操作系l有养I所以是不确定的Q上例以gbkZ。?br />
l (tng)从browser到web (tng)serverQ可以在表单中指定提交内Ҏ(gu)使用的字W集Q否则会(x)使用面指定的编码。而如果在url中直接用?的方式输入参敎ͼ则其~码往往是操作系l本w的~码Q因时和面无关。上qC旧以gbk~码Z。?br />
l (tng)Web (tng)server (tng)接收到的是字节流Q默认时QgetParameterQ会(x)以iso8859-1~码处理之,l果是不正确的,所以需要进行处理。但如果预先讄?jin)编码(通过request. (tng)setCharacterEncoding (tng)()Q,则能够直接获取到正确的结果。?br />
l (tng)在页面中指定~码是个好习(fn)惯,否则可能失去控制Q无法指定正的~码。?br />
3.4.2. (tng)文g~译 (tng)

假设文g是gbk~码保存的,而编译有两种~码选择Qgbk或者iso8859-1Q前者是中文windows的默认编码,后者是linux的默认编码,当然也可以在~译时指定编码。?br />
Jsp (tng) (tng)* (tng)(gbk:d6d0 (tng)cec4) (tng) (tng)java (tng)file (tng) (tng)*(gbk:d6d0 (tng)cec4) (tng) (tng)compiler (tng)read (tng) (tng)uincode(gbk: (tng) (tng)4e2d (tng)6587; (tng)iso8859-1: (tng)00d6 (tng)00d (tng)000ce (tng)00c4) (tng) (tng)compiler (tng)write (tng) (tng)utf(gbk: (tng)e4b8ad (tng)e69687; (tng) (tng)iso8859-1: (tng)*) (tng) (tng)compiled (tng)file (tng) (tng)unicode(gbk: (tng)4e2d (tng)6587; (tng)iso8859-1: (tng)00d6 (tng)00d (tng)000ce (tng)00c4) (tng) (tng) (tng)class。所以用gbk~码保存Q而用iso8859-1~译的结果是不正的。?br />
class (tng) (tng)unicode(4e2d (tng)6587) (tng) (tng)system.out (tng)/ (tng)jsp.out (tng) (tng)gbk(d6d0 (tng)cec4) (tng) (tng)os (tng)console (tng)/ (tng)browser。?br />
l (tng)文g可以以多U编码方式保存,中文windows下,默认为ansi/gbk。?br />
l (tng) (tng)~译器读取文件时Q需要得到文件的~码Q如果未指定Q则使用pȝ默认~码。一般class文gQ是以系l默认编码保存的Q所以编译不?x)出问题Q但对于 (tng)jsp文gQ如果在中文windows下编辑保存,而部|在英文linux下运?~译Q则?x)出现问题。所以需要在jsp文g中用 (tng)pageEncoding指定~码。?br />
l (tng)Java~译的时候会(x)转换成统一的unicode~码处理Q最后保存的时候再转换为utf~码。?br />
l (tng) (tng)当系l输出字W的时候,?x)按指定~码输出Q对于中文windows下,System.out用gbk~码Q而对于responseQ浏览器Q,则用?tng)jsp文g头指定的contentTypeQ或者可以直接ؓ(f)response指定~码。同Ӟ?x)告诉browser|页的编码。如果未指定Q则?x)用 (tng)iso8859-1~码。对于中文,应该为browser指定输出字符串的~码。?br />
l (tng)browser昄|页的时候,首先使用response中指定的~码Qjsp文g头指定的contentType最l也反映在response上)(j)Q如果未指定Q则?x)用网中metaҎ(gu)定中的contentType。?br />
3.5. (tng)几处讄 (tng)

对于web应用E序Q和~码有关的设|或者函数如下。?br />
3.5.1. (tng)jsp~译 (tng)

指定文g的存储编码,很明显,该设|应该置于文件的开头。例如:(x)<%@page (tng)pageEncoding="GBK"%>。另外,对于一般class文gQ可以在~译的时候指定编码。?br />
3.5.2. (tng)jsp输出 (tng)

指定文g输出到browser是用的~码Q该讄也应该置于文件的开头。例如:(x)<%@ (tng)page (tng)contentType="text/html; (tng) (tng)charset= (tng)GBK" (tng)%>。该讄和response.setCharacterEncoding("GBK"){效。?br />
3.5.3. (tng)meta讄 (tng)

指定|页使用的编码,该设|对?rn)态网尤其有作用。因为静(rn)态网|法采用jsp的设|,而且也无法执行response.setCharacterEncoding()。例如:(x) (tng)

如果同时采用?jin)jsp输出和meta讄两种~码指定方式Q则jsp指定的优先。因为jsp指定的直接体现在response中。?br />
需要注意的是,apache有一个设|可以给无编码指定的|页指定~码Q该指定{同于jsp的编码指定方式,所以会(x)覆盖?rn)态网中的meta指定。所以有人徏议关闭该讄。?br />
3.5.4. (tng)form讄 (tng)

当浏览器提交表单的时候,可以指定相应的编码。例如:(x)。一般不必不使用该设|,览器会(x)直接使用|页的编码。?br />
4. (tng)pȝ软g (tng)

下面讨论几个相关的系lY件。?br />
4.1. (tng)mysql数据库?br />
很明显,要支持多语言Q应该将数据库的~码讄成utf或者unicodeQ而utf更适合与存储。但是,如果中文数据中包含的英文字母很少Q其实unicode更ؓ(f)适合。?br />
数据库的~码可以通过mysql的配|文件设|,例如default-character-set=utf8。还可以在数据库链接URL中设|,例如Q?tng) (tng)useUnicode=true&characterEncoding=UTF-8。注意这两者应该保持一_(d)在新的sql版本里,在数据库链接URL里可以不q行讄Q但也不能是错误的设|。?br />
4.2. (tng)apache (tng)

appache和编码有关的配置在httpd.conf中,例如AddDefaultCharset (tng)UTF-8。如前所qͼ该功能会(x)所有静(rn)态页面的~码讄为UTF-8Q最好关闭该功能。?br />
另外Qapacheq有单独的模块来处理|页响应_(d)其中也可能对~码q行讄。?br />
4.3. (tng)linux默认~码 (tng)

q里所说的linux默认~码Q是指运行时的环境变量。两个重要的环境变量是LC_ALL和LANGQ默认编码会(x)影响到java (tng)URLEncode的行为,下面有描q。?br />
都设|ؓ(f)"zh_CN.UTF-8"。?br />
4.4. (tng)其它 (tng)

Z(jin)支持中文文g名,linux在加载磁盘时应该指定字符集,例如Qmount (tng)/dev/hda5 (tng)/mnt/hda5/ (tng)-t (tng)ntfs (tng)-o (tng)iocharset=gb2312。?br />
另外Q如前所qͼ使用GETҎ(gu)提交的信息不支持request.setCharacterEncoding()Q但可以通过tomcat的配|文件指定字W集Q在tomcat的server.xml文g中,形如Q。这U方法将l一讄所有请求,而不能针对具体页面进行设|,也不一定和browser使用的编码相同,所以有时候ƈ不是所期望的。?br />
5. (tng)URL地址 (tng)

URL地址中含有中文字W是很麻?ch)的Q前面描q过使用GETҎ(gu)提交表单的情况,使用GETҎ(gu)Ӟ参数是包含在URL中。?br />
5.1. (tng)URL~码 (tng)

对于URL中的一些特D字W,览器会(x)自动q行~码。这些字W除?/?&"{外Q还包括unicode字符Q比如汉子。这时的~码比较Ҏ(gu)。?br />
IE (tng)有一个选项"L使用UTF-8发送URL"Q当该选项有效ӞIE会(x)对特D字W进行UTF-8~码Q同时进行URL~码。如果改选项无效Q则使用默认~码"GBK"Qƈ且不q行URL~码。但是,对于URL后面的参敎ͼ则L不进行编码,相当于UTF-8选项无效。比?中文.html?a=中文"Q当UTF-8选项有效Ӟ发送链?%e4%b8%ad%e6%96%87.html?a=\x4e\x2d\x65\x87"Q而UTF-8选项无效Ӟ发送链?\x4e\x2d\x65\x87.html?a=\x4e\x2d\x65\x87"。注意后者前面的"中文"两个字只?个字节,而前者却?8个字节,q主要时URL~码的原因。?br />
当web (tng)serverQtomcatQ接收到该链接时Q将?x)进行URL解码Q即L (tng)"%"Q同时按照ISO8859-1~码Q上面已l描qͼ可以使用URLEncoding来设|成其它~码Q识别。上qC子的l果分别?\ue4\ (tng)ub8\uad\ue6\u96\u87.html?a=\u4e\u2d\u65\u87"?\u4e\u2d\u65\u87.html?a=\ (tng)u4e\u2d\u65\u87"Q注意前者前面的"中文"两个字恢复成?个字W。这里用"\u"Q表C是unicode。?br />
所以,׃客户端设|的不同Q相同的链接Q在服务器上得到?jin)不同结果。这个问题(sh)h都遇刎ͼ却没有很好的解决办法。所以有的网站会(x)用户试关闭UTF-8选项。不q,下面?x)描qC个更好的处理办法。?br />
5.2. (tng)rewrite (tng)

熟?zhn)的h都知道,apache有一个功能强大的rewrite模块Q这里不描述其功能。需要说明的是该模块?x)自动将URL解码Q去?Q,卛_成上qWweb (tng)serverQtomcatQ的部分功能。有相关文档介绍说可以用[NE]参数来关闭该功能Q但我试验ƈ未成功,可能是因为版本(我用的是?tng)apache (tng)2.0.54Q问题。另外,当参C含有"?& (tng)"{符L(fng)时候,该功能将Dpȝ得不到正常结果。?br />
rewrite本ng完全是采用字节处理的方式Q而不考虑字符串的~码Q所以不?x)带来编码问题。?br />
5.3. (tng)URLEncode.encode() (tng)

q是Java本n提供对的URL~码函数Q完成的工作和上qUTF-8选项有效时浏览器所做的工作怼。值得说明的是Qjava已经不赞成不指定~码来用该Ҏ(gu)QdeprecatedQ。应该在使用的时候增加编码指定。?br />
当不指定~码的时候,该方法用系l默认编码,q会(x)D软gq行l果得不定。比如对?中文"Q当pȝ默认~码?gb2312"Ӟl果?%4e% (tng)2d%65%87"Q而默认编码ؓ(f)"UTF-8"Q结果却?%e4%b8%ad%e6%96%87"Q后l程序将难以处理。另外,q儿说的pȝ默认~码是由q行tomcat时的环境变量LC_ALL和LANG{决定的Q曾l出现过tomcat重启后就出现q的问题,最后才郁闷的发现是因ؓ(f)修改修改?jin)这两个环境变量。?br />
l一指定?UTF-8"~码Q可能需要修改相应的E序。?br />
5.4. (tng)一个解x(chng)案?br />
上面说vq,因ؓ(f)览器设|的不同Q对于同一个链接,web (tng)server收到的是不同内容Q而Y件系l有无法知道q中间的区别Q所以这一协议目前q存在缺陗?br />
针对具体问题Q不应该侥幸认ؓ(f)所有客L(fng)IE讄都是UTF-8有效的,也不应该_暴的徏议用户修改IE讄Q要知道Q用户不可能去记住每一个web (tng)server的设|。所以,接下来的解决办法只能是让自qE序多一Ҏ(gu)能:(x)Ҏ(gu)内容来分析编码是否UTF-8。?br />
比较q运的是UTF-8~码相当有规律,所以可以通过分析传输q来的链接内容,来判断是否是正确的UTF-8字符Q如果是Q则以UTF-8处理之,如果不是Q则使用客户默认~码Q比?GBK"Q,下面是一个判断是否UTF-8的例子,如果你了(jin)解相应规律,容易理解。?br />
public (tng)static (tng)boolean (tng)isValidUtf8(byte[] (tng)b,int (tng)aMaxCount){ (tng)

 (tng) (tng) (tng) (tng) (tng) (tng) (tng)int (tng)lLen=b.length,lCharCount=0; (tng)

 (tng) (tng) (tng) (tng) (tng) (tng) (tng)for(int (tng)i=0;i

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)byte (tng)lByte=b[i++];//to (tng)fast (tng)operation, (tng)++ (tng)now, (tng)ready (tng)for (tng)the (tng)following (tng)for(;;) (tng)

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)if(lByte>=0) (tng)continue;//>=0 (tng)is (tng)normal (tng)ascii (tng)

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)if(lByte<(byte)0xc0 (tng)|| (tng)lByte>(byte)0xfd) (tng)return (tng)false; (tng)

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)int (tng)lCount=lByte>(byte)0xfc?5:lByte>(byte)0xf8?4 (tng)

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng):lByte>(byte)0xf0?3:lByte>(byte)0xe0?2:1; (tng)

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)if(i+lCount>lLen) (tng)return (tng)false; (tng)

 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)for(int (tng)j=0;j=(byte)0xc0) (tng)return (tng)false; (tng)

 (tng) (tng) (tng) (tng) (tng) (tng) (tng)} (tng)

 (tng) (tng) (tng) (tng) (tng) (tng) (tng)return (tng)true; (tng)

} (tng)

相应圎ͼ一个用上q方法的例子如下Q?br />
public (tng)static (tng)String (tng)getUrlParam(String (tng)aStr,String (tng)aDefaultCharset) (tng)

throws (tng)UnsupportedEncodingException{ (tng)

 (tng) (tng) (tng) (tng) (tng) (tng) (tng)if(aStr==null) (tng)return (tng)null; (tng)

 (tng) (tng) (tng) (tng) (tng) (tng) (tng)byte[] (tng)lBytes=aStr.getBytes("ISO-8859-1"); (tng)

 (tng) (tng) (tng) (tng) (tng) (tng) (tng)return (tng)new (tng)String(lBytes,StringUtil.isValidUtf8(lBytes)?"utf8":aDefaultCharset); (tng)

} (tng)

不过Q该Ҏ(gu)也存在缺P如下两方面:(x) (tng)

l (tng)没有包括对用户默认编码的识别Q这可以Ҏ(gu)h信息的语a来判断,但不一定正,因ؓ(f)我们有时候也?x)输入一些韩文,或者其他文字。?br />
l (tng)可能?x)错误判断UTF-8字符Q一个例子是"学习(fn)"两个字,其GBK~码? (tng)\xd1\xa7\xcf\xb0"Q如果用上qisValidUtf8Ҏ(gu)判断Q将q回true。可以考虑使用更严格的判断Ҏ(gu)Q不q估计效果不大。?br />
有一个例子可以证明google也遇C(jin)上述问题Q而且也采用了(jin)和上q相似的处理Ҏ(gu)Q比如,如果在地址栏中输入"http: (tng)//www.google.com/search?hl=zh-CN&newwindow=1&q=学习(fn)"Qgoogle无法正识别,而其他汉字一般能够正常识别。?br />
最后,应该补充说明一下,如果不用rewrite规则Q或者通过表单提交数据Q其实ƈ不一定会(x)遇到上述问题Q因时可以在提交数据时指定希望的~码。另外,中文文g名确实会(x)带来问题Q应该}慎用。?br />
6. (tng)其它 (tng)

下面描述一些和~码有关的其他问题。?br />
6.1. (tng)SecureCRT (tng)

除了(jin)览器和控制C~码有关外,一些客L(fng)也很有关pR比如在使用SecureCRTq接linuxӞ应该让SecureCRT的显C编码(不同的sessionQ可以有不同的编码设|)(j)和linux的编码环境变量保持一致。否则看到的一些帮助信息,可能是q。?br />
另外Qmysql有自q~码讄Q也应该保持和SecureCRT的显C编码一致。否则通过SecureCRT执行sql语句的时候,可能无法处理中文字符Q查询结果也?x)出Cؕ码。?br />
对于Utf-8文gQ很多编辑器Q比如记事本Q会(x)在文件开头增加三个不可见的标志字节,如果作ؓ(f)mysql的输入文Ӟ则必要Lq三个字W。(用?tng)linux的vi保存可以Lq三个字W)(j)。一个有的现象是,在中文windows下,创徏一个新txt文gQ用C本打开Q输?q?两个字,保存Q再打开Q你?x)发C个字没了(jin)Q只留下一个小黑点。?br />
6.2. (tng)qo(h)器?br />
如果需要统一讄~码Q则通过filterq行讄是个不错的选择。在filter (tng)class中,可以l一为需要的h或者回应设|编码。参加上qsetCharacterEncoding()。这个类apache已经l出?jin)可以直接用的例子SetCharacterEncodingFilter。?br />
6.3. (tng)POST和GET (tng)

很明显,以POST提交信息ӞURL有更好的可读性,而且可以方便的用setCharacterEncoding()来处理字W集问题。但GETҎ(gu)形成的URL能够更容易表辄늚实际内容Q也能够用于收藏。?br />
从统一的角度考虑问题Q徏议采用GETҎ(gu)Q这要求在程序中获得参数是进行特D处理,而无法用setCharacterEncoding()的便利,如果不考虑rewriteQ就不存在IE的UTF-8问题Q可以考虑通过讄URIEncoding来方便获取URL中的参数。?br />
6.4. (tng)J体~码转换 (tng)

GBK (tng)同时包含体和J体~码Q也是说同一个字Q由于编码不同,在GBK~码下属于两个字。有时候,Z(jin)正确取得完整的结果,应该繁体和体进行统一。可以考虑UTF、GBK中的所有繁体字Q{换ؓ(f)相应的简体字QBIG5~码的数据,也应该{化成相应的简体字。当?dng)仍旧以UTF~码存储。?br />
例如Q对?语言 (tng)?a"Q用UTF表示?\xE8\xAF\xAD\xE8\xA8\x80 (tng)\xE8\xAA\x9E\xE8\xA8\x80"Q进行简J体~码转换后应该是两个相同的?\xE8\xAF\xAD\xE8\xA8\x80>"。?br />

matthew 2006-11-15 09:11 发表评论
]]>
MD5加密?qing)Java的实现方式- 转脓(chung)http://www.aygfsteel.com/matthew2006/archive/2006/08/10/62719.htmlmatthewmatthewThu, 10 Aug 2006 01:51:00 GMThttp://www.aygfsteel.com/matthew2006/archive/2006/08/10/62719.htmlhttp://www.aygfsteel.com/matthew2006/comments/62719.htmlhttp://www.aygfsteel.com/matthew2006/archive/2006/08/10/62719.html#Feedback0http://www.aygfsteel.com/matthew2006/comments/commentRss/62719.htmlhttp://www.aygfsteel.com/matthew2006/services/trackbacks/62719.html首先
 (tng) (tng) (tng)我看到很多脓(chung)子,上面描述MD5加密解密{话题,因此写此文章Z(jin)把MD5加密问题单的说个透彻Qƈ且给大家已经实践q的代码?br />
其次
 (tng) (tng) (tng)MD5加密q不是把原文加密Q这个大家得注意Q既然没有把原文加密何来的解密呢Q简直是个笑话。MD5的用途就是把一D原文数据通过一定的法生成16字节的密文,通过q个密文我们可以(g)查原文的数据是否被修改过。常用在|络中明文数据传输,防止传输q程中内容被恶意修改。典型的应用协议为radiusQradius协议中有16byte是MD5所留的Q把用户的密码加在报文尾部进行MD5Q把l果存在|络中,所以明文部分看不到用户的密码,当服务器收到此包Q用同样的方法进行MD5Q如果加密出来的16byte一P说明是有效的未被恶意修改的网l包?br />
最?/b>
附上实现的代?br />
  1. import (tng)java.security.*;
  2. public (tng)class (tng)MD5 (tng){
  3.  (tng) (tng)/**
  4.  (tng) (tng) (tng)* (tng)MD5
  5.  (tng) (tng) (tng)*
  6.  (tng) (tng) (tng)* (tng)@author (tng)Dreamer
  7.  (tng) (tng) (tng)*/
  8.  (tng) (tng)public (tng)MD5() (tng){
  9.  (tng) (tng)}
  10.  (tng) (tng)public (tng)static (tng)byte[] (tng)md5(byte[] (tng)in) (tng){
  11.  (tng) (tng) (tng) (tng)MessageDigest (tng)md (tng)= (tng)null;
  12.  (tng) (tng) (tng) (tng)byte[] (tng)out (tng)= (tng)new (tng)byte[16];
  13.  (tng) (tng) (tng) (tng)try (tng){
  14.  (tng) (tng) (tng) (tng) (tng) (tng)md (tng)= (tng)MessageDigest.getInstance("MD5");
  15.  (tng) (tng) (tng) (tng)}
  16.  (tng) (tng) (tng) (tng)catch (tng)(NoSuchAlgorithmException (tng)ex) (tng){
  17.  (tng) (tng) (tng) (tng) (tng) (tng)System.out.println(ex.toString());
  18.  (tng) (tng) (tng) (tng)}
  19.  (tng) (tng) (tng) (tng)md.reset();
  20.  (tng) (tng) (tng) (tng)md.update(in);
  21.  (tng) (tng) (tng) (tng)out (tng)= (tng)md.digest();
  22.  (tng) (tng) (tng) (tng)return (tng)out;
  23.  (tng) (tng)}
  24.  (tng) (tng)public (tng)static (tng)byte[] (tng)md5(byte[] (tng)in, (tng)int (tng)len) (tng){
  25.  (tng) (tng) (tng) (tng)MessageDigest (tng)md (tng)= (tng)null;
  26.  (tng) (tng) (tng) (tng)byte[] (tng)out (tng)= (tng)new (tng)byte[16];
  27.  (tng) (tng) (tng) (tng)try (tng){
  28.  (tng) (tng) (tng) (tng) (tng) (tng)md (tng)= (tng)MessageDigest.getInstance("MD5");
  29.  (tng) (tng) (tng) (tng)}
  30.  (tng) (tng) (tng) (tng)catch (tng)(NoSuchAlgorithmException (tng)ex) (tng){
  31.  (tng) (tng) (tng) (tng) (tng) (tng)System.out.println(ex.toString());
  32.  (tng) (tng) (tng) (tng)}
  33.  (tng) (tng) (tng) (tng)md.reset();
  34.  (tng) (tng) (tng) (tng)md.update(in, (tng)0, (tng)len);
  35.  (tng) (tng) (tng) (tng)out (tng)= (tng)md.digest();
  36.  (tng) (tng) (tng) (tng)return (tng)out;
  37.  (tng) (tng)}
  38. }


matthew 2006-08-10 09:51 发表评论
]]>
Java中的日期处理Q{?/title><link>http://www.aygfsteel.com/matthew2006/archive/2006/07/15/58325.html</link><dc:creator>matthew</dc:creator><author>matthew</author><pubDate>Sat, 15 Jul 2006 06:52:00 GMT</pubDate><guid>http://www.aygfsteel.com/matthew2006/archive/2006/07/15/58325.html</guid><wfw:comment>http://www.aygfsteel.com/matthew2006/comments/58325.html</wfw:comment><comments>http://www.aygfsteel.com/matthew2006/archive/2006/07/15/58325.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/matthew2006/comments/commentRss/58325.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/matthew2006/services/trackbacks/58325.html</trackback:ping><description><![CDATA[q来上网查了(jin)些java日期处理的资料,其中有些内容觉得比较有实际用处。脓(chung)出来做个记录Q?br /><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><font size="6"><strong><span lang="ZH-CN" style="FONT-SIZE: 22pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt; mso-fareast-language: ZH-CN"></span></strong></font><strong><span lang="EN-US" style="FONT-SIZE: 22pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt; mso-fareast-language: ZH-CN"><?XML:NAMESPACE PREFIX = O /?><o:p><font size="4">1 日期模板</font></o:p></span></strong></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="ZH-CN" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt; mso-fareast-language: ZH-CN">模板定义如下Q?/span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt; mso-fareast-language: ZH-CN"><o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt; mso-fareast-language: ZH-CN">y </span><span lang="ZH-CN" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt; mso-fareast-language: ZH-CN">q号Q如</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt; mso-fareast-language: ZH-CN">1996<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">M 月䆾Q如July 或?7<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">d 月中W几天,?2<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt; mso-fareast-language: ZH-CN">H </span><span lang="ZH-CN" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt; mso-fareast-language: ZH-CN">时</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt; mso-fareast-language: ZH-CN">(24 </span><span lang="ZH-CN" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt; mso-fareast-language: ZH-CN">?/span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt; mso-fareast-language: ZH-CN">)</span><span lang="ZH-CN" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt; mso-fareast-language: ZH-CN">Q如</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt; mso-fareast-language: ZH-CN">0</span><span lang="ZH-CN" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt; mso-fareast-language: ZH-CN">?/span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt; mso-fareast-language: ZH-CN">17<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">m 分钟,?2<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">s 钞钟Q如55<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">S 微钞Q如978<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">E 星期几,如Tuesday<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">D 一q中的第几天Q如189<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">w week in year (Number) 27<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">W week in month (Number) 2<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">a am/pm marker (Text) PM<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">k hour in day (1~24) (Number) 24<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">K hour in am/pm (0~11) (Number) 0<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">z time zone (Text) Pacific Standard Time<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">' escape for text (Delimiter)<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">'' single quote (Literal) '<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><strong><span lang="EN-US" style="FONT-SIZE: 22pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt"><o:p><font size="4">2 日期格式</font></o:p></span></strong></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">使用<span lang="EN-US">SimpleDateFormat cL式化日期Q如果日期格式不对,?x)生异常?o:p></o:p></span></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">import java.text.*;<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">import java.util.*;<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">public class TestDate {<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">public static void main(String[] args) {<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">String dStr = "2001.12.12-08.23.21";<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">Date d = null;<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd- HH.mm.ss");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">try {</span><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt"><o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">http://www.54he.com </span><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">何vq?span lang="EN-US">hp54@163.com<o:p></o:p></span></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">d = sdf.parse(dStr);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">} catch (ParseException pe) {<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">System.out.println(pe.getMessage());<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">}<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">System.out.println(d);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">System.out.println(d.getTime());<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">}<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">}<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">?span lang="EN-US">java.text 包中扑ֈ那个SimpleDateFormat c,l它一个模板,可以parse 成一个DateQ然后用Date<o:p></o:p></span></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">cȝ<span lang="EN-US">getItme() Ҏ(gu)Q可以得C个Long 数据?o:p></o:p></span></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt"><font size="4"><strong>3 取得当前日期</strong></font><br />public String GetDateTime()<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">{<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">Calendar cal = Calendar.getInstance();<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">SimpleDateFormat formatter = new SimpleDateFormat("yyyy- MM-dd HH:mm:ss");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">String mDateTime=formatter.format(cal.getTime());<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">return (mDateTime);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">}<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">public java.sql.Date GetDate()<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">{<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">java.sql.Date mDate;<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">Calendar cal = Calendar.getInstance();<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">SimpleDateFormat formatter = new SimpleDateFormat("yyyy- MM-dd HH:mm:ss");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">String mDateTime=formatter.format(cal.getTime());<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">return (java.sql.Date.valueOf(mDateTime));<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">}<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><strong><span lang="EN-US" style="FONT-SIZE: 22pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt"><o:p><font size="4">4 当前旉</font></o:p></span></strong></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">Calendar cal = Calendar.getInstance();<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">// SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM- dd HH:mm:ss");</span><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt"><o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt"><span lang="EN-US"><o:p></o:p></span></span> (tng)</p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss G E D F w W a E F");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">String mDateTime=formatter.format(cal.getTime());<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">out.println(mDateTime);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">out.println("<br>");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><strong><span lang="EN-US" style="FONT-SIZE: 22pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt"><o:p><font size="4">5 一q前日期</font></o:p></span></strong></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">java.util.Date myDate=new java.util.Date();<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">long myTime=(myDate.getTime()/1000)-60*60*24*365;<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">myDate.setTime(myTime*1000);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">String mDate=formatter.format(myDate);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">out.println(mDate);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">out.println("<br>");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><strong><span lang="EN-US" style="FONT-SIZE: 22pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt"><o:p><font size="4">6 明天日期</font></o:p></span></strong></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">myDate=new java.util.Date();<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">myTime=(myDate.getTime()/1000)+60*60*24;<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">myDate.setTime(myTime*1000);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">mDate=formatter.format(myDate);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">out.println(mDate);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">out.println("<br>");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt"><strong><font size="4">7 两个旉之间的天?/font></strong><br />SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM- dd");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">java.util.Date date= myFormatter.parse("2003-05-1");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">java.util.Date mydate= myFormatter.parse("1899-12-30");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">long day=(date.getTime()-mydate.getTime())/(24*60*60*1000);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">out.println(day);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">out.println("<br>");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><strong><span lang="EN-US" style="FONT-SIZE: 22pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt"><o:p><font size="4">8 加半时</font></o:p></span></strong></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">java.util.Date date1 = format.parse("2002-02-28 23:16:00");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">long Time=(date1.getTime()/1000)+60*30;<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">date1.setTime(Time*1000);</span><span lang="EN-US" style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt"><o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt"><span lang="EN-US"><o:p></o:p></span></span> (tng)</p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">String mydate1=formatter.format(date1);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">out.println(mydate1);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">out.println("<br>");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><strong><span lang="EN-US" style="FONT-SIZE: 22pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt"><o:p><font size="4">9 q月周求日期</font></o:p></span></strong></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM F E");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">java.util.Date date2= formatter2.parse("2003-05 5 星期?);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">SimpleDateFormat formatter3 = new SimpleDateFormat("yyyy-MM-dd");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">String mydate2=formatter3.format(date2);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">out.println(mydate2);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">out.println("<br>");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><strong><span lang="EN-US" style="FONT-SIZE: 22pt; COLOR: black; FONT-FAMILY: SimSun; mso-font-kerning: 0pt"><o:p><font size="4">10 求给定日期是星期?/font></o:p></span></strong></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">mydate= myFormatter.parse("2001-1-1");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">SimpleDateFormat formatter4 = new SimpleDateFormat("E");<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">String mydate3=formatter4.format(mydate);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">out.println(mydate3);<o:p></o:p></span></p><p class="MsoNormal" style="MARGIN: 0mm 0mm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #333333; FONT-FAMILY: SimSun; mso-font-kerning: 0pt">out.println("<br>");<o:p></o:p></span></p><img src ="http://www.aygfsteel.com/matthew2006/aggbug/58325.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/matthew2006/" target="_blank">matthew</a> 2006-07-15 14:52 <a href="http://www.aygfsteel.com/matthew2006/archive/2006/07/15/58325.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>常见java面试?/title><link>http://www.aygfsteel.com/matthew2006/archive/2006/06/29/55813.html</link><dc:creator>matthew</dc:creator><author>matthew</author><pubDate>Thu, 29 Jun 2006 12:08:00 GMT</pubDate><guid>http://www.aygfsteel.com/matthew2006/archive/2006/06/29/55813.html</guid><wfw:comment>http://www.aygfsteel.com/matthew2006/comments/55813.html</wfw:comment><comments>http://www.aygfsteel.com/matthew2006/archive/2006/06/29/55813.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/matthew2006/comments/commentRss/55813.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/matthew2006/services/trackbacks/55813.html</trackback:ping><description><![CDATA[ <p>Java基础斚w:</p> <p>1,作用域public,protected,private,以及(qing)不写时的区别</p> <p> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<font color="#0033ff">作用域?tng) (tng) (tng)?/font> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) <font color="#0033ff">当前c?tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)?同一package (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)  (tng)子孙c?tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)?其他package </font></p> <p> <font color="#0033ff"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) </font> <font color="#cc3333">public (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) √?tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)?√?tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)?√?tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)??/font> </p> <p> <font color="#cc3333"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</font> <font color="#cc3333"> protected (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) √?tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)?√?tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)?√?tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)?×</font> </p> <p> <font color="#cc3333"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</font> <font color="#cc3366"> friendly (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) √?tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)?√?tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)× (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)?×</font> </p> <p> <font color="#cc3366"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</font> <font color="#993333"> (tng) private (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)√?tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)?× (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) × (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)×</font> </p> <p> <font color="#993333"> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)不写旉认ؓ(f)friendly <br /></font> </p> <p>2,ArrayList和Vector的区?HashMap和Hashtable的区?/p> <p> <font color="#0033ff">{:(x)ArrayList与Vector主要从二斚w来说. <br />一.同步?Vector是线E安全的Q也是说是同步的,而ArrayList是线E序不安全的Q不是同步的 <br />?数据增长:当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一?<br />HashMap与HashTable主要从三斚w来说?<br />一.历史原因:Hashtable是基于陈旧的DictionarycȝQHashMap是Java 1.2引进的Map接口的一个实?<br />?同步?Hashtable是线E安全的Q也是说是同步的,而HashMap是线E序不安全的Q不是同步的 <br />?|(x)只有HashMap可以让你空gZ个表的条目的key或value </font> </p> <p>3,char型变量能不能定义Z个中?Z?</p> <p> <font color="#0033ff">是能够定义成Z个中文的Q因为java中以unicode~码Q一个char?6个字节,所以放一个中文是没问题的 <br /></font> </p> <p>4,多线E有几种表示Ҏ(gu),都是什?同步有几U实现方?都是什?</p> <p> <font color="#0033ff">多线E有两种实现Ҏ(gu)Q分别是l承ThreadcM实现Runnable接口 <br />同步的实现方面有一U,使用synchronized,wait,notify <br /></font> </p> <p>5,l承时候类的执行顺序问?一般都是选择?问你会(x)打印Z?</p> <p>6,内部cȝ实现方式?</p> <p>7,垃圾回收机制,如何优化E序?</p> <p>8,float型float f=3.4是否正确?</p> <p>Jsp斚w</p> <p>1,jsp有哪些内|对?作用分别是什?</p> <p>2,jsp有哪些动?作用分别是什?</p> <p>3,include的两U实现方式的区别?</p> <p>4,两种跌{方式分别是什?有什么区?</p> <p>Servlet斚w</p> <p>1,说一说Servlet的生命周?</p> <p>2,Servlet版本?忘(sh)(jin)问的是哪两个版本?的不?</p> <p>Jdbc,Jdo斚w</p> <p>1,可能?x)让你写一DJdbcqOracle的程?</p> <p>2,Class.forName的作?Z么要?</p> <p>3,Jdo是什?</p> <p> <font color="#0000ff">JDO是Java对象持久化的规范之一Qؓ(f)java data object的简U?是一个用于存取某U数据仓库中的对象的标准化API。JDO提供?jin)透明的对象存储,因此对开发h员来_(d)存储数据对象完全不需要额外的代码Q如JDBC API的用)(j)。这些繁琐的例行工作已经转移到JDO产品提供商n上,使开发h员解脱出来,从而集中时间和_֊在业务逻辑上。另外,JDO很灵z,因ؓ(f)它可以在M数据底层上运行。JDBC只是面向关系数据库(RDBMS)JDO更通用Q提供到M数据底层的存储功能,比如关系数据库、文件、XML以及(qing)对象数据库(ODBMSQ等{,使得应用可移植性更强?/font> </p> <p>Xml斚w</p> <p>1,xml有哪些解析技?区别是什?</p> <p> <font color="#0000cc">DOM:处理大型文g时其性能下降的非常厉実뀂这个问题是由DOM的树(wi)l构所造成的,q种l构占用的内存较多,而且DOM必须在解析文件之前把整个文档装入内存,适合对XML的随?/font> </p> <p> <font color="#0000cc">SAX:不现于DOM,SAX是事仉动型的XML解析方式。它序dXML文gQ不需要一ơ全部装载整个文件。当遇到像文件开_(d)文档l束Q或者标{ּ头与标签l束Ӟ它会(x)触发一个事Ӟ用户通过在其回调事g中写入处理代码来处理XML文gQ适合对XML的顺序访?</font> </p> <p> <font color="#0000cc"> <br />STAX:Streaming API for XML (StAX)</font> </p> <p>2,你在目中用C(jin)xml技术的哪些斚w?如何实现?</p> <p> <font color="#0000ff">用到?jin)数据存贮,信息配置两方面。在做数据交换^台时Q将不同数据源的数据l装成XML文gQ然后将XML文g压羃打包加密后通过|络传送给接收者,接收解密与解压羃后再同XML文g中还原相关信息进行处理。在做Y仉|时Q利用XML可以很方便的q行QY件的各种配置参数都存贮在XML文g中?/font> <br /> </p> <p>3,用jdom解析xml文g时如何解决中文问?如何解析?</p> <p>EJB斚w</p> <p>1,EJB2.0有哪些内?分别用在什么场? EJB2.0和EJB1.1的区?</p> <p>MVC斚w</p> <p>1,MVC的各个部分都有那些技术来实现?如何实现?</p> <p>设计模式斚w:</p> <p>1,开发中都用C(jin)那些设计模式?用在什么场?</p> <p>JavaScript斚w</p> <p> (tng) (tng) (tng) (tng) (tng) 1,如何校验数字?</p> <p>CORBA</p> <p> (tng) (tng) (tng) (tng) (tng) 1,CORBA是什?用途是什?</p> <p> (tng)</p> <p>以上是我的ȝ,可能不是全部,因ؓ(f)旉问题,如果能够记v?我会(x)再加?有些问题描述的可能不准确,希望大家批评指正,问题都很基础,即不知?׃一Ҏ(gu)间查?csdn/java?p弄懂,希望Ҏ(gu)在找工作的朋友有所帮助,有所提醒.一份正率很高的笔试卷可能?x)?f)你的面试减轻负担,问不少问题.</p> <p>当然我还是要提醒?br /></p> <h2 align="center"> <a id="viewpost" > <font style="BACKGROUND-COLOR: #f5f5dc" color="#800080"> <u>Java陷阱一筐----面试题集</u> </font> </a> </h2> <p>扑ַ作要面试Q有面试有对付面试的办法。以下一些题目来自我和我朋友痛苦的面试经历,提这些问题的公司包括IBM, E*Trade, Siebel, Motorola, SUN, 以及(qing)其它大小公司?br /><br />面试是没什么道理可讲的Q它的题目有的不合情理、脱d际。有在纸上写的,有当面考你的,也有在电(sh)话里问的Q给你I(yng)DE的估计很?否则你赶快去买彩, 说不定中)。所以如果你看完此文后,请不要抱怨说q些问题都能用IDE来解冟뀂你必须在Q何情况下准确回答q些问题Q在面试中如果出C两题回答不准很 有可能你p拒之门外?jin)?br /><br />当然q些都是Java的基本题Q那些面试的人大多数不会(x)问你Hibernate有多先进QEclipse的三个组成部分,或command design patternQ他们都是老一辈了(jin)Q最喜欢问的是基础知识。别看?jin)这些基Q我朋友水^一,l果栽在一到基知识的问题(sh)Q和高薪无缘?br /><br />好了(jin)废话说Q开始正题?br /><br />W一Q谈谈final, finally, finalize的区别?br />最常被问到?/p> <p> <font color="#0033ff">final—修饰符Q关键字Q如果一个类被声明ؓ(f)finalQ意味着它不能再z出新的子c,不能作ؓ(f)父类被ѝ因此一个类不能既被声明?abstract的,又被声明为final的。将变量或方法声明ؓ(f)finalQ可以保证它们在使用中不被改变。被声明为final的变量必d声明时给定初|而在以后的引用中只能dQ不可修攏V被声明为final的方法也同样只能使用Q不能重?<br />finally—再异常处理时提?finally 块来执行M清除操作。如果抛Z个异常,那么相匹配的 catch 子句׃(x)执行Q然后控制就?x)进?finally 块(如果有的话)(j)?<br />finalize—方法名。Java 技术允怋?finalize() Ҏ(gu)在垃圾收集器对象从内存?sh)清除出M前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对q个对象调用的。它是在 Object cM定义的,因此所有的c都l承?jin)它。子c覆?finalize() Ҏ(gu)以整理系l资源或者执行其他清理工作。finalize() Ҏ(gu)是在垃圾攉器删除对象之前对q个对象调用的?<br /><br /></font> <br />W二QAnonymous Inner Class (匿名内部c? 是否可以extends(l承)其它c,是否可以implements(实现)interface(接口)?<br /></p> <p> <font color="#0033ff">匿名的内部类是没有名字的内部cR不能extends(l承) 其它c,但一个内部类可以作ؓ(f)一个接口,由另一个内部类实现?/font> </p> <p> <br />W三QStatic Nested Class ?Inner Class的不同,说得多好(面试题有的很W统)?/p> <p> (tng)</p> <p> <font color="#0033ff">Nested Class Q一般是C++的说法)(j)QInner Class (一般是JAVA的说?。Java内部cMC++嵌套cL大的不同在于是否有指向外部的引用上。具体可见http: //www.frontfree.net/articles/services/view.asp?id=704&page=1 <br />注:(x) ?rn)态内部类QInner ClassQ意味着1创徏一个static内部cȝ对象Q不需要一个外部类对象Q?不能从一个static内部cȝ一个对象访问一个外部类对象 <br /><br /></font> <br />W四Q?amp;?amp;&的区别?br />q个问得很少?/p> <p> <font color="#0033ff">&是位q算W?amp;&是布?yu)(dng)逻辑q算W?br /></font> <br />W五QHashMap和Hashtable的区别?br />帔R?/p> <p> <font color="#0033ff">都属于Map接口的类Q实C(jin)惟一键映到特定的g?<br />HashMap cL有分cL者排序。它允许一?null 键和多个 null 倹{?<br />Hashtable cM?HashMapQ但是不允许 null 键和 null 倹{它也比 HashMap 慢,因ؓ(f)它是同步的?br /></font> <br />W六QCollection ?Collections的区别?br />你千万别说一个是单数一个是复数?/p> <p> <font color="#0033ff">Collections是个java.util下的c,它包含有各种有关集合操作的静(rn)态方法?<br />Collection是个java.util下的接口Q它是各U集合结构的父接口?<br /></font> <br /> <br />W七Q什么时候用assert?br />APIU的技术h员有可能?x)问q个?/p> <p> <font color="#0033ff">断言是一个包含布?yu)(dng)表辑ּ的语句,在执行这个语句时假定该表辑ּ?true。如果表辑ּ计算?falseQ那么系l会(x)报告一?AssertionError。它用于调试目的Q?<br />assert(a > 0); // throws an AssertionError if a <= 0 <br />断言可以有两UŞ式:(x) <br />assert Expression1 ; <br />assert Expression1 : Expression2 ; <br />Expression1 应该L产生一个布?yu)(dng)倹{?<br />Expression2 可以是得Z个值的L表达式。这个值用于生成显C更多调试信息的 String 消息?<br />断言在默认情况下是禁用的。要在编译时启用断言Q需要?source 1.4 标记Q?<br />javac -source 1.4 Test.java <br />要在q行时启用断aQ可使用 -enableassertions 或?-ea 标记?<br />要在q行旉择用断言Q可使用 -da 或?-disableassertions 标记?<br />要系l类中启用断aQ可使用 -esa 或?-dsa 标记。还可以在包的基上启用或者禁用断a?<br />可以在预计正常情况下不会(x)到达的Q何位|上攄断言。断a可以用于验证传递给U有Ҏ(gu)的参数。不q,断言不应该用于验证传递给公有Ҏ(gu)的参敎ͼ因ؓ(f)不管是否启用?jin)断aQ公有方法都必须(g)查其参数。不q,既可以在公有Ҏ(gu)中,也可以在非公有方法中利用断言试后置条g。另外,断言不应该以M方式改变E序的状态?<br /></font> <br /> <br />W八QGC是什? Z么要有GC? <br />基础?br /></p> <p> <font color="#0033cc">GC是垃圾收集器。Java E序员(sh)用担?j)内存管理,因?f)垃圾攉器会(x)自动q行理。要h垃圾攉Q可以调用下面的Ҏ(gu)之一Q?<br />System.gc() <br />Runtime.getRuntime().gc() <br /></font> <br />W九(ji)QString s = new String("xyz");创徏?jin)几个String Object?</p> <p> <font color="#0033ff">问题太bt,偶不回答Q?br /></font> <br />W十QMath.round(11.5){於多少? Math.round(-11.5){於多少?</p> <p> <font color="#0033ff">Math.round(11.5)q回QlongQ?2QMath.round(-11.5)q回QlongQ?11; <br /></font> <br />W十一Qshort s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?<br />面试题都是很变态的Q要做好受虐的准备?/p> <p> <font color="#0033ff">short s1 = 1; s1 = s1 + 1;有错Qs1是short型,s1+1是int?不能昑ּ转化为short型。可修改为s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正确。?Q?br /><br /></font>W十二,sleep() ?wait() 有什么区?<br />搞线E的最爱?/p> <p> <font color="#0033ff">sleep()Ҏ(gu)是ɾU程停止一D|间的Ҏ(gu)。在sleep 旉间隔期满后,U程不一定立x(chng)复执行。这是因为在那个时刻Q其它线E可能正在运行而且没有被调度ؓ(f)攑ּ执行Q除?a)“醒来”的U程h更高的优先 <br />(b)正在q行的线E因为其它原因而阻塞?<br />wait()是线E交互时Q如果线E对一个同步对象x 发出一个wait()调用Q该U程?x)暂停执行,被调对象q入{待状态,直到被唤醒或{待旉到?<br /><br /></font> <br />W十三,Java有没有goto?<br />很十三的问题Q如果哪个面试的问到q个问题Q我劝你q是别进q家公司?/p> <p> <font color="#0033ff">Goto—java中的保留字,现在没有在java中用?/font> <br /> <br />W十四,数组有没有length()q个Ҏ(gu)? String有没有length()q个Ҏ(gu)?</p> <p> <font color="#0033ff">数组没有length()q个Ҏ(gu)Q有length的属性?<br />String有有length()q个Ҏ(gu)?<br /></font> <br /> <br />W十五,Overload和Override的区别。Overloaded的方法是否可以改变返回值的cd?<br />帔R?/p> <p> <font color="#0033ff">Ҏ(gu)的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父cM子类之间多态性的一U表玎ͼ重蝲Overloading是一个类中多态性的一U表现。如果在子类中定义某Ҏ(gu)与其父类有相同的名称和参敎ͼ我们说该Ҏ(gu)被重?(Overriding)。子cȝ对象使用q个Ҏ(gu)Ӟ调用子cM的定义,对它而言Q父cM的定义如同被“屏蔽”了(jin)。如果在一个类中定义了(jin)多个同名的方法,它们或有不同的参C数或有不同的参数cdQ则UCؓ(f)Ҏ(gu)的重?Overloading)。Overloaded的方法是可以改变q回值的cd?<br /></font> <br /> <br />W十六,Set里的元素是不能重复的Q那么用什么方法来区分重复与否? 是用==q是equals()? 它们有何区别?</p> <p> <font color="#0033ff">Set里的元素是不能重复的Q那么用iterator()Ҏ(gu)来区分重复与否。equals()是判M个Set是否相等?<br />equals()?=Ҏ(gu)军_引用值是否指向同一对象equals()在类中被覆盖Qؓ(f)的是当两个分ȝ对象的内容和cd盔R的话Q返回真倹{?Q不知所云)(j)<br /><br /></font> <br />W十七,l我一个你最常见到的runtime exception?br />如果你这个答不出来,面试的h?x)认Z没有实际~程l验?/p> <p> <font color="#0033ff">ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, <br />ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException <br /></font> <br /> <br />W十八,error和exception有什么区?</p> <p> <font color="#0033ff">error 表示恢复不是不可能但很困隄情况下的一U严重问题。比如说内存溢出。不可能指望E序能处理这L(fng)情况?<br />exception 表示一U设计或实现问题。也是_(d)它表C如果程序运行正常,从不?x)发生的情?/font>?br /><br />W十?ji),List, Set, Map是否l承自Collection接口?</p> <p> <font color="#0033ff">ListQSet?<br /><br />Map不是 <br /></font> <br /> <br />W二十,abstract class和interface有什么区?<br />帔R?/p> <p> <font color="#0033ff">声明Ҏ(gu)的存在而不d现它的类被叫做抽象类Qabstract classQ,它用于要创徏一个体现某些基本行为的c,qؓ(f)该类声明Ҏ(gu)Q但不能在该cM实现该类的情c(din)不能创建abstract cȝ实例。然而可以创Z个变量,其类型是一个抽象类Qƈ让它指向具体子类的一个实例。不能有抽象构造函数或抽象?rn)态方法。Abstract cȝ子类为它们父cM的所有抽象方法提供实玎ͼ否则它们也是抽象cMؓ(f)。取而代之,在子cM实现该方法。知道其行ؓ(f)的其它类可以在类中实现这些方法?<br />接口QinterfaceQ是抽象cȝ变(sh)。在接口中,所有方法都是抽象的。多l承性可通过实现q样的接口而获得。接口中的所有方法都是抽象的Q没有一个有E序体。接口只可以定义static final成员变量。接口的实现与子cȝ|除了(jin)该实现类不能从接口定义中l承行ؓ(f)。当cd现特D接口时Q它定义Q即程序体l予Q所有这U接口的Ҏ(gu)。然后,它可以在实现?jin)该接口的类的Q何对象上调用接口的方法。由于有抽象c,它允怋用接口名作ؓ(f)引用变量的类型。通常的动态联~将生效。引用可以{换到接口cd或从接口cd转换Qinstanceof q算W可以用来决定某对象的类是否实现?jin)接口?/font> <br /> <br /> <br />W二十一Qabstract的method是否可同时是static,是否可同时是nativeQ是否可同时是synchronized?</p> <p> <font color="#0000cc">不能</font> <br /> <br /> <br />W二十二Q接口是否可l承接口? 抽象cL否可实现(implements)接口? 抽象cL否可l承实体c?concrete class)?</p> <p> <font color="#0000cc">接口可以l承接口。抽象类可以实现(implements)接口Q抽象类是否可承实体类Q但前提是实体类必须有明的构造函数?<br /></font> <br /> <br />W二十三Q启动一个线E是用run()q是start()?</p> <p> <font color="#0000cc">启动一个线E是调用start()Ҏ(gu)QɾU程所代表的虚拟处理机处于可运行状态,q意味着它可以由JVM调度q执行。这q不意味着U程׃(x)立即q行。run()Ҏ(gu)实执行的内容?/font> <br /> <br />W二十四Q构造器Constructor是否可被override?</p> <p> <font color="#0000cc">构造器Constructor不能被承,因此不能重写OverridingQ但可以被重载Overloading?/font> <br /> <br />W二十五Q是否可以承Stringc?<br /><br />W二十六Q当一个线E进入一个对象的一个synchronizedҎ(gu)后,其它U程是否可进入此对象的其它方?<br /><br />W二十七Qtry {}里有一个return语句Q那么紧跟在q个try后的finally {}里的code?x)不会(x)被执行Q什么时候被执行Q在return前还是后?<br /><br />W二十八Q编E题: 用最有效率的Ҏ(gu)出2乘(sh)8{於?<br />有C背景的程序员特别喜欢问这U问题?br /><br />W二十九(ji)Q两个对象值相?x.equals(y) == true)Q但却可有不同的hash codeQ这句话对不?<br /><br />W三十,当一个对象被当作参数传递到一个方法后Q此Ҏ(gu)可改变这个对象的属性,q可q回变化后的l果Q那么这里到底是g递还是引用传?<br /><br />W三十一Qswtich是否能作用在byte上,是否能作用在long上,是否能作用在String?<br /><br />W三十二Q编E题: 写一个Singleton出来?br /></p> <img src ="http://www.aygfsteel.com/matthew2006/aggbug/55813.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/matthew2006/" target="_blank">matthew</a> 2006-06-29 20:08 <a href="http://www.aygfsteel.com/matthew2006/archive/2006/06/29/55813.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank">»</a>| <a href="http://" target="_blank">ij</a>| <a href="http://" target="_blank">ʳ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">䴨</a>| <a href="http://" target="_blank">«Ϫ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">麣</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ľ</a>| <a href="http://" target="_blank">۶</a>| <a href="http://" target="_blank">͸</a>| <a href="http://" target="_blank">ŷ</a>| <a href="http://" target="_blank">׿</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ҵ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ͭ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ǩ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">̩</a>| <a href="http://" target="_blank">Թ</a>| <a href="http://" target="_blank">¡</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ƽ</a>| <a href="http://" target="_blank">ʱ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">¡</a>| <a href="http://" target="_blank">̫</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">گ</a>| <a href="http://" target="_blank"></a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>