﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-Write Once,Run Anywhere!</title><link>http://www.blogjava.net/gongtao200118/</link><description>人生最遗憾的，莫过于，轻易的放弃了不该放弃的，固执的坚持了不该坚持的！</description><language>zh-cn</language><lastBuildDate>Sun, 03 May 2026 10:14:41 GMT</lastBuildDate><pubDate>Sun, 03 May 2026 10:14:41 GMT</pubDate><ttl>60</ttl><item><title>java中的方法和函数</title><link>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18839.html</link><dc:creator>Write Once,Run Anywhere!</dc:creator><author>Write Once,Run Anywhere!</author><pubDate>Tue, 08 Nov 2005 10:44:00 GMT</pubDate><guid>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18839.html</guid><wfw:comment>http://www.blogjava.net/gongtao200118/comments/18839.html</wfw:comment><comments>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18839.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/gongtao200118/comments/commentRss/18839.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gongtao200118/services/trackbacks/18839.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=0 width="95%" border=0>
<TBODY>
<TR>
<TD align=middle width="100%">
<H2><B>java中的方法和函数</B></H2></TD></TR>
<TR>
<TD width="100%"><FONT size=3>java中的方法和函数</FONT> 
<P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">1</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">、方法</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">(</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">例程</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">BoxDemo5.java) 
<P></SPAN></B></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>class Box { 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>double width; 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>double height; 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>double depth; 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">
<P><FONT size=3></FONT>&nbsp;</P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>double volume() { 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>return width * height * depth; 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>} 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">void setDim(double w</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">double h</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">double d) { 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>width = w; 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>height = h; 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>depth = d; 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>} 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>} 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>class BoxDemo5 { 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>public static void main(String args[]) { 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Box mybox1 = new Box();//*</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">以下几步等价于</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">oxDemo7.java</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">中的</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Box mybox1 = new Box(10</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">20</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">
<P><FONT size=3></FONT></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>15); 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>Box mybox2 = new Box(3</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">6</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">
<P><FONT size=3></FONT></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>9);*// 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3>
<ADDRESS w:st="on"><STREET w:st="on"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Box</SPAN></STREET><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> mybox2</SPAN></ADDRESS><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">= new Box(); 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>double vol; 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">mybox1.setDim(10</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">20</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">15); 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">mybox2.setDim(3</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">6</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">9); 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>vol = mybox1.volume(); 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>System.out.println("Volume is " + vol); 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>vol = mybox2.volume(); 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>System.out.println("Volume is " + vol); 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>} 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>} 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">
<P><FONT size=3></FONT>&nbsp;</P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">2</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">、函数</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">(</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">例程</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">BoxDemo7.java)</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">函数是用来初始化对象的</SPAN></B><B style="mso-bidi-font-weight: normal"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> 
<P></SPAN></B></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>class Box { 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>double width; 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>double height; 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>double depth; 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Box(double w</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">double h</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">double d) { 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>width = w; 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>height = h; 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>depth = d; 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>} 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>double volume() { 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>return width * height * depth; 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>} 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>} 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>class BoxDemo7 { 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>public static void main(String args[]) { 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Box mybox1 = new Box(10</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">20</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">15); 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Box mybox2 = new Box(3</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">6</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">9); 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>double vol; 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>vol = mybox1.volume(); 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>System.out.println("Volume is " + vol); 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>vol = mybox2.volume(); 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>System.out.println("Volume is " + vol); 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>} 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><FONT size=3>} 
<P></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">3</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">、</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">(1)</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">静态方法和静态变量（相当于一般编成语言中的全局函数</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">
<P><FONT size=3></FONT></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">和全局变量）</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">(2)</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">静态方法通过类名来调用</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">(</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">当然通过类对象来调用一样）的方</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">
<P><FONT size=3></FONT></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">法</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">
<P><FONT size=3></FONT>&nbsp;</P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">(3)</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">关于静态方法</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">(</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">通过类产生的对象</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">调用静态方法</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">,</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">调用非静态</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">
<P><FONT size=3></FONT></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">方法</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">(</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">通过类名或都是对象调用</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">都是可以的</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">,</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">但是</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">,</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">静态方法可以</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">
<P><FONT size=3></FONT></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">调用静态变量而不可以调用非静态变量</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">(</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">道理很简单，应为它是</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">
<P><FONT size=3></FONT></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">面向全局的，不可能只针对于某个类中的一般变量而使用，全局</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">
<P><FONT size=3></FONT></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">函数只能定义全局变量，否则肯定无法使用）</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">(4)</SPAN><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">静态方法常用于经常使用的东西（如计算两个变量的积等等</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">
<P><FONT size=3></FONT></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><FONT size=3><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，定义了这种静态方法后就不用再在各个使用的类中再去定义了</SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"> 
<P></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">
<P><FONT size=3></FONT></P></SPAN>
<P></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-pagination: widow-orphan"><SPAN style="COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial"><FONT size=3>）</FONT></SPAN><SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"></P></SPAN></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/gongtao200118/aggbug/18839.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gongtao200118/" target="_blank">Write Once,Run Anywhere!</a> 2005-11-08 18:44 <a href="http://www.blogjava.net/gongtao200118/archive/2005/11/08/18839.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java中一些多方法的东西总结</title><link>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18837.html</link><dc:creator>Write Once,Run Anywhere!</dc:creator><author>Write Once,Run Anywhere!</author><pubDate>Tue, 08 Nov 2005 10:40:00 GMT</pubDate><guid>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18837.html</guid><wfw:comment>http://www.blogjava.net/gongtao200118/comments/18837.html</wfw:comment><comments>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18837.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gongtao200118/comments/commentRss/18837.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gongtao200118/services/trackbacks/18837.html</trackback:ping><description><![CDATA[<A href="http://www.icqblog.com/more.asp?name=wsq&amp;id=544">java中一些多方法的东西总结</A>
<DIV class=date>&nbsp;</DIV>
<DIV class=blogOne>
<P>安装了jdk以后，要配置环境变量 <BR>配置环境变量 <BR>系统98:打开:C:\autoexec.bat文件 <BR>set path=c:\jdk1.4\bin <BR>set java_home=c:\jdk1.4 <BR>set classpath=.;c:\jdk1.4\lib\dt.jar;c:\jdk1.4\lib\tools.jar;（.;已经不能少，因为它代表当前路径) <BR>配置环境变量 <BR>系统2000或XP: <BR>我的电脑-&gt;属性-&gt;高级-&gt;环境变量 <BR>添加以下环境变量(假定你的java安装在c:\jdk1.4） <BR>java_home=c:\jdk1.4 <BR>classpath=.;c:\jdk1.4\lib\dt.jar;c:\jdk1.4\lib\tools.jar;（.;已经不能少，因为它代表当前路径) <BR>path = c:\jdk1.4\bin <BR>新开一个dos窗口，键入java和javac测试一下 <BR></P>
<P>1. this是指当前对象自己。 <BR>当在一个类中要明确指出使用对象自己的的变量或函数时就应该加上this引用。如下面这个例子中: <BR><BR>public class A { <BR><BR>String s = "Hello"; <BR><BR>public A(String s) { <BR>System.out.println("s = " + s); <BR>System.out.println("1 -&gt; this.s = " + this.s); <BR>this.s = s; <BR>System.out.println("2 -&gt; this.s = " + this.s); <BR>} <BR><BR>public static void main(String[] args) { <BR>new A("HelloWorld!"); <BR>} <BR>} <BR><BR>运行结果： <BR><BR>s = HelloWorld! <BR>1 -&gt; this.s = Hello <BR>2 -&gt; this.s = HelloWorld! <BR><BR>在这个例子中，构造函数A中，参数s与类A的变量s同名，这时如果直接对s进行操作则是对参数s进行操作。若要对类A的变量s进行操作就应该用this进行引用。运行结果的第一行就是直接对参数s进行打印结果；后面两行分别是对对象A的变量s进行操作前后的打印结果。 <BR><BR>2. 把this作为参数传递 <BR>当你要把自己作为参数传递给别的对象时，也可以用this。如： <BR><BR>public class A { <BR>public A() { <BR>new B(this).print(); <BR>} <BR><BR>public void print() { <BR>System.out.println("Hello from A!"); <BR>} <BR>} <BR><BR>public class B { <BR>A a; <BR>public B(A a) { <BR>this.a = a; <BR>} <BR><BR>public void print() { <BR>a.print(); <BR>System.out.println("Hello from B!"); <BR>} <BR>} <BR><BR>运行结果： <BR>Hello from A! <BR>Hello from B! <BR><BR>在这个例子中，对象A的构造函数中，用new B(this)把对象A自己作为参数传递给了对象B的构造函数。 <BR><BR>3. 注意匿名类和内部类中的中的this。 <BR>有时候，我们会用到一些内部类和匿名类。当在匿名类中用this时，这个this则指的是匿名类或内部类本身。这时如果我们要使用外部类的方法和变量的话，则应该加上外部类的类名。如下面这个例子： <BR><BR>public class A { <BR>int i = 1; <BR><BR>public A() { <BR>Thread thread = new Thread() { <BR>public void run() { <BR>for(;;) { <BR>A.this.run(); <BR>try { <BR>sleep(1000); <BR>} catch(InterruptedException ie) { <BR>} <BR>} <BR>} <BR>}; <BR>thread.start(); <BR>} <BR><BR>public void run() { <BR>System.out.println("i = " + i); <BR>i++; <BR>} <BR><BR>public static void main(String[] args) throws Exception { <BR>new A(); <BR>} <BR><BR>} <BR><BR>在上面这个例子中, thread 是一个匿名类对象，在它的定义中，它的 run 函数里用到了外部类的 run 函数。这时由于函数同名，直接调用就不行了。这时有两种办法，一种就是把外部的 run 函数换一个名字，但这种办法对于一个开发到中途的应用来说是不可取的。那么就可以用这个例子中的办法用外部类的类名加上 this 引用来说明要调用的是外部类的方法 run。 <BR></P>
<P>一、基础知识： <BR>1、super（参数）：调用基类中的某一个构造函数（应该为构造函数中的第一条语句）。 <BR>2、this（参数）：调用本类中另一种形成的构造函数（应该为构造函数中的第一条语句）； <BR>3、super:　它引用当前对象的直接父类中的成员（用来访问直接父类中被隐藏的父类中成员数据或函数，基类与派生类中有相同成员定义时）。 <BR>如：super.变量名 <BR>super.成员函数据名（实参） <BR>4、this：它代表当前对象名（在程序中易产生二义性之处，应使用this来指明当前对象；如果函数的形参与类中的成员数据同名，这时需用this来指明成员变量名）。 <BR>二、应用实例： <BR>class Point <BR>{ private int x,y; <BR>public Point(int x,int y) <BR>{ <BR>this.x=x; //this它代表当前对象名 <BR>this.y=y; <BR>} <BR>public void Draw() <BR>{ <BR>} <BR>public Point() <BR>{ <BR>this(0,0); //this（参数）调用本类中另一种形成的构造函数 <BR>} <BR>} <BR>class Circle extends Point <BR>{ <BR>private int radius; <BR>public circle(int x0,int y0, int r ) <BR>{ <BR>super(x0,y0); //super（参数）调用基类中的某一个构造函数 <BR>radius=r; <BR>} <BR>public void Draw() <BR>{ <BR>super.Draw(); //super它引用当前对象的直接父类中的成员 <BR>drawCircle(); <BR>} <BR>} <BR></P>
<P>Java 语言中的 return 语句 <BR><BR>众所周知，return 只能用在有返回类型的函数中，但是有返回值的函数一定要有return吗？return都可以用在函数的哪些地方呢？这是本文需要讨论的问题。 <BR><BR><BR><BR>-------------------------------------------------------------------------------- <BR><BR><BR>例一： <BR><BR>class test { <BR>public String test() { <BR>if(true){ <BR>return ""; <BR>} <BR>else{ <BR>return ""; <BR>} <BR>} <BR>} <BR><BR>上面这样即可通过编译，但是下面这两个例子却不能通过编译： <BR><BR>(一) <BR>class test { <BR>public String test() { <BR>if(true){ <BR>return ""; <BR>} <BR>} <BR>} <BR><BR><BR>(二) <BR>class test { <BR>public String test() { <BR>if(isTrue()){ <BR>return ""; <BR>} <BR>else if(!isTrue()){//两个if里的判断包括了所有的可能性,但是还是编译期error <BR>return ""; <BR>} <BR>} <BR>boolean isTrue(){ <BR>return true; <BR>} <BR>} <BR><BR>结论1： <BR>对于(一)，这是因为java编译器认定单独的if语句只在当一定条件满足情况下才执行，它认为if不会有任何情况下都能执行的能力。 <BR>对于(二)，这是因为java编译器对if else 语句能够全面囊括所有情况的能力只限定在的if...else(或if...else if...else)时，而不包括if...else if。 <BR><BR><BR><BR>-------------------------------------------------------------------------------- <BR><BR><BR>再看例二： <BR><BR>class test { <BR>public String test() { <BR>while(true){ <BR>return ""; <BR>} <BR>} <BR>} <BR>上面这样即可通过编译，但是下面这样不行： <BR><BR>class test { <BR>public String test() { <BR>while(isTrue()){ <BR>return ""; <BR>} <BR>} <BR>boolean isTrue(){ <BR>return true; <BR>} <BR>} <BR><BR>结论2： <BR>这是因为编译器认为while语句有在任何情况下都能执行的能力，但是只在入参为true的情况下有该能力。 <BR><BR><BR><BR>-------------------------------------------------------------------------------- <BR><BR><BR>再看例三： <BR><BR>public class test { <BR>String test() throws Exception{ <BR><BR>throw new Exception();//抛出异常后，跳出程序,程序中止 <BR>} <BR>} <BR>结论3： <BR>如果函数中创建了异常，并抛出，则该函数可以不返回值。</P>
<P>常常在网上看到有人询问：如何把 java 程序编译成 .exe 文件。通常回答只有两种，一种是说，制作一个可执行的 JAR 文件包，就可以像.chm 文档一样双击运行了；而另一种回答，则是使用 JET 来进行编译。但是 JET 是要用钱买的，而且，据说 JET 也不是能把所有的 Java 程序都编译成执行文件，性能也要打些折扣。所以，使用制作可执行 JAR 文件包的方法就是最佳选择了，何况它还能保持 Java 的跨平台特性。先来看看什么是 JAR 文件包： <BR><BR>1. JAR 文件包 <BR><BR>　　JAR 文件就是 Java Archive File，顾名思意，它的应用是与 Java 息息相关的，是 Java 的一种文档格式。JAR 文件非常类似 ZIP 文件??准确的说，它就是 ZIP 文件，所以叫它文件包。JAR 文件与 ZIP 文件唯一的区别就是在 JAR 文件的内容中，包含了一个 META-INF/MANIFEST.MF 文件，这个文件是在生成 JAR 文件的时候自动创建的。举个例子，如果我们具有如下目录结构的一些文件： <BR><BR>　　== <BR>　　`-- test <BR>　　　 `-- Test.class <BR><BR>　　把它压缩成 ZIP 文件 test.zip，则这个 ZIP 文件的内部目录结构为： <BR><BR>　　test.zp <BR>　　`-- test <BR>　　　 `-- Test.class <BR><BR>　　如果我们使用 JDK 的 jar 命令把它打成 JAR 文件包 test.jar，则这个 JAR 文件的内部目录结构为： <BR><BR>　　test.jar <BR>　　|-- META-INF <BR>　　|　 `-- MANIFEST.MF <BR>　　`-- test <BR>　　　　`--Test.class <BR><BR><BR>2. 创建可执行的 JAR 文件包 <BR><BR>　　制作一个可执行的 JAR 文件包来发布你的程序是 JAR 文件包最典型的用法。 <BR><BR>　　Java 程序是由若干个 .class 文件组成的。这些 .class 文件必须根据它们所属的包不同而分级分目录存放；运行前需要把所有用到的包的根目录指定给 CLASSPATH 环境变量或者 java 命令的 -cp 参数；运行时还要到控制台下去使用 java 命令来运行，如果需要直接双击运行必须写 Windows <BR>的批处理文件 (.bat) 或者 Linux 的 Shell 程序。因此，许多人说，Java 是一种方便开发者苦了用户的程序设计语言。 <BR><BR>　　其实不然，如果开发者能够制作一个可执行的 JAR 文件包交给用户，那么用户使用起来就需要方便了。在 Windows 下安装 JRE (Java Runtime Environment) 的时候，安装文件会将 .jar 文件映射给 javaw.exe 打开。那么，对于一个可执行的 JAR 文件包，用户只需要双击它就可以运行程序了，和阅读 .chm 文档一样方便 (.chm 文档默认是由 hh.exe 打开的)。那么，现在的关键，就是如何来创建这个可执行的 JAR 文件包。 <BR><BR>　　创建可执行的 JAR 文件包，需要使用带 cvfm 参数的 jar 命令，同样以上述 test 目录为例，命令如下： <BR><BR>　　jar cvfm test.jar manifest.mf test <BR><BR>　　这里 test.jar 和 manifest.mf 两个文件，分别是对应的参数 f 和 m，其重头戏在 manifest.mf。因为要创建可执行的 JAR 文件包，光靠指定一个 manifest.mf 文件是不够的，因为 MANIFEST 是 JAR 文件包的特征，可执行的 JAR 文件包和不可执行的 JAR 文件包都包含 MANIFEST。关键在于可执行 JAR 文件包的 MANIFEST，其内容包含了 Main-Class 一项。这在 MANIFEST 中书写格式如下： <BR><BR>　　Main-Class: 可执行主类全名(包含包名) <BR><BR>　　例如，假设上例中的 Test.class 是属于 test 包的，而且是可执行的类 (定义了 public static void main(String[]) 方法)，那么这个 manifest.mf 可以编辑如下： <BR><BR>　　Main-Class: test.Test &lt;回车&gt; <BR><BR>　　这个 manifest.mf 可以放在任何位置，也可以是其它的文件名，只需要有 Main-Class: test.Test 一行，且该行以一个回车符结束即可。创建了 manifest.mf 文件之后，我们的目录结构变为： <BR><BR>　　== <BR>　　|-- test <BR>　　|　 `-- Test.class <BR>　　`-- manifest.mf <BR><BR>　　这时候，需要到 test 目录的上级目录中去使用 jar 命令来创建 JAR 文件包。也就是在目录树中使用?=?表示的那个目录中，使用如下命令?? <BR><BR>　　jar cvfm test.jar manifest.mf test <BR><BR>　　之后在?=?目录中创建??test.jar，这个 test.jar 就是执行的 JAR 文件包。运行时只需要使用 java -jar test.jar 命令即可。 <BR><BR>　　需要注意的是，创建的 JAR 文件包中需要包含完整的、与 Java 程序的包结构对应的目录结构，就像上例一样。而 Main-Class 指定的类，也必须是完整的、包含包路径的类名，如上例的 test.Test；而且在没有打成 JAR 文件包之前可以使用 java &lt;类名&gt; 来运行这个类，即在上例中 java test.Test 是可以正确运行的 (当然要在 CLASSPATH 正确的情况下)。 <BR><BR><BR>3. jar 命令详解 <BR><BR>　　jar 是随 JDK 安装的，在 JDK 安装目录下的 bin 目录中，Windows 下文件名为 jar.exe，Linux 下文件名为 jar。它的运行需要用到 JDK 安装目录下 lib 目录中的 tools.jar 文件。不过我们除了安装 JDK 什么也不需要做，因为 SUM 已经帮我们做好了。我们甚至不需要将 tools.jar 放到 CLASSPATH 中。 <BR><BR>　　使用不带任何的 jar 命令我们可以看到 jar 命令的用法如下： <BR><BR>　　jar {ctxu}[vfm0M] [jar-文件] [manifest-文件] [-C 目录] 文件名 ... <BR><BR>　　其中 {ctxu} 是 jar 命令的子命令，每次 jar 命令只能包含 ctxu 中的一个，它们分别表示： <BR><BR>　　-c　创建新的 JAR 文件包 <BR>　　-t　列出 JAR 文件包的内容列表 <BR>　　-x　展开 JAR 文件包的指定文件或者所有文件 <BR>　　-u　更新已存在的 JAR 文件包 (添加文件到 JAR 文件包中) <BR><BR>　　[vfm0M] 中的选项可以任选，也可以不选，它们是 jar 命令的选项参数 <BR><BR>　　-v　生成详细报告并打印到标准输出 <BR>　　-f　指定 JAR 文件名，通常这个参数是必须的 <BR>　　-m　指定需要包含的 MANIFEST 清单文件 <BR>　　-0　只存储，不压缩，这样产生的 JAR 文件包会比不用该参数产生的体积大，但速度更快 <BR>　　-M　不产生所有项的清单（MANIFEST〕文件，此参数会忽略 -m 参数 <BR><BR>　　[jar-文件] 即需要生成、查看、更新或者解开的 JAR 文件包，它是 -f 参数的附属参数 <BR>　　[manifest-文件] 即 MANIFEST 清单文件，它是 -m 参数的附属参数 <BR><BR>　　[-C 目录] 表示转到指定目录下去执行这个 jar 命令的操作。它相当于先使用 cd 命令转该目录下再执行不带 -C 参数的 jar 命令，它只能在创建和更新 JAR 文件包的时候可用。 <BR>　　文件名 ... 指定一个文件/目录列表，这些文件/目录就是要添加到 JAR 文件包中的文件/目录。如果指定了目录，那么 jar 命令打包的时候会自动把该目录中的所有文件和子目录打入包中。 <BR><BR>　　下面举一些例子来说明 jar 命令的用法： <BR><BR>　　1) jar cf test.jar test <BR><BR>　　该命令没有执行过程的显示，执行结果是在当前目录生成了 test.jar 文件。如果当前目录已经存在 test.jar，那么该文件将被覆盖。 <BR><BR>　　2) jar cvf test.jar test <BR><BR>　　该命令与上例中的结果相同，但是由于 v 参数的作用，显示出了打包过程，如下： <BR><BR>　　标明清单(manifest) <BR>　　增加：test/(读入= 0) (写出= 0)(存储了 0%) <BR>　　增加：test/Test.class(读入= 7) (写出= 6)(压缩了 14%) <BR><BR>　　3) jar cvfM test.jar test <BR><BR>　　该命令与 2) 结果类似，但在生成的 test.jar 中没有包含 META-INF/MANIFEST 文件，打包过程的信息也略有差别： <BR><BR>　　增加：test/(读入= 0) (写出= 0)(存储了 0%) <BR>　　增加：test/Test.class(读入= 7) (写出= 6)(压缩了 14%) <BR><BR>　　4) jar cvfm test.jar manifest.mf test <BR><BR>　　运行结果与 2) 相似，显示信息也相同，只是生成 JAR 包中的 META-INF/MANIFEST 内容不同，是包含了 manifest.mf 的内容 <BR><BR>　　5) jar tf test.jar <BR><BR>　　在 test.jar 已经存在的情况下，可以查看 test.jar 中的内容，如对于 2) 和 3) 生成的 test.jar 分别应该此命令，结果如下； <BR><BR>　　对于 2) <BR><BR>　　META-INF/ <BR>　　META-INF/MANIFEST.MF <BR>　　test/ <BR>　　test/Test.class <BR><BR>　　对于 3) <BR><BR>　　test/ <BR>　　test/Test.class <BR><BR>　　6) jar tvf test.jar <BR><BR>　　除显示 5) 中显示的内容外，还包括包内文件的详细信息，如： <BR><BR>　　　　 0 Wed Jun 19 15:39:06 GMT 2002 META-INF/ <BR>　　　　86 Wed Jun 19 15:39:06 GMT 2002 META-INF/MANIFEST.MF <BR>　　　　 0 Wed Jun 19 15:33:04 GMT 2002 test/ <BR>　　　　 7 Wed Jun 19 15:33:04 GMT 2002 test/Test.class <BR><BR>　　7) jar xf test.jar <BR><BR>　　解开 test.jar 到当前目录，不显示任何信息，对于 2) 生成的 test.jar，解开后的目录结构如下： <BR><BR>　　== <BR>　　|-- META-INF <BR>　　|　 `-- MANIFEST <BR>　　`-- test <BR>　　　　`-- Test.class <BR><BR>　　8) jar xvf test.jar <BR><BR>　　运行结果与 7) 相同，对于解压过程有详细信息显示，如： <BR><BR>　　　创建：META-INF/ <BR>　　展开：META-INF/MANIFEST.MF <BR>　　　创建：test/ <BR>　　展开：test/Test.class <BR><BR>　　9) jar uf test.jar manifest.mf <BR><BR>　　在 test.jar 中添加了文件 manifest.mf，此使用 jar tf 来查看 test.jar 可以发现 test.jar 中比原来多了一个 manifest。这里顺便提一下，如果使用 -m <BR>参数并指定 manifest.mf 文件，那么 manifest.mf 是作为清单文件 MANIFEST 来使用的，它的内容会被添加到 MANIFEST 中；但是，如果作为一般文件添加到 JAR 文件包中，它跟一般文件无异。 <BR><BR>　　10) jar uvf test.jar manifest.mf <BR><BR>　　与 9) 结果相同，同时有详细信息显示，如： <BR><BR>　　增加：manifest.mf(读入= 17) (写出= 19)(压缩了 -11%) <BR><BR><BR>4. 关于 JAR 文件包的一些技巧 <BR><BR>　　1） 使用 unzip 来解压 JAR 文件 <BR><BR>　　在介绍 JAR 文件的时候就已经说过了，JAR 文件实际上就是 ZIP 文件，所以可以使用常见的一些解压 ZIP 文件的工具来解压 JAR 文件，如 Windows 下的 WinZip、WinRAR 等和 Linux 下的 unzip 等。使用 WinZip 和 WinRAR 等来解压是因为它们解压比较直观，方便。而使用 unzip，则是因为它解压时可以使用 -d 参数指定目标目录。 <BR><BR>　　在解压一个 JAR 文件的时候是不能使用 jar 的 -C 参数来指定解压的目标的，因为 -C 参数只在创建或者更新包的时候可用。那么需要将文件解压到某个指定目录下的时候就需要先将这具 JAR 文件拷贝到目标目录下，再进行解压，比较麻烦。如果使用 unzip，就不需要这么麻烦了，只需要指定一个 -d 参数即可。如： <BR><BR>　　unzip test.jar -d dest/ <BR><BR>　　2） 使用 WinZip 或者 WinRAR 等工具创建 JAR 文件 <BR><BR>　　上面提到 JAR 文件就是包含了 META-INF/MANIFEST 的 ZIP 文件，所以，只需要使用 WinZip、WinRAR 等工具创建所需要 ZIP 压缩包，再往这个 ZIP 压缩包中添加一个包含 MANIFEST 文件的 META-INF 目录即可。对于使用 jar 命令的 -m 参数指定清单文件的情况，只需要将这个 MANIFEST 按需要修改即可。 <BR><BR>　　3） 使用 jar 命令创建 ZIP 文件 <BR><BR>　　有些 Linux 下提供了 unzip 命令，但没有 zip 命令，所以需要可以对 ZIP 文件进行解压，即不能创建 ZIP 文件。如要创建一个 ZIP 文件，使用带 -M 参数的 jar 命令即可，因为 -M 参数表示制作 JAR 包的时候不添加 MANIFEST 清单，那么只需要在指定目标 JAR 文件的地方将 .jar 扩展名改为 .zip 扩展名，创建的就是一个不折不扣的 ZIP 文件了，如将上一节的第 3） 个例子略作改动： <BR><BR>　　jar cvfM test.zip test <BR></P>
<P>&nbsp;</P>
<P>检验配置的方法:</P>
<P>运行：java -version</P>
<P>path配置不对会提示找不到java命令，classpath配置不对不会出现信息提示。</P>
<P>static很容易理解的，与其它非static的变量和方法区别在于它是类的一部分而不是属于类的实例 </P>
<P>&nbsp;</P>
<P>&nbsp;</P></DIV>
<DIV class=blogBottom><A href="http://www.icqblog.com/showtb.asp?id=544" target=_blank></A>&nbsp;</DIV>
<DIV><BR></DIV>
<DIV class=sectionLinks>? 回复:java中一些多方法的东西总结<A name=64></A></DIV>
<DIV class=date>2004-11-21 23:00:32</DIV>
<DIV class=blogOne>//ReadMultiFile.Java <BR>import Java.io.*; <BR>import Java.util.*; <BR><BR>class ReadMultiFile <BR>{ <BR>public static void main(String args[]) <BR>{ <BR>//实例化FileFilter类 <BR>FileFilter fFilter = new FileFilter(“D:\Java2\Source”,”Java”); <BR>//创建顺序输入流 <BR>SequenceInputStream seqInput = new SequenceInputStream(fFilter); <BR>//创建输出文件对象 <BR>FileOutputStream fOutput = new FileOutputStream(“SourceSum”); <BR>//每次读取的字符 <BR>int bContent; <BR>//从文件输入流中读取内容 <BR>while((bContent = seqInput.read())!=-1) <BR>{ <BR>//写出到文件输出对象 <BR>fOutput.write(nContent); <BR>} <BR>//关闭顺序输入流 <BR>seqInput.close(); <BR>//关闭文件输出对象 <BR>fOutput.close(); <BR>} <BR>} <BR>class FileFilter implements Enumeration <BR>{ <BR>File directory; <BR>String extension; <BR>String strFileList[]; <BR>Filter filter; <BR>int nCounter; <BR>//构造方法 <BR>FileFilter(String strDirectoryName,String extension) <BR>{ <BR>this.extension = extension; <BR>//创建目录对象 <BR>directory = new File(strDirectoryName); <BR>if(directory.isDirectory()) <BR>{ <BR>//如果是目录，获取目录中所有文件 <BR>filter = new Filter(extension); <BR>strFileList = directory.list(filter); <BR>} <BR>else <BR>{ <BR>//如果不是目录，获取当前文件 <BR>strFileList = new String[1]; <BR>strFileList[0] = strDirectoryName; <BR>} <BR>nCounter = 0; <BR>} <BR>//判断枚举中十分还有元素的方法 <BR>public Boolean hasMoreElements() <BR>{ <BR>if(nCounter&lt;strFileList.length) <BR>{ <BR>return true; <BR>} <BR>else <BR>{ <BR>return false; <BR>} <BR>} <BR>//获取枚举中下一元素的方法 <BR>public Object nextElement() <BR>{ <BR>//如果还有元素 <BR>if( hasMoreElements()) <BR>{ <BR>nCounter++; <BR>//返回文件输入流对象 <BR>return new FileInputStream(strFileList[nCounter-1]); <BR>} <BR>else <BR>return null; <BR>} <BR>} <BR><BR><BR><BR><BR>//FilterWalker.Java <BR>import Java.io.*; <BR>import Java.util.*; <BR>class FilterWalker implements Observer <BR>{ <BR>String[] patterns; <BR>File dir; <BR>FilterWalker (String dirname, String[] patterns) <BR>{ <BR>dir = new File(dirname); <BR>this.patterns = patterns; <BR>// Start walking the file system. <BR>FileWalker fw = new FileWalker(); <BR>fw.addObserver(this); <BR>fw.walk(new File(dirname), false, new FileFilter()); <BR>} <BR>class FileFilter implements Java.io.FileFilter <BR>{ <BR>// Returns true if filename matches one of the patterns. <BR>public boolean accept(File file) <BR>{ <BR>if (file.isDirectory()) <BR>{ <BR>return true; <BR>} <BR>String s = file.getName(); <BR>if (patterns.length == 0) { <BR>return true; <BR>} else { <BR>for (int i=0; i&lt;patterns.length; i++) { <BR>if (s.endsWith(patterns[i])) { <BR>return true; <BR>} <BR>} <BR>} <BR>return false; <BR>} <BR>} <BR>// This method is called for each file that the file walker discovers. <BR>public void update(Observable o, Object arg) { <BR>System.out.println(arg); <BR>} <BR>public static void main(String[] args) { <BR>if (args.length &lt; 1) { <BR>System.err.println( <BR>"Usage: Java Main &lt;directory&gt; [&lt;pattern&gt;...]"); <BR>} else { <BR>// Retrieve patterns, if any. <BR>String[] patterns = new String[args.length-1]; <BR>System.arraycopy(args, 1, patterns, 0, patterns.length); <BR>new Main(args[0], patterns); <BR>} <BR>} <BR>} <BR>//FileWalker.Java <BR>import Java.io.*; <BR>import Java.util.*; <BR>import Java.util.zip.*; <BR>class FileWalker extends Observable <BR>{ <BR>void walk(File dir, boolean includeDirectories, FileFilter filter) <BR>{ <BR>if (dir.isDirectory()) { <BR>if (includeDirectories) { <BR>setChanged(); <BR>notifyObservers(dir); <BR>} <BR>File[] files = dir.listFiles(filter); <BR>if (files != null) { <BR>for (int i=0; i&lt;files.length; i++) { <BR>walk(files[i], includeDirectories, filter); <BR>} <BR>} <BR>} else { <BR>setChanged(); <BR>notifyObservers(dir); <BR>} <BR>} <BR>} <BR><BR><BR><BR>//DataIOTest.Java <BR>import Java.io.*; <BR>public class DataIOTest <BR>{ <BR>public static void main(String[] args) throws IOException <BR>{ <BR>//创建数据输出流 <BR>DataOutputStream out = new DataOutputStream(new <BR>FileOutputStream("content.txt")); <BR>//初始化输出数据 <BR>double[] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 }; <BR>int[] units = { 12, 8, 13, 29, 50 }; <BR>String[] descs = { <BR>"Java T-shirt", <BR>"Java Mug", <BR>"Duke Juggling Dolls", <BR>"Java Pin", <BR>"Java Key Chain" <BR>}; <BR>//数据输出 <BR>for (int i = 0; i &lt; prices.length; i ++) <BR>{ <BR>out.writeDouble(prices[i]); <BR>out.writeChar(´\t´); <BR>out.writeInt(units[i]); <BR>out.writeChar(´\t´); <BR>out.writeChars(descs[i]); <BR>out.writeChar(´\n´); <BR>} <BR>//关闭数据输出流 <BR>out.close(); <BR>//创建数据输入流 <BR>DataInputStream in = new DataInputStream( <BR>new FileInputStream("content.txt")); <BR><BR>double price; <BR>int unit; <BR>String desc; <BR>double total = 0.0; <BR>try <BR>{ <BR>//利用数据输入流读文件内容 <BR>while (true) <BR>{ <BR>price = in.readDouble(); <BR>in.readChar(); // throws out the tab <BR>unit = in.readInt(); <BR>in.readChar(); // throws out the tab <BR>desc = in.readLine(); <BR>System.out.println("You´ve ordered " + <BR>unit + " units of " + <BR>desc + " at $" + price); <BR>total = total + unit * price; <BR>} <BR>} <BR>//捕获异常 <BR>catch (EOFException e) <BR>{ <BR>e.printStackTrace(); <BR>} <BR>System.out.println("For a TOTAL of: $" + total); <BR>//关闭数据输入流 <BR>in.close(); <BR>} <BR>} <BR><BR><BR><BR>// DataIOException.Java <BR>import Java.io.*; <BR>class DataIOException <BR>{ <BR>public static void main(String args[]) <BR>{ <BR>//利用文件输入流创建数据输入流 <BR>DataInputStream dis = new DataInputStream( <BR>New FileInputStream(“DataIOException.Java”)); <BR>byte b; <BR>try <BR>{ <BR>//读文件的内容并打印出来 <BR>while(true) <BR>{ <BR>b = dis.readByte(); <BR>System.out.println((char)b); <BR>System.out.flush(); <BR>} <BR>} <BR>//捕获文件结束异常 <BR>catch(EOFException e1) <BR>{ <BR>System.out.println(e1); <BR>} <BR>//捕获文件不存在异常 <BR>catch(FileNotFoundException e2) <BR>{ <BR>System.out.println(e2); <BR>} <BR>//捕获文件输入输出异常 <BR>catch(IOException e3) <BR>{ <BR>System.out.println(e3); <BR>} <BR>//处理其他异常 <BR>catch(Throwable anything) <BR>{ <BR>System.out.println(anything); <BR>} <BR>} <BR>} <BR><BR><BR>//BufferedInputDemo.Java <BR>class BufferedInputDemo <BR>{ <BR>public static void main(String args[]) <BR>{ <BR>//创建与文件输入流对应的缓冲区输入流 <BR>BufferedInputStream bis = new BufferedInputStream( <BR>new FileInputStream(“BufferedInputDemo.Java”)); <BR>int b; <BR>try <BR>{ <BR>//从缓冲区输入流中读数据 <BR>while((b=bis.read())!=-1) <BR>{ <BR>System.out.println((char)b); <BR>} <BR>} <BR>catch(IOException e) <BR>{ <BR>e.printStackTrace(); <BR>} <BR>} <BR>} <BR><BR><BR><BR>//LineNumberDemo.Java <BR>class LineNumerDemo <BR>{ <BR>public static void main(String args[]) <BR>{ <BR>//定义数据输入流 <BR>DataInputStream dis; <BR>//定义文件输入流 <BR>FileInputStream fis; <BR>//定义缓冲区输入流 <BR>BufferedInputStream bis; <BR>//定义行号输入流 <BR>LineNumberInputStream lnis; <BR>String strLine; <BR><BR>Try <BR>{ <BR>//创建文件输入流对象，与实际文件相连 <BR>fis = new FileInputStream(“LineNumberDemo.Java”); <BR>//根据文件输入流对象创建缓冲区输入流 <BR>bis = new BufferedInputStream(fis); <BR>//根据缓冲区输入流对象创建行号输入流 <BR>lnis = new LineNumberStream(bis); <BR>//根据行号输入流创建数据输入流 <BR>dis = new DataInputStream(lnis); <BR>//从数据输入流中读数据 <BR>while((strLine=dis.readLine())!=null) <BR>{ <BR>//从行号输入流中取得行号 <BR>int nLineNumber = lis.getLineNumber(); <BR>//打印出行号和当前行内容 <BR>System.out.println(nLineNumer+”:”+strLine); <BR>} <BR>} <BR>catch(Exception e) <BR>{ <BR>e.printStackTrace(); <BR>} <BR>finally <BR>{ <BR>//关闭数据输入流 <BR>dis.close(); <BR>} <BR>} <BR>} <BR><BR><BR><BR>//FileCopy.Java <BR>//自定义异常 <BR>class FileCopyException extends IOException <BR>{ <BR>public FileCopyException(String msg) <BR>{ <BR>//调用父类的构造函数 <BR>super(msg); <BR>} <BR>} <BR>//FileCopy类 <BR>public class FileCopy <BR>{ <BR>public static void copy(String sourcename,String destname) <BR>throw IOException <BR>{ <BR>//创建源文件对象 <BR>File sourcefile = new File(sourcename); <BR>//创建目标文件对象 <BR>File destfile = new File(destname); <BR>//定义文件输入流 <BR>FileInputStream source= null; <BR>//定义文件输出流 <BR>FileOutputStream dest = null; <BR>byte[] buffer; <BR>int readbytes; <BR>try <BR>{ <BR>//判断文件十分存在、是否为普通文件 <BR>if(!sourcefile.exists() || !sourcefile.isFile()) <BR>throw new FileCopyException("No such file:"+sourcename+"\n"); <BR>//判断是否具有写权限 <BR>if(!sourcefile.canRead()) <BR>throw new FileCopyException(sourcename+"cann’t be read\n"); <BR>//判断目标文件存在 <BR>if(destfile.exists()) <BR>{ <BR>//目标文件是普通文件 <BR>if(destfile.isFile()) <BR>{ <BR>//定义数据输入流 <BR>DataInputStream in = new DataInputStream(System.in); <BR>String response; <BR>if(!destfile.canWrite())throw new <BR>FileCopyException(destname+"does not can write\n"); <BR>System.out.println("Overwrite (Yes/No) ?"); <BR>System.out.flush(); <BR>//读取输入内容 <BR>response = System.in.readline(); <BR>} <BR>else <BR>{ <BR>System.out.println(“不能对目录进行读写”); <BR>} <BR>} <BR>else <BR>{ <BR>System.out.println(“指定的文件不存在”); <BR>} <BR>//创建文件输入对象 <BR>source = new FileInputStream(sourcefile); <BR>//创建文件输出对象 <BR>destination = new FileOutputStream(destfile); <BR>buffer = new byte[1024]; <BR>//文件输出 <BR>for(;;) <BR>{ <BR>readbytes = source.read(buffer); <BR>if(readbytes==-1)break; <BR>destination.write(buffer,0,readbytes); <BR>} <BR>} <BR>finally <BR>{ <BR>if(source!=null) <BR>{ <BR>try <BR>{ <BR>source.close(); <BR>} <BR>catch(IOException e){}; <BR>} <BR>if(destination!=null) <BR>{ <BR>try <BR>{ <BR>destination.close(); <BR>} <BR>catch(IOException e){}; <BR>} <BR>} <BR>} <BR>public static void main(String args[]) <BR>{ <BR>if(args.length!=2) <BR>System.out.println("Java FileCopy &lt;SourceFile&gt; &lt;DestFile&gt;"); <BR>else <BR>{ <BR>try <BR>{ <BR>copy(args[0],args[1]); <BR>} <BR>catch(IOException e) <BR>{ <BR>System.out.println(e.getMessage()); <BR>} <BR>} <BR>} <BR><BR>private static File parent(File f) <BR>{ <BR>String dirname = f.getParent(); <BR>if(f.isAbsolute()) <BR>return new File(File.seperator); <BR>else <BR>return new File(System.getProperty("user.dir")); <BR>} </DIV>
<DIV class=blogBottom><A href="http://www.icqblog.com/more.asp?name=wsq&amp;id=544#top"></A>&nbsp;</DIV>
<DIV><BR></DIV>
<DIV class=sectionLinks>? 回复:java中一些多方法的东西总结<A name=63></A></DIV>
<DIV class=date>2004-11-21 22:59:36</DIV>
<DIV class=blogOne>//InOutDemo.Java <BR>class InOutDemo <BR>{ <BR>public static void main(String args[]) throws Exception <BR>{ <BR>//定义字节数组 <BR>byte buffer[] = new byte[30]; <BR>//将从键盘输入的字节序列存储到字节缓冲区中 <BR>System.in.read(buffer); <BR>//生成String对象 <BR>String strBuffer = new String(buffer); <BR>//在标准输出中输出生成的String对象 <BR>System.out.println(strBuffer); <BR>} <BR>} <BR><BR><BR><BR>//FileFilterDemo.Java <BR>import Java.io.*; <BR>public class FileFilterDemo <BR>{ <BR>//创建文件对象 <BR>File dir = new File(“D:\JavaSource”); <BR>//创建文件类型过滤器 <BR>Filter filter = new Filter(“Java”); <BR><BR>//取得文件名字符串数组 <BR>String fileList[] = dir.list(filter); <BR>for(int I=0;I&lt;fileList.length;I++) <BR>{ <BR>//获取文件对象 <BR>File tmpFile = new File(fileList[I]); <BR>//取得文件属性 <BR>if( tmpFile.isFile() ) <BR>System.out.println(“文件”+tmpfile); <BR>else <BR>System.out.println(“目录”+tmpfile); <BR>} <BR>} <BR>//定义文件过滤器 <BR>class Filter implements FilenameFilter <BR>{ <BR>//扩展名 <BR>String extension; <BR>//构造方法 <BR>Filter(String extension) <BR>{ <BR>this.extension = extension; <BR>} <BR>//测试文件的扩展名是否为extension <BR>public boolean accept(File directory,String filename) <BR>{ <BR>return filename.endsWith(“.”+extension); <BR>} <BR>} <BR><BR><BR><BR><BR>//LastModified.Java <BR>import Java.io.*; <BR>class LastModified <BR>{ <BR>public static void main(String[] args) <BR>{ <BR>try <BR>{ <BR>File temp = File.createTempFile("jcl", ".out"); <BR>// Make sure it gets deleted when we´re done <BR>temp.deleteOnExit(); <BR>// Print out file name and its last modified time <BR>long mod = temp.lastModified(); <BR>System.out.println(temp + ":" + mod); <BR>// Introduced some delay <BR>try <BR>{ <BR>Thread.sleep(3000); <BR>} <BR>catch (InterruptedException ie) <BR>{ <BR>}; <BR>// Write something out to file <BR>FileWriter fout = new FileWriter(temp); <BR>fout.write("hello"); <BR>fout.close(); <BR>System.out.println(temp + ":" + temp.lastModified()); <BR>// Change modified date back to original <BR>if (temp.setLastModified(mod)) <BR>{ <BR>System.out.println(temp + ":" + temp.lastModified()); <BR>} <BR>else <BR>{ <BR>System.out.println("modification time unchanged"); <BR>} <BR>// <BR>} <BR>catch (IOException e) <BR>{ <BR>e.printStackTrace(); <BR>} <BR>} <BR>} <BR><BR><BR><BR><BR>//FileAttributeDemo.Java <BR>class FileAttributeDemo <BR>{ <BR>//main方法 <BR>public static void main(String args[]) <BR>{ <BR>FileAttributeDemo demo = new FileAttributeDemo(); <BR>} <BR>//类构造方法 <BR>public FileAttributeDemo() <BR>{ <BR>//路径分隔符 <BR>System.out.println(“Path Separator”+File.pathSeparator); <BR>//路径分隔字符 <BR>System.out.println(“Path Separator character”+File.pathSeparatorChar); <BR>//文件分隔符 <BR>System.out.println(“Separator”+File.separator); <BR>//文件分隔字符 <BR>System.out.println(“Separator character”+File.separatorChar); <BR>//创建文件对象 <BR>File flFile = new File(“D:\JavaSource\FileDemo.Java”); <BR>//文件全路径名称 <BR>System.out.println(f); <BR>//读属性 <BR>System.out.println(f.canRead()); <BR>//写属性 <BR>System.out.println(f.canWrite()); <BR>//文件长度 <BR>System.out.println(f.length()); <BR>//测试是否为普通文件 <BR>System.out.println(f.isFile()); <BR>//测试是否为目录 <BR>System.out.println(f.isDirectory()); <BR>//取得文件最后修改时间 <BR>System.out.println(f.lastModified()); <BR>//取得文件名 <BR>System.out.println(f.getName()); <BR>//取得文件所在路径 <BR>System.out.println(f.getPath()); <BR>//判断文件是否存在 <BR>System.out.println(f.exists()); <BR>} <BR>} <BR><BR><BR><BR><BR>//ReafFromFile.Java <BR>import Java.io.*; <BR>class ReadFromFile <BR>{ <BR>public static void main(String args[]) <BR>{ <BR>System.out.println(“Please enter a directory that the file located in:”); <BR>//构造待读取文件的目录 <BR>StringBuffer stfDir = new StringBuffer(); <BR>//从键盘获取输入字符，存储进入字符缓冲区 <BR>While((char ch = (char)System.in.read())!=’\n’) <BR>{ <BR>stfDir.appendChar(ch); <BR>} <BR>//创建目录文件对象 <BR>File dir = new File(stfDir.toString()); <BR><BR>System.out.println(“Please enter a filename that want to read:”); <BR>//获取待读取的文件名 <BR>StringBuffer stfFilename = new StringBuffer(); <BR>//从键盘获取输入字符，存储进入字符缓冲区 <BR>While((char ch = (char)System.in.read())!=’\n’) <BR>{ <BR>stfFilename.appendChar(ch); <BR>} <BR>//创建文件对象 <BR>File readFrom = new File(dir,stfFilename.toString()); <BR><BR>//判断文件是否为目录、是否具有写权限、读权限 <BR>if(readFrom.isFile() &amp;&amp; reafFrom.canWrite() &amp;&amp; reafFrom.canRead()) <BR>{ <BR>//创建RandomAccessFile对象 <BR>RandomAccessFile rafFile = <BR>new RandomAccessFile(readFrom,”rw”); <BR>//如果未读到文件尾，则继续读取 <BR>while(rafFile.getFilePointer()&lt;rafFile.length()) <BR>System.out.println(file.readLine()); <BR>//文件关闭 <BR>rafFile.close(); <BR>} <BR>else <BR>System.out.println(“File cann’t be read!”); <BR>} <BR>} <BR><BR><BR><BR><BR>//WriteToFile.Java <BR>import Java.io.*; <BR>class WriteToFile <BR>{ <BR>public static void main(String args[]) <BR>{ <BR>System.out.println(“Please enter a directory that the file located in:”); <BR>//构造待读取文件的目录 <BR>StringBuffer stfDir = new StringBuffer(); <BR>//从键盘获取输入字符，存储进入字符缓冲区 <BR>While((char ch = (char)System.in.read())!=’\n’) <BR>{ <BR>stfDir.appendChar(ch); <BR>} <BR>//创建目录文件对象 <BR>File dir = new File(stfDir.toString()); <BR><BR>System.out.println(“Please enter a filename that want to read:”); <BR>//获取待读取的文件名 <BR>StringBuffer stfFilename = new StringBuffer(); <BR>//从键盘获取输入字符，存储进入字符缓冲区 <BR>While((char ch = (char)System.in.read())!=’\n’) <BR>{ <BR>stfFilename.appendChar(ch); <BR>} <BR>//创建文件对象 <BR>File readFrom = new File(dir,stfFilename.toString()); <BR><BR>//判断文件是否为目录、是否具有写权限、读权限 <BR>if(readFrom.isFile() &amp;&amp; reafFrom.canWrite() &amp;&amp; reafFrom.canRead()) <BR>{ <BR>//创建RandomAccessFile对象 <BR>RandomAccessFile rafFile = <BR>new RandomAccessFile(readFrom,”rw”); <BR>//如果未读到文件尾，则继续读取 <BR>int ch; <BR>StringBuffer stfContent; <BR>while(ch!=-1) <BR>{ <BR>//字符缓冲区清空 <BR>stfContent.setLength(0); <BR>//接收键盘输入、构造字符缓冲区 <BR>while((ch=System.in.read())!=-1) <BR>stfContent.appendChar(ch); <BR>//附加Dos格式行结束标志 <BR>stfContent.append(“\r\n”); <BR>//将字符缓冲区的内容写出 <BR>rafFile.writeBytes(stfContent.toString()); <BR>} <BR>//文件关闭 <BR>rafFile.close(); <BR>} <BR>} <BR>else <BR>System.out.println(“File cann’t be write!”); <BR>} <BR>} <BR><BR><BR><BR><BR>//SetFileLength.Java <BR>import Java.io.*; <BR>class SetFileLength.Java <BR>{ <BR>public static void main(String[] args) <BR>{ <BR>if (args.length != 2) <BR>{ <BR>System.err.println( <BR>"usage: Java Main &lt;new filename&gt; &lt;size in bytes&gt;"); <BR>System.exit(-1); <BR>} <BR>long size = 0; <BR>try <BR>{ <BR>size = Long.parseLong(args[1]); <BR>} <BR>catch (NumberFormatException e) <BR>{ <BR>System.err.println( <BR>"usage: Java Main &lt;new filename&gt; &lt;size in bytes&gt;"); <BR>System.exit(-1); <BR>} <BR><BR>try <BR>{ <BR>RandomAccessFile raf = new RandomAccessFile(args[0], "rw"); <BR>raf.setLength(size); // extend file to be specified size <BR>raf.close(); <BR>} catch (IOException e) { <BR>e.printStackTrace(); <BR>} <BR>} <BR>} <BR><BR><BR><BR><BR>//FileIODemo.Java <BR>import Java.io.* <BR>class FileIODemo <BR>{ <BR>//main方法 <BR>public static void main(String args[]) <BR>{ <BR>FileIODemo aFileIODemo = new FileIODemo(); <BR>} <BR>//构造方法 <BR>public FileIODemo <BR>{ <BR>try <BR>{ <BR>//利用系统输入设备作为文件输入流 <BR>FileInputStream fin = new FileInputStream(System.in); <BR>//创建输出文件input.txt <BR>FileOutputStream fout = new FileOutputStream( new File(“input.txt”)); <BR>int nKeyIn; <BR><BR>for(int n=0;n&lt;10;n++) <BR>{ <BR>//从标准输入设备读取10个字符输入 <BR>nKeyIn = fin.read(); <BR>//向文件输出流中写出输入的字符 <BR>fout.write(data); <BR>} <BR>//关闭输出流 <BR>fout.close(); <BR><BR>//创建文件输入流为文件input.txt <BR>FileInputStream fin = new FileInputStream(new File(“input.txt”)); <BR>//文件输出流为系统标准输出 <BR>FileOutputStream fout = new FileOutputStream(System.out); <BR>while(fin.available()&gt;0) <BR>{ <BR>//从文件中读字符 <BR>data = fin.read(); <BR>//写出文件输出流 <BR>fout.write(data); <BR>} <BR>//关闭输入流 <BR>fin.close(); <BR>//关闭输出流 <BR><BR>fout.close(); <BR>} <BR>//捕获文件异常 <BR>catch(FileNotFoundException e) <BR>{ <BR>e.printStackTrace(); <BR>} <BR>//捕获输入输出异常 <BR>catch(IOException exp) <BR>{ <BR>exp.printStackTrace(); <BR>} <BR>} <BR>} <BR><BR><BR><BR><BR>//PipedIODemo.Java <BR>import Java.io.*; <BR>class PipedIODemo <BR>{ <BR>public static void main(String args[]) <BR>{ <BR>try <BR>{ <BR>//创建管道输入流 <BR>PipedInputStream pin = new PipedInputStream(); <BR>//创建管道输出流 <BR>PipedOutputStream pout = new PipedOutputStream(); <BR>//输入与输出流相连 <BR>pout.connect( pin); <BR>//启动管道输入线程 <BR>new PipeSender(pout,”sendString”).start(); <BR>//启动管道输出线程 <BR>new PipeReciver(pin,”receiveString”).start(); <BR>} <BR>catch(IOException e) <BR>{ <BR>e.printStackTrace(); <BR>} <BR>} <BR>} <BR>//管道输入类 <BR>class PipeSender extends Thread <BR>{ <BR>PipedOutputStream pout; <BR>File fFile; <BR>//构造函数 <BR>PipeSender(PipedOutputStream out,String file) <BR>{ <BR>fFile = file; <BR>pout = out; <BR>} <BR>public void run() <BR>{ <BR>//创建输入文件对象 <BR>FileInputStream fin = new FileInputStream(fFile); <BR>int n; <BR>try <BR>{ <BR>//读文件 <BR>while((n=fin.read())!=-1) <BR>{ <BR>//向管道中写入 <BR>pout.write(n); <BR>} <BR>pout.close(); <BR>} <BR>catch(IOException e) <BR>{ <BR>e.printStackTrace(); <BR>} <BR>} <BR>} <BR>//管道接收类 <BR>class PipeReciver extends Thread <BR>{ <BR>PipedInputStream pin; <BR>File fFile; <BR>//构造方法 <BR>PipeReciver (PipedInputStream in,String file) <BR>{ <BR>fFile = file; <BR>pin = in; <BR>} <BR>public void run() <BR>{ <BR>//输出文件对象 <BR>FileOutputStream fout = new FileOutputStream(fFile); <BR>int n; <BR>try <BR>{ <BR>//从管道中读数据 <BR>while((n=pin.read())!=-1) <BR>{ <BR>//向文件输出对象中写数据 <BR>fout.write(n); <BR>} <BR>} <BR>catch(IOException e) <BR>{ <BR>e.printStackTrace(); <BR>} <BR>} <BR>}</DIV>
<DIV class=blogBottom><A href="http://www.icqblog.com/more.asp?name=wsq&amp;id=544#top"></A>&nbsp;</DIV>
<DIV><BR></DIV>
<DIV class=sectionLinks>? 回复:java中一些多方法的东西总结<A name=62></A></DIV>
<DIV class=date>2004-11-21 22:58:39</DIV>
<DIV class=blogOne>//InOutDemo.Java <BR>class InOutDemo <BR>{ <BR>public static void main(String args[]) throws Exception <BR>{ <BR>//定义字节数组 <BR>byte buffer[] = new byte[30]; <BR>//将从键盘输入的字节序列存储到字节缓冲区中 <BR>System.in.read(buffer); <BR>//生成String对象 <BR>String strBuffer = new String(buffer); <BR>//在标准输出中输出生成的String对象 <BR>System.out.println(strBuffer); <BR>} <BR>}</DIV>
<DIV><BR></DIV>
<DIV class=sectionLinks>? 回复:java中一些多方法的东西总结<A name=61></A></DIV>
<DIV class=date>2004-11-21 22:58:17</DIV>
<DIV class=blogOne>//ExceptionDemo.java <BR>class ExceptionDemo <BR>{ <BR>public static void main(String args[]) <BR>{ <BR>for(int n=0;n&lt;4;n++) <BR>{ <BR>try <BR>{ <BR>switch(n) <BR>{ <BR>case 0: <BR>char c = “123456”.charAt(100); <BR>break; <BR>case 1: <BR>int[] a = null; <BR>a[0] = 10; <BR>break; <BR>case 2: <BR>int[] b = new int[10]; <BR>b[15] = 15; <BR>break; <BR>case 3: <BR>int nNull = 0; <BR>int c = 10/nNull; <BR>break; <BR>} <BR>} <BR>catch(Exception e) <BR>{ <BR>System.out.println(e.toString()); <BR>} <BR>} <BR>} <BR>} <BR><BR><BR><BR><BR>// ExecutionOrder.java <BR>public class ExecutionOrder <BR>{ <BR>public static void main(String args[]) <BR>{ <BR>System.out.println("1"); <BR>try <BR>{ <BR>System.out.println("2"); <BR>if( true) <BR>//抛出用户定义的异常 <BR>throw new InstanceException(); <BR>System.out.println("3"); <BR>} <BR>//捕获该异常 <BR>catch(InstanceException e) <BR>{ <BR>System.out.println("4"); <BR>} <BR>System.out.println("5"); <BR>} <BR>} <BR>class InstanceException extends Exception <BR>{ <BR>public InstanceException() <BR>{ <BR>super(); <BR>} <BR>} <BR><BR><BR><BR><BR>//Demo.java <BR>import java.io.*; <BR>class IOExceptionDemo <BR>{ <BR>public IOExceptionDemo() <BR>{ <BR>try <BR>{ <BR>int a = 0; <BR>int b = 10; <BR>int c = b/a; <BR>} <BR>catch(ArithmeticException e) <BR>{ <BR>System.out.println("arithmetic exception"); <BR>} <BR>finally <BR>{ <BR>System.out.println("Entering finally statement. This must be executed"); <BR>} <BR>} <BR>} <BR>public class Demo <BR>{ <BR>public static void main(String args[]) <BR>{ <BR>IOExceptionDemo aIOExceptionDemo = new IOExceptionDemo(); <BR>} <BR>} <BR><BR><BR><BR><BR>//UserExceptionDemo.java <BR>class UserExceptionDemo <BR>{ <BR>//抛出异常的方法 <BR>void doSomeThing() <BR>{ <BR>int a = 0; <BR>int b = 10; <BR>//产生异常的条件判断 <BR>if(a !=0) <BR>{ <BR>System.out.println(“Normal”); <BR>} <BR>else <BR>{ <BR>//抛出异常 <BR>throw new UserDefineException(); <BR>} <BR>} <BR>public static void main(String args[]) <BR>{ <BR>//实例化 <BR>UserExceptionDemo aUserExceptionDemo = new UserExceptionDemo(); <BR>//调用类实例的方法 <BR>aUserExceptionDemo.doSomeThing(); <BR>} <BR>} <BR>//用户定义的异常，由Exception类派生 <BR>class UserDefineException extends ArithmeticException <BR>{ <BR>//Exception message <BR>System.out.println(“Exception occured”); <BR>} <BR><BR><BR><BR>// ListOfNumbersDeclared.java <BR>import java.io.*; <BR>import java.util.Vector; <BR><BR>class ListOfNumbers <BR>{ <BR>private Vector victor; <BR>private static final int size = 10; <BR><BR>//构造方法 <BR>public ListOfNumbers () <BR>{ <BR>//创建向量类 <BR>victor = new Vector(size); <BR>//向向量中增加元素 <BR>for (int i = 0; i &lt; size; i++) <BR>victor.addElement(new Integer(i)); <BR>} <BR>//成员方法，抛出两种类型的异常 <BR>public void writeList() throws IOException, ArrayIndexOutOfBoundsException <BR>{ <BR>//文件IO处理 <BR>PrintStream out = new PrintStream( <BR>new FileOutputStream("OutFile.txt")); <BR>//取得向量元素 <BR>for (int i = 0; i &lt; size; i++) <BR>out.println("Value at: " + i + " = " + victor.elementAt(i)); <BR>//关闭输出流 <BR>out.close(); <BR>} <BR>} <BR><BR>public class ListOfNumbersDeclared <BR>{ <BR>public static void main(String[] args) <BR>{ <BR>//实例化对象 <BR>ListOfNumbers list = new ListOfNumbers(); <BR>try{ <BR>//调用方法 <BR>list.writeList(); <BR>} <BR>catch( Exception e) <BR>{ <BR>//打印出异常的栈跟踪 <BR>e.printStackTrace(); <BR>} <BR>} <BR>} <BR></DIV>
<DIV class=blogBottom><A href="http://www.icqblog.com/more.asp?name=wsq&amp;id=544#top"></A>&nbsp;</DIV>
<DIV><BR></DIV>
<DIV class=sectionLinks>? 回复:java中一些多方法的东西总结<A name=60></A></DIV>
<DIV class=date>2004-11-21 22:57:47</DIV>
<DIV class=blogOne>1：类的基本概念 <BR>　　Java程序的基本单位是类，类是对象的实例，或者说对象是类定义的的数据类型的变量。你建立类之后，就可用它来建立许多你需要的对象。Java把每一个可执行的成分都变成类。 <BR>　　类的定义形式如下： <BR>　　class classname extends superclassname <BR>　　{ <BR>　　　　..... <BR><BR>　　} <BR>　　这 里，classname和superclassname是合法的标识符。关键词extends用来表明classname是superclassname派生的子类。有一个类叫做Object，它是所有Java类的根。如果你想定义Object的直接子类，你可以省略extends子句，编译器会自动包含它。下面是一个简单的类的定义。 <BR>　　在类定义的开始与结束处必须使用花括号。你也许想建立一个矩形类，那么可以用如下代码： <BR>　　public class Rectangle <BR>　　{ <BR>　　　　...... <BR><BR>　　} <BR><BR>2：类的基本组成 <BR>　　一个类中通常都包含数据与函数两种类型的元素，我们一般把它叫作属性和成员函数，在很多时候我们也把成员函数称为方法(method)。将数据与代码通过类紧密结合在一起，就形成了现在非常流行的封装的概念。自然，类的定义也要包括以上两个部分。 <BR><BR>class &lt;classname&gt; <BR><BR>&lt;member data declarations&gt; <BR>&lt;member function declarations&gt; <BR><BR>3：类的实例创建 <BR>　　矩形类Rectangle中，也许你想把矩形的相关信息写入类，如：width,height，当然你还可以写入其它信息，但或许长和宽对简单的矩形来说已足够了。现在，类的定义如下所示： <BR>　　public class Retangle <BR>　　{ <BR>　　int width,height; <BR>　　} <BR>　　当你创建了自己的类之后，通常需要使用它来完成某种工作。你可以通过定义类的实例－－对象来实现这种需求。 <BR>　　对象是通过new来创建，实现成员函数如下：Rectangle myrect=new Rectangle，当然，此时对象myrect并没有做任何什么事；它只保存了矩形的长和宽的信息。有了对象以后，我们怎样使用对象内部的数据呢？下面是几个例子： <BR>myrect.width=10; <BR>myrect.height=20; <BR>　　类的成员函数也是用“.”运算符来被引用的。 <BR></DIV>
<DIV class=blogBottom>By <B>wsq </B>| 个人主页 | <A href="http://www.icqblog.com/more.asp?name=wsq&amp;id=544&amp;commentid=60#comment">引用</A> | <A href="http://www.icqblog.com/more.asp?name=wsq&amp;id=544#top">返回</A></DIV>
<DIV><BR></DIV>
<DIV class=sectionLinks>? 回复:java中一些多方法的东西总结<A name=59></A></DIV>
<DIV class=date>2004-11-21 22:57:22</DIV>
<DIV class=blogOne>１.String类和StringBuffer类 <BR><BR>它们都是处理字符串的类,但是它们有一个最大的区别,那就是,String对象是存储你不能改动的文本字符 <BR>串,相反,如果你希望改动,则应使用StringBuffer类作为替换. <BR>eg1: <BR>...... <BR>//omit some code <BR>String s1="You are hired!"; <BR>System.out.println(s1.replace(′h′,′f′));//用f把字串中的h替换了 <BR>System.out.println(s1); <BR>...... <BR>//omit some code <BR>运行结果: <BR>You are fired! <BR>You are hired! <BR>结果分析: <BR>从结果,明显可知,s1的值并没有被改变,而第一行结果只是屏幕内容的替换. <BR>eg2: <BR>...... <BR>//omit some code <BR>StringBuffer s2=new StringBuffer("Hello from Java!"); <BR>s2.replace(6,10,"to"); <BR>System.out.println(s2); <BR>...... <BR>//omit some code <BR>运行结果: <BR>Hello to Java! <BR>结果分析: <BR>显然,s2的值已改变. <BR><BR>２.位逻辑与条件逻辑 <BR><BR>首先声明, 为了与位逻辑更好区分开来,我把通常所说的逻辑取了个别名叫做条件逻辑. <BR>它们都有各自的操作符,位逻辑操作符有:&amp;(与运算),^(异或运算),|(或运算);条件逻辑操作符有:&amp;&amp;(并 <BR>且),||(或者). <BR>位逻辑运算通常是针对两个数而言,实行位操作;而条件逻辑运算是针对两个条件表达式而言,实行条件操 <BR>作.其实,位逻辑操作符一样可以实现条件操作,但是此时有一个重要的区别:用位操作符时,不管操作符两边的 <BR>条件表达式成不成立,它都要通通进行运算判断,而条件逻辑操作符不一样了,如果通过左侧的操作数就可以进 <BR>行它们需要的判断,那么它就不会再计算右侧的操作数了,这种情况叫短路.废话少说!且看下例. <BR>eg1: <BR>...... <BR>//omit some code <BR>double value=0; <BR>if(value!=0 &amp;&amp; 1/value&lt;1000){ <BR>System.out.println("The value is not too small."); <BR>} <BR>else{ <BR>System.out.println("The value is too small."); <BR>} <BR>...... <BR>//omit some code <BR>运行结果: <BR>The value is too small. <BR>结果分析: <BR>照理说应会出现除数为0的错误,但是我刚才说了,由于条件逻辑操作符是短路操作符,显然,value!=0不 <BR>成立,立即就可作出判断应执行else后的语句,所以它就不再会运算判断1/value&lt;1000了.如果不懂请再看一 <BR>例: <BR>eg2: <BR>...... <BR>//omit some code <BR>double int1=0,int2=1,int3=1; <BR>if(int1!=0 &amp; (int2=2)==1){} <BR>System.out.println("int2="+int2); <BR>if(int1!=0 &amp;&amp; (int3=2)==1){} <BR>System.out.println("int3="+int3); <BR>...... <BR>//omit some code <BR>运行结果: <BR>int2=2.0 <BR>int3=1.0 <BR>结果分析: <BR>我想不用我分析了,你应该懂了吧. <BR><BR>３.实例变量与类变量 <BR><BR>可以通过两种方法在类中存储数据───作为实例变量和类变量.实例变量是特定于对象的,如果你有两个对 <BR>象(即一个类的两个实例),每一个对象中的实例变量独立于另一个对象中的实例变量的;另一方面,两个对象的 <BR>类变量均指向相同的数据,并因此面保存相同的值,换句话说,类变量被类中的所有对象共享.差点忘了,它们在 <BR>形式上的区别,类变量在声明时比实例变量多一个static. <BR>eg: <BR>class data <BR>{ <BR>public int intdata=0;//显然,intdata在这儿是实例变量 <BR>} <BR>public class exam <BR>{ <BR>public static void main(String[] args) <BR>{ <BR>data a,b; <BR>a=new data(); <BR>b=new data(); <BR>a.intdata=1; <BR>System.out.println("b.indata="+b.intdata); <BR>} <BR>} <BR>运行结果: <BR>b.intdata=0 <BR>结果分析: <BR>可以看出,a.intdata的值虽然变了,但并没有影响b.intdata.但是如果在data类中声明intdata时,在其前 <BR>面加上static就变成类变量了(即:public static int intdata=0;),则此时运行结果会变为: <BR>b.intdata=1 <BR>这次a.intdata值的改变可把b.intdata影响了,事实上,对象a和b的类变量均指向相同的数据,所有值一 <BR>样,这就是类变量的作用. <BR><BR>４.实例方法,类方法,构造器方法 <BR><BR>我们通常所说的方法系指实例方法,就像c语言中的函数一样,其具体方法我就不用说了,在这里我主要是 <BR>用它来区分类方法和构造器方法.类方法与实例方法最大的区别是:在形式上类方法多一个static,在用法上, <BR>不必创建对象就可直接调用类方法(而实例方法却一定要先创建对象,再通过对象调用). <BR>eg: <BR>class add <BR>{ <BR>static int addem(int op1,int op2) <BR>{ <BR>return op1+op2; <BR>} <BR>} <BR>public class xxf <BR>{ <BR>public static void main(String[] args) <BR>{ <BR>System.out.println("addem(2,2)="+add.addem(2,2)); <BR>} //直接用类名作为对象调用类方法 <BR>} <BR><BR>注: 也可按通常的方法,即先创建对象,再调用方法,不过,这时static就无任何意义了. <BR>再说说构造器方法,它是用来初始化对象中的数据的一种方法,创建很容易,只需在类中加上一个与这个类 <BR>同名的方法,不需要在前面加任何访问说明符或者返回类型,另外,构造器也一样可以向方法一样传递参数. <BR>eg: <BR>class data <BR>{ <BR>private String data1;//事先声明 <BR><BR>data(String s) <BR>{ <BR>data1=s; /*通过接收数据来初始化变量.(注:不能在构造器内 <BR>声明变量,事先在外就要声明.)*/ <BR>} <BR><BR>public String getdata() <BR>{ <BR>return data1; <BR>} <BR>} <BR><BR>public class xxf <BR>{ <BR>public static void main(String[] args) <BR>{ <BR>System.out.println((new data("I love you")).getdata());/*通过传递参数调用构造器新建一 <BR>个对象,再通过对象调用方法得到数据*/ <BR>} <BR>} <BR><BR>５.接口与类 <BR><BR>类是对一类特定对象的规格说明,我们可以类定义创建对象,通过创建对象来组合所有属于该类的组件,而 <BR>接口不能这样做.而接口实质上就是一个常量和抽象方法的集合,要使用一个接口,就需要在类中实现这个接 <BR>口,然后作为类定义的一部分,编写接口中声明的每一个方法,接口中的方法永远是public,abstract,接口中的 <BR>常量永远是public static和final,因此不需要为它们说明属性. <BR>因为在Java中不支持多重继承,但是,可以用接口来实现类似的功能,这是接口的重要作用之一. <BR>eg: <BR>interface anyone //定义一个接口 <BR>{ <BR>final double PI=3.1416; <BR>void setNumber(int number); <BR>int getNumber(); <BR>} <BR>interface anyother //定义另一个接口 <BR>{ <BR>void setString(String str); <BR>String getString(); <BR>} <BR><BR>class xxf implement anyone,anyother //定义一个类,并使用两个接口 <BR>{ <BR>int number; <BR>String str; <BR>public xxf(){} <BR>void setNumber(int number) <BR>{ <BR>this.number=number; <BR>} <BR>void setString(String str) <BR>{ <BR>this.str=str; <BR>} <BR>void int getNumber(){}//可以为一个空实现. <BR>void String getString(){} <BR>} <BR>//在类中必须实现接口中声明的所有方法.(当然也可不必,但是要用到适配器类或用抽象类) <BR></DIV><img src ="http://www.blogjava.net/gongtao200118/aggbug/18837.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gongtao200118/" target="_blank">Write Once,Run Anywhere!</a> 2005-11-08 18:40 <a href="http://www.blogjava.net/gongtao200118/archive/2005/11/08/18837.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDK1.4安装与环境配置完全图解(windows) </title><link>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18836.html</link><dc:creator>Write Once,Run Anywhere!</dc:creator><author>Write Once,Run Anywhere!</author><pubDate>Tue, 08 Nov 2005 10:36:00 GMT</pubDate><guid>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18836.html</guid><wfw:comment>http://www.blogjava.net/gongtao200118/comments/18836.html</wfw:comment><comments>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18836.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gongtao200118/comments/commentRss/18836.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gongtao200118/services/trackbacks/18836.html</trackback:ping><description><![CDATA[以下过程为JDK下载安装：<BR><BR>1.点击下面网址进入JDK1.4下载页面：<BR><BR><A href="http://java.sun.com/j2se/1.4.2/download.html" target=_blank><FONT color=#000000>http://java.sun.com/j2se/1.4.2/download.html</FONT></A><BR><BR>2.点击“Download J2SE SDK”：<BR><BR><A href="http://forums.zdnet.com.cn/cgi-bin/attachment.cgi?forum=3&amp;topic=1448&amp;postno=2&amp;type=.jpg">http://forums.zdnet.com.cn/cgi-bin/attachment.cgi?forum=3&amp;topic=1448&amp;postno=2&amp;type=.jpg</A><BR><BR><A href="http://forums.zdnet.com.cn/cgi-bin/attachment.cgi?forum=3&amp;topic=1448&amp;postno=3&amp;type=.jpg">http://forums.zdnet.com.cn/cgi-bin/attachment.cgi?forum=3&amp;topic=1448&amp;postno=3&amp;type=.jpg</A><BR><BR>4.下面列出了各个平台下的JDK版本，其中Windows版有两种安装方式，一种是完全下载后再安装，一种是在线安装，我们选择第一种：<BR><BR><A href="http://forums.zdnet.com.cn/cgi-bin/attachment.cgi?forum=3&amp;topic=1448&amp;postno=4&amp;type=.jpg">http://forums.zdnet.com.cn/cgi-bin/attachment.cgi?forum=3&amp;topic=1448&amp;postno=4&amp;type=.jpg</A><BR><BR>5.下载完成后，双击图标进行安装，安装过程中可以自定义安装目录等信息，<BR>例如我们选择安装目录为D:\jdk1.4<BR>以下过程为配置JDK环境变量：<BR>6.右击“我的电脑”，点击“属性”：<BR><BR><A href="http://forums.zdnet.com.cn/cgi-bin/attachment.cgi?forum=3&amp;topic=1448&amp;postno=5&amp;type=.jpg">http://forums.zdnet.com.cn/cgi-bin/attachment.cgi?forum=3&amp;topic=1448&amp;postno=5&amp;type=.jpg</A><BR><BR>7.选择“高级”选项卡，点击“环境变量”：<BR><BR><A href="http://forums.zdnet.com.cn/cgi-bin/attachment.cgi?forum=3&amp;topic=1448&amp;postno=6&amp;type=.jpg">http://forums.zdnet.com.cn/cgi-bin/attachment.cgi?forum=3&amp;topic=1448&amp;postno=6&amp;type=.jpg</A><BR><BR>8.在“系统变量”中，设置3项属性，JAVA_HOME,PATH,CLASSPATH(大小写无所谓),若已存在则点击“编辑”，不存在则点击“新建”：<BR><BR><A href="http://forums.zdnet.com.cn/cgi-bin/attachment.cgi?forum=3&amp;topic=1448&amp;postno=7&amp;type=.jpg">http://forums.zdnet.com.cn/cgi-bin/attachment.cgi?forum=3&amp;topic=1448&amp;postno=7&amp;type=.jpg</A><BR><BR>9.JAVA_HOME指明JDK安装路径，就是刚才安装时所选择的路径D:\jdk1.4，此路径下包括lib，bin，jre等文件夹（此变量最好设置，因为以后运行tomcat，eclipse等都需要依靠此变量）<BR>&nbsp; Path使得系统可以在任何路径下识别java命令，设为：%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin<BR>&nbsp; CLASSPATH为java加载类(class or lib)路径，只有类在classpath中，java命令才能识别，设为：.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar (要加.表示当前路径)<BR>&nbsp; %JAVA_HOME%就是引用前面指定的JAVA_HOME。<BR><A href="http://forums.zdnet.com.cn/cgi-bin/attachment.cgi?forum=3&amp;topic=1448&amp;postno=8&amp;type=.jpg">http://forums.zdnet.com.cn/cgi-bin/attachment.cgi?forum=3&amp;topic=1448&amp;postno=8&amp;type=.jpg</A><BR><BR>11.键入命令“java -version”，出现下图画面，说明环境变量配置成功：<BR><BR><BR><BR><A href="http://forums.zdnet.com.cn/cgi-bin/attachment.cgi?forum=3&amp;topic=1448&amp;postno=9&amp;type=.jpg">http://forums.zdnet.com.cn/cgi-bin/attachment.cgi?forum=3&amp;topic=1448&amp;postno=9&amp;type=.jpg</A><BR><BR>
<TABLE style="TABLE-LAYOUT: fixed" height=260 cellSpacing=0 width="100%">
<TBODY>
<TR>
<TD style="WORD-WRAP: break-word; 130: " vAlign=top><SPAN id=post9 style="FONT-SIZE: 12px; COLOR: #000000">12.好了，打完收工。<BR></SPAN></TD>
<TD width=16></TD></TR>
<TR>
<TD></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/gongtao200118/aggbug/18836.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gongtao200118/" target="_blank">Write Once,Run Anywhere!</a> 2005-11-08 18:36 <a href="http://www.blogjava.net/gongtao200118/archive/2005/11/08/18836.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#与Java之争  </title><link>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18835.html</link><dc:creator>Write Once,Run Anywhere!</dc:creator><author>Write Once,Run Anywhere!</author><pubDate>Tue, 08 Nov 2005 10:27:00 GMT</pubDate><guid>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18835.html</guid><wfw:comment>http://www.blogjava.net/gongtao200118/comments/18835.html</wfw:comment><comments>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18835.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gongtao200118/comments/commentRss/18835.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gongtao200118/services/trackbacks/18835.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=4 width="95%" border=0>
<P>
<TBODY>
<TR>
<TD class=textblack>
<P align=center><B>C#与Java之争</B> </P></TD></TR>
<TR>
<TD class=textblack></TD></TR>
<TR>
<TD class=textgray>
<P>
<DIV>Builder.com邀请了几个CNET的程序员Dan Seewer、Norris Shelton和Kevin Cobb来参加关于C#与Java的辩论。这两门语言以及它们各自的开发平台之间真的存在巨大的鸿沟吗？ 
<P></P>
<TABLE cellSpacing=0 cellPadding=0 width=0 align=right border=0>
<TBODY>
<TR>
<TD align=middle></TD></TR>
<TR>
<TD><!--start banner ad--><!--ba-->
<SCRIPT language=JavaScript1.1 src="http://ad.cn.doubleclick.net/adj/messagingplus.zdnet.com.cn/developer/code;sz=1x1;ord=2085296806?"> </SCRIPT>
<!-- Sniffer Code for Flash 5 -->
<SCRIPT language=VBScript> 
on error resume next 
ShockMode = (IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash.5")))
</SCRIPT>
<NOEMBED>
<a href="http://ad.cn.doubleclick.net/click%3Bh=v5|332a|3|0|%2a|z%3B20498354%3B0-0%3B0%3B6694709%3B31-1|1%3B12161671|12179567|1%3B%3B%7Esscs%3D%3fhttp%3a%2f%2fwww.site.com" target="_blank"><IMG SRC="http://ad.cn.doubleclick.net/123456/banner.gif" WIDTH=468 HEIGHT=60 BORDER=0 ></a>
</NOEMBED><NOSCRIPT>
<a href="http://ad.cn.doubleclick.net/click%3Bh=v5|332a|3|0|%2a|z%3B20498354%3B0-0%3B0%3B6694709%3B31-1|1%3B12161671|12179567|1%3B%3B%7Esscs%3D%3fhttp%3a%2f%2fwww.site.com" target="_blank"><IMG SRC="http://ad.cn.doubleclick.net/123456/banner.gif" WIDTH=468 HEIGHT=60 BORDER=0 ></a>
</NOSCRIPT><NOSCRIPT> <A HREF="http://ad.cn.doubleclick.net/jump/messagingplus.zdnet.com.cn/developer/code;sz=1x1;ord=2085296806?"> <IMG SRC="http://ad.cn.doubleclick.net/ad/messagingplus.zdnet.com.cn/developer/code;sz=1x1;ord=2085296806?" border=0 ></A> 
      </NOSCRIPT><!--end banner ad--></TD></TR></TBODY></TABLE>
<P><B>Builder.com</B><B>：</B>好吧，现在谁准备到“我喜欢Java”一边，谁到“我喜欢C#”一边？</P>
<P><B>Kevin</B><B>：</B>首先必须说明的是我们都是Java的使用者。因此从三个Java使用者的观点出发来看C#，我们只是给出我们对C#的意见——好的或坏的。</P>
<P><B>Norris</B>：我们可以证明我们的观点，它们的确是对的。C#与Java非常相像，它们之间的差别比起C#与C++来要小得多。如果Java中有某个东西，在C#中也会有相似的某个东西，反之亦然。</P>
<P><B>Dan</B><B>：</B>我想，微软的说词在于C++，以及他们对C++的发展。</P>
<P><B>Kevin</B><B>：</B>那我们能拿出什么呢？</P>
<P><B>Dan</B><B>：</B>对，我们能够拿出其它的什么来吸引和说服C++用户呢？</P>
<P><B>Kevin</B><B>：</B>我学习C#过程中它对我的打击是，加入其中的是一些浮华的东西，只是吸引了人们的眼球，却没有真正使它成为一门更好的语言。也许这样说有些不公……</P>
<P><B>Dan</B><B>：</B>不，我想的却是这样。</P>
<P><B>Norris</B><B>：</B>我想，他们有了C++，然后又有了Java。于是C++的某些特性被拿掉以使Java更简。单。</P>
<P><B>Dan</B><B>：</B>很对。如果C++的爱好者不喜欢这样，他们会把这种改变视为障碍。</P>
<P><B>Norris</B><B>：</B>应该说这对于Java的使用者并不成立，因为如果一开始就使用Java，你就不会感到任何的不便。</P>
<P><B>Dan</B><B>：</B>对</P>
<P><B>Norris</B><B>：</B>但是那些并不适用Java的人却看得到所有的限制。如果我是一个C++程序员，而且我并不想学习Java，于是我开始学习C#。微软为C#添加了许多内容，但是在某些情况下，他们加入的只会变得更复杂。比如索引器——它并没有使你得到新的东西。Java程序员对此不会感到损失，但是我相信这会增加程序的复杂性。</P>
<P><B>Dan</B><B>：</B>对于运算符重载也是同一个道理。</P>
<P><B>Norris</B><B>：</B>是的。</P></DIV></TD></TR>
<P></P></P></TABLE><img src ="http://www.blogjava.net/gongtao200118/aggbug/18835.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gongtao200118/" target="_blank">Write Once,Run Anywhere!</a> 2005-11-08 18:27 <a href="http://www.blogjava.net/gongtao200118/archive/2005/11/08/18835.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>该学 Java 或 .NET  </title><link>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18834.html</link><dc:creator>Write Once,Run Anywhere!</dc:creator><author>Write Once,Run Anywhere!</author><pubDate>Tue, 08 Nov 2005 10:25:00 GMT</pubDate><guid>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18834.html</guid><wfw:comment>http://www.blogjava.net/gongtao200118/comments/18834.html</wfw:comment><comments>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18834.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/gongtao200118/comments/commentRss/18834.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gongtao200118/services/trackbacks/18834.html</trackback:ping><description><![CDATA[<P align=left>自从 .NET 问世以来，程序员都很关心的一个问题是「该学 Java 或 .NET 」。我也在挣扎，该「该继续 Java 的研究，或者该开始准备培养 .NET 的知识」。 </P>
<P align=left>当然，最好是能两者兼顾，但是每个人的时间都很有限，想要兼顾两者，其实不太容易。投入在 .NET 的时间越多，所能花费在 Java 的时间自然就少了，反之亦然。在信息爆炸的时代，重要的不是信息的取得，而是信息的抉择。信息太多，时间太少，如果不能慎选适合的技术，只会平白浪费许多时间，斲丧自己的竞争力。 </P>
<P align=left>由于我喜新厌旧的个性使然，过去这两年半，我着实花了不少时间在 .NET 上，对于 .NET 的认识越来越深，也修正了对于 .NET 原先的一些误解，渐渐的认同 .NET 的许多技术理念。姑且不论我们对于微软是褒是贬，单纯就技术本身来看， .NET 的确是很卓越的。 </P>
<P align=left>我并不是唯一一个这样想的人。以「 Thinking in Java 」等技术书籍广受欢迎的 Bruce Eckel 也是如此。他原本认为 C# 和 .NET 只是 Java 的模仿者，并无新意，但是在深入了解之后，才发现 C# 和 .NET 其实是改良版的 Java ，不管在各方面，都有比 Java 更突出之处。当我看到 Bruce Eckel 说出这样的话，我感觉他说出了我的心声。 <BR><BR></P>
<P>下面，我试图从许多不同的角度，简单地比较 Java 和 .NET 。 </P>
<P align=left><STRONG>从技术的观点 </STRONG></P>
<P align=left>通常新的技术会比旧技术更好，因为新技术可以从旧技术学到优点，且新技术可以摒除旧技术的缺点。 NET 比 Java 诞生的时间晚了六年，许多方面都比 Java 先进，当然是无庸置疑。 </P>
<P align=left>我的意思并不是 Java 这六年停滞不前，事实上， Java 一直在进步中，只是有许多缝缝补补、修修改改的地方。例如， XML 是在这六年之间出现的技术，所以 .NET 对于 XML 的整合可以说是天衣无缝，但 Java 是后来才把 XML 整合进来，且整合的程度比不上 .NET 。 </P>
<P align=left><STRONG>从历史的观点 </STRONG></P>
<P align=left>以史为镜，可以知兴替。如果你了解近二十年的软件产业发展史，你会发现微软挫败的机会很小，即使是在头几场战役失败，也会在整场战争中获胜。换句话说， .NET 挫败的机会不大。在 Office 软件大战中， WordPerfect 、 Ami Pro 、 Lotus 123 如今安在？在操作系统大战中， OS/2 也已经销声匿迹。在浏览器大战中， Navigator 如今只整剩下小小的疆土。你一定可以举出更多这样的例子。 </P>
<P align=left><STRONG>从市调的观点 </STRONG></P>
<P align=left>分析机构如 Meta Group 和 IDC 皆预测，在 Windows Server 2003 推出之后，未来几年市占率会大幅提高。我认为，在 longhorn 推出之后（ 2006 年？）， PC 更是会全面 .NET 化。由于「精通」 .NET 知识可能需要费时两三年以上，技术人员应该尽量提早学习 .NET 以为因应。 </P>
<P align=left>三年前（ 2000 年）学习 .NET 恐怕有点太早，三年后（ 2006 年）学习 .NET 恐怕有点太晚，而现在学习 .NET 正是时候，不会太早，也不会太晚。学会之后，可以立刻投入市场对于 .NET 技术的人力需求。 </P>
<P align=left><STRONG>从营销的观点 </STRONG></P>
<P align=left>任何人都不能否定微软营销功力的厉害。平面的营销，包括在电子时报、 IT Home 等信息媒体，甚至连商业周刊等非信息媒体，都看得到相关的广告。动态的营销，包括 PDC 、 TechEd. 、修练讲座、产品发表会 … 等活动，直接走入人群，接触客户。电子的营销，包括 MSDN 中英文网站、微软 TechNet Flash 新闻信 … 等，提供技术新知。 </P>
<P align=left>另外，还有多得拿不完的教学光盘，读不完的在线文件，看不完的 Microsoft Press 出版品 … 。我发现，微软的作法和另一家公司的作法大相径庭。微软给我们一堆技术信息，要什么有什么，但另一家公司却常常把信息当成「传家宝」，舍不得释放出来给大众，连透过内部管道都还不见得拿得到，「好像很不希望有人学习他们正大力推广的技术」。 </P>
<P align=left><STRONG>从销售指标的观点 </STRONG></P>
<P align=left>关于某个城市的消费者物价指数，麦香堡指标（ BigMac Index ）是一个很有名也很简易的评估指标。我也发明了一个类似的指标，称为天珑指标（ TenLong Index ），可以用来评估 IT 技术的热门程度。天珑书局是台湾最大的 IT 图书门市，它的技术书籍销售量，对于判断技术的热门程度，有一定程度的参考价值。 </P>
<P align=left>2002 年全年和 2003 年上半年，天珑书局在 .NET 书籍的销售量都不高，但是在 2003 年下半年之后， .NET 书籍已经有相当不错的表现，这意味着最近准备采用 .NET 技术的公司已经增加了。 </P>
<P align=left>我记得在 Java 推广初期，由于大家对于 Java 认知不够，所以对于 Java 有许多 FUD 存在。现在微软在推广 .NET 上，也遭遇到许多 FUD ，这是微软目前必须极力消除的障碍。如果你对于 .NET 也存有这些 FUD ，你不妨尝试着去破除这些 FUD ，就如同七八年前破除 Java 的 FUD 一样。你将会发现，就目前来说， .NET 是一个非常有潜力的技术，值得投入。 </P><img src ="http://www.blogjava.net/gongtao200118/aggbug/18834.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gongtao200118/" target="_blank">Write Once,Run Anywhere!</a> 2005-11-08 18:25 <a href="http://www.blogjava.net/gongtao200118/archive/2005/11/08/18834.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Java中使用方法重载  </title><link>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18832.html</link><dc:creator>Write Once,Run Anywhere!</dc:creator><author>Write Once,Run Anywhere!</author><pubDate>Tue, 08 Nov 2005 10:21:00 GMT</pubDate><guid>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18832.html</guid><wfw:comment>http://www.blogjava.net/gongtao200118/comments/18832.html</wfw:comment><comments>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18832.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gongtao200118/comments/commentRss/18832.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gongtao200118/services/trackbacks/18832.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=4 width="95%" border=0>
<P>
<TBODY>
<TR>
<TD class=textblack>
<P align=center><B>在Java中使用方法重载</B> </P></TD></TR>
<P></P></P></TABLE>命名转换是任何程序开发工程的重要部分，但当处理特别的名称的时候命名转换也会变得相当繁琐。简化这一过程的其中一个方法是通过重载而重新使用方法的名称。重载能够使具有相同名称但不相同数目和类型参数的类传递给方法。
<H5>名称中包含的内容</H5>
<P>当将名称分配到类、方法、变量时，使用能够容易理解的名称相当重要。例如，建立一个定义一个人的类，此时应该建立一个合适的名为<I>Person</I>的类。这一个类命名为一个随便的名称<I>dkjfb</I>也无可厚非，但对于开发这一软件的任何程序员是没有什么意义，因为它不能代表本身的含义。<I>Person</I>类应该具有以下的内容：</P>
<P><FONT color=#0066ff>class Person {<BR>private String firstName;<BR>private String lastName;<BR>}</FONT><BR><BR>列举的代码声明了一个名为<I>Person</I>的类，其带有两个成员变量参数以存储姓和名。分配给成员变量参数的名称就符合它们本身的含义，这样就很容易地识别存储在变量中的内容。当调用一个<I>Person</I>类时，我们可以很直观地使用这些成员变量参数。</P>
<H5>对象构建</H5>
<P>建立一个新的对象的实例会触发类的构造函数的方法。以下代码使用了一个基本的构造函数，这一构造函数无需接收任何变量：</P>
<P><FONT color=#0066ff>class Person {<BR>private String firstName;<BR>private String lastName;<BR>Person() {<BR>this.firstName = "";<BR>this.lastName = "";<BR>} }</FONT><BR><BR>这一基本的构造函数使用空字符串的变量参数。在以后的程序中可以看到，在很多时候，对象建立时都附带已知的名字。你可以使用方法重载来建立多个方法，但每一个方法都有自己的方法记号。记号指定了被方法接受的参数。例如，这里是前一构造函数的方法记号：</P>
<P><FONT color=#0066ff>Person()</FONT><BR><BR>这一方法可以重载以接收姓和名或者只是名：<BR><FONT color=#0066ff>class Person {<BR>private String firstName;<BR>private String lastName;<BR>Person() {<BR>this.firstName = "";<BR>this.lastName = "";<BR>}<BR>Person(String lname) {<BR>this.firstName = "";<BR>this.lastName = lname;<BR>}<BR>Person(String fname, String lname) {<BR>this.firstName = fname;<BR>this.lastName = lname;<BR>} }</FONT><BR><BR>在一个类中任何具有相同名称的两个方法必须有不同的参数类型或者不同的参数数目，否则编译器拒绝它们。现在类可以声明如下：</P>
<P><FONT color=#0066ff>Person p1 = new Person();<BR>Person p2 = new Person("Patton");<BR>Person p3 = new Person("Patton", "Tony");</FONT><BR><BR><BR></P>
<H5>一个Java的特性</H5>
<P>
<TABLE cellSpacing=0 cellPadding=0 width=0 align=right border=0>
<TBODY>
<TR>
<TD align=middle></TD></TR>
<TR>
<TD><!--start banner ad--><!--ba-->
<SCRIPT language=JavaScript1.1 src="http://ad.cn.doubleclick.net/adj/messagingplus.zdnet.com.cn/developer/code;sz=1x1;ord=1918373381?"> </SCRIPT>
<!-- Sniffer Code for Flash 5 -->
<SCRIPT language=VBScript> 
on error resume next 
ShockMode = (IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash.5")))
</SCRIPT>
<NOEMBED>
<a href="http://rd.intl.doubleclick.net/click%3Bh=v5|332a|3|0|%2a|z%3B20498354%3B0-0%3B0%3B6694709%3B31-1|1%3B12161671|12179567|1%3B%3B%7Esscs%3D%3fhttp%3a%2f%2fwww.site.com" target="_blank"><IMG SRC="http://m.2mdn.net/123456/banner.gif" WIDTH=468 HEIGHT=60 BORDER=0 ></a>
</NOEMBED><NOSCRIPT>
<a href="http://rd.intl.doubleclick.net/click%3Bh=v5|332a|3|0|%2a|z%3B20498354%3B0-0%3B0%3B6694709%3B31-1|1%3B12161671|12179567|1%3B%3B%7Esscs%3D%3fhttp%3a%2f%2fwww.site.com" target="_blank"><IMG SRC="http://m.2mdn.net/123456/banner.gif" WIDTH=468 HEIGHT=60 BORDER=0 ></a>
</NOSCRIPT><NOSCRIPT> <A HREF="http://ad.cn.doubleclick.net/jump/messagingplus.zdnet.com.cn/developer/code;sz=1x1;ord=1918373381?"> <IMG SRC="http://ad.cn.doubleclick.net/ad/messagingplus.zdnet.com.cn/developer/code;sz=1x1;ord=1918373381?" border=0 ></A> 
      </NOSCRIPT><!--end banner ad--></TD></TR></TBODY></TABLE></P>
<P>重载能够用于标准的Java类中。System.out.println方法接收多参数列表。相关范例代码可以见以下：</P>
<P><FONT color=#0066ff>System.out.println("Builder.com");</FONT><BR><BR>以及：</P>
<P><FONT color=#0066ff>int test = 2;<BR>System.out.println(test);</FONT><BR><BR>这两个代码片段编译与执行时都没有任何错误。Println方法已经被设计为接收不同的变量，所以重载超乎构造函数的程序。为了更进一步的说明这一点，我们可以通过添加一个print方法来输出姓和名以加深我们的范例程序：</P>
<P><FONT color=#0066ff>class Person {<BR>private String firstName;<BR>private String lastName;<BR>Person() {<BR>this.firstName = "";<BR>this.lastName = "";<BR>}<BR>Person(String lname) {<BR>this.firstName = "";<BR>this.lastName = lname;<BR>}<BR>Person(String fname, String lname) {<BR>this.firstName = fname;<BR>this.lastName = lname;<BR>}<BR><BR>public void Print() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(firstName + " " + lastName);<BR>}<BR>&nbsp;<BR>public void Print(String pout) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(pout + " " + firstName + " " + lastName);<BR>}<BR>&nbsp;}</FONT><BR><BR>这两个print方法输出成员变量，其中一个方法接收文本而输出，而另一方法没有采用这样的方式。</P>
<H5>当使用重载的时候</H5>
<P>重载是一个功能强大的特性，但你只能在需要的时候使用它。当你确实需要不同变量的多种方法，但这些方法都可以做相同的任务，此时就可以采用重载方式。也就是说，如果多种方法执行不同的任务，此时不能采用重载方式。否则，这一方法只能导致你的程序显得很混乱，特别是其他程序员阅读你的代码的时候。</P><img src ="http://www.blogjava.net/gongtao200118/aggbug/18832.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gongtao200118/" target="_blank">Write Once,Run Anywhere!</a> 2005-11-08 18:21 <a href="http://www.blogjava.net/gongtao200118/archive/2005/11/08/18832.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java中final方法的意义 </title><link>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18831.html</link><dc:creator>Write Once,Run Anywhere!</dc:creator><author>Write Once,Run Anywhere!</author><pubDate>Tue, 08 Nov 2005 10:18:00 GMT</pubDate><guid>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18831.html</guid><wfw:comment>http://www.blogjava.net/gongtao200118/comments/18831.html</wfw:comment><comments>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18831.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/gongtao200118/comments/commentRss/18831.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gongtao200118/services/trackbacks/18831.html</trackback:ping><description><![CDATA[&nbsp; 
<TABLE style="TABLE-LAYOUT: fixed; WORD-BREAK: break-all" cellSpacing=0 cellPadding=0 width="90%" border=0>
<TBODY>
<TR>
<TD class=oblog_t_4>
<P align=center><SPAN class=style1><FONT size=3>java中final方法的意义</FONT></SPAN></P></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD>
<DIV align=right><SPAN class=oblog_text></SPAN>&nbsp;</DIV></TD></TR></TBODY></TABLE><SPAN class=oblog_text><BR>之所以要使用final方法，可能是出于对两方面理由的考虑。第一个是为方法“上锁”，防止任何继承类改变它的本来含义。设计程序时，若希望一个方法的行为在继承期间保持不变，而且不可被覆盖或改写，就可以采取这种做法。<BR>采用final方法的第二个理由是程序执行的效率。将一个方法设成final后，编译器就可以把对那个方法的所有调用都置入“嵌入”调用里。<BR></SPAN></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/gongtao200118/aggbug/18831.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gongtao200118/" target="_blank">Write Once,Run Anywhere!</a> 2005-11-08 18:18 <a href="http://www.blogjava.net/gongtao200118/archive/2005/11/08/18831.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA教程 第六讲 Java的线程和Java Applet</title><link>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18680.html</link><dc:creator>Write Once,Run Anywhere!</dc:creator><author>Write Once,Run Anywhere!</author><pubDate>Mon, 07 Nov 2005 16:56:00 GMT</pubDate><guid>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18680.html</guid><wfw:comment>http://www.blogjava.net/gongtao200118/comments/18680.html</wfw:comment><comments>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18680.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gongtao200118/comments/commentRss/18680.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gongtao200118/services/trackbacks/18680.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JAVA教程 第六讲 Java的线程和Java Applet<BR><BR>6．1 线程简介 <BR><BR>　　随着计算机的飞速发展，个人计算机上的<A class=blue href="http://www.it.com.cn/edu/systeminfo/" target=_blank>操作系统</A>也纷纷采用多任务和分时设计，将早期只有大型计算机才具有的系统特性带到了个人计算机系统中。一般可以在同一时间内执行多个程序的操作系统都有进程的概念。一个进程就是一个执行中的程序，而每一个进程都有自己独立的一块内存空间、一组系统资源。在进程概念中，每一个进程的内部数据和状态都是完全独立的。Java程序通过流控制来执行程序流，程序中单个顺序的流控制称为线程，多线程则指的是在单个程序中可以同时运行多个不同的线程，执行不同的任务。多线程意味着一个程序的多行语句可以看上去几乎在同一时间内同时运行。 <BR><BR>　　线程与进程相似，是一段完成某个特定功能的代码，是程序中单个顺序的流控制；但与进程不同的是，同类的多个线程是共享一块内存空间和一组系统资源，而线程本身的数据通常只有微处理器的寄存器数据，以及一个供程序执行时使用的堆栈。所以系统在产生一个线程，或者在各个线程之间切换时，负担要比进程小的多，正因如此，线程被称为轻负荷进程（light-weight process）。一个进程中可以包含多个线程。 <BR><BR>　　一个线程是一个程序内部的顺序控制流。 <BR>　　1. 进程：每个进程都有独立的代码和数据空间（进程上下文） ，进程切换的开销大。 <BR>　　2. 线程：轻量的进程，同一类线程共享代码和数据空间，每个线程有独立的运行栈和程序计数器（PC），线程切换的开销小。 <BR>　　3. 多进程：在操作系统中，能同时运行多个任务程序。 <BR>　　4. 多线程：在同一应用程序中，有多个顺序流同时执行。 <BR><BR>　　6．1．1 线程的概念模型 <BR><BR>　　Java内在支持多线程，它的所有类都是在多线程下定义的，Java利用多线程使整个系统成为异步系统。Java中的线程由三部分组成，如图6.1所示。 <BR><BR>　　1. 虚拟的CPU，封装在java.lang.Thread类中。 <BR>　　2. CPU所执行的代码，传递给Thread类。 <BR>　　3. CPU所处理的数据，传递给Thread类。 <BR><BR>　　图6.1线程 <BR><BR>　　6. 1. 2 线程体(1) <BR><BR><BR>　　Java的线程是通过java.lang.Thread类来实现的。当我们生成一个Thread类的对象之后,一个新的线程就产生了。 <BR><BR>　　此线程实例表示Java解释器中的真正的线程，通过它可以启动线程、终止线程、线程挂起等，每个线程都是通过类Thread在Java的软件包Java.lang中定义，它的构造方法为： <BR><BR>　　　public Thread （ThreadGroup group，Runnable target，String name）； <BR><BR>　　其中，group 指明该线程所属的线程组；target实际执行线程体的目标对象，它必须实现接口Runnable； name为线程名。Java中的每个线程都有自己的名称，Java提供了不同Thread类构造器，允许给线程指定名称。如果name为null时，则Java自动提供唯一的名称。 <BR>　　当上述构造方法的某个参数为null时，我们可得到下面的几个构造方法： <BR><BR>　　public Thread （）； <BR>　　public Thread （Runnable target）； <BR>　　public Thread （Runnable target，String name）； <BR>　　public Thread （String name）； <BR>　　public Thread （ThreadGroup group，Runnable target）； <BR>　　public Thread （ThreadGroup group，String name）； <BR><BR>　　一个类声明实现Runnable接口就可以充当线程体，在接口Runnable中只定义了一个方法 run（）： <BR>　　　　　　　public void run（）； <BR><BR>　　任何实现接口Runnable的对象都可以作为一个线程的目标对象，类Thread本身也实现了接口Runnable，因此我们可以通过两种方法实现线程体。 <BR><BR>　　（一）定义一个线程类，它继承线程类Thread并重写其中的方法 run（），这时在初始化这个类的实例时，目标target可为null，表示由这个实例对来执行线程体。由于Java只支持单重继承，用这种方法定义的类不能再继承其它父类。 <BR><BR>　　（二）提供一个实现接口Runnable的类作为一个线程的目标对象，在初始化一个Thread类或者Thread子类的线程对象时，把目标对象传递给这个线程实例，由该目标对象提供线程体 run（）。这时，实现接口Runnable的类仍然可以继承其它父类。 <BR><BR>　　每个线程都是通过某个特定Thread对象的方法run( )来完成其操作的，方法run( )称为线程体。图6.2表示了java线程的不同状态以及状态之间转换所调用的方法。 <BR><BR>　　图6.2 线程的状态 <BR>　　　　 <BR>　　 1. 创建状态(new Thread) <BR>　　执行下列语句时，线程就处于创建状态： <BR>　　Thread myThread = new MyThreadClass( ); <BR>　　当一个线程处于创建状态时，它仅仅是一个空的线程对象，系统不为它分配资源。 <BR><BR>　　2. 可运行状态( Runnable ) <BR>　　Thread myThread = new MyThreadClass( ); <BR>　　myThread.start( ); <BR>　　当一个线程处于可运行状态时，系统为这个线程分配了它需的系统资源，安排其运行并调用线程运行方法，这样就使得该线程处于可运行( Runnable )状态。需要注意的是这一状态并不是运行中状态（Running )，因为线程也许实际上并未真正运行。由于很多计算机都是单处理器的，所以要在同一时刻运行所有的处于可运行状态的线程是不可能的，Java的运行系统必须实现调度来保证这些线程共享处理器。 <BR>　　 <BR>　　3. 不可运行状态（Not Runnable） <BR>　　进入不可运行状态的原因有如下几条： <BR>　　1) 调用了sleep（）方法; <BR>　　2) 调用了suspend（）方法; <BR>　　3) 为等候一个条件变量，线程调用wait（）方法; <BR>　　4) 输入输出流中发生线程阻塞; <BR>　　不可运行状态也称为阻塞状态（Blocked）。因为某种原因（输入/输出、等待消息或其它阻塞情况），系统不能执行线程的状态。这时即使处理器空闲，也不能执行该线程。 <BR><BR>　　4. 死亡状态（Dead） <BR>　　线程的终止一般可通过两种方法实现：自然撤消（线程执行完）或是被停止（调用stop()方法）。目前不推荐通过调用stop()来终止线程的执行，而是让线程执行完。 <BR><BR>　　 <BR><BR>　　6. 1. 2 线程体(2) <BR><BR><BR>　　◇线程体的构造 <BR><BR>　　任何实现接口Runnable的对象都可以作为一个线程的目标对象，上面已讲过构造线程体有两种方法，下面通过实例来说明如何构造线程体的。 <BR><BR>　　例6．1 通过继承类Thread构造线程体 <BR>　　class SimpleThread extends Thread { <BR>　　public SimpleThread(String str) { <BR>　　　super(str); //调用其父类的构造方法 <BR>　　} <BR>　　public void run() { //重写run方法 <BR>　　　for (int i = 0; i &lt; 10; i++) { <BR>　　　　System.out.println(i + " " + getName()); <BR>　　　　　　　　　　　　　//打印次数和线程的名字 <BR>　　　　try { <BR>　　　　　　sleep((int)(Math.random() * 1000)); <BR>　　　　　　　　　　　　　//线程睡眠，把控制权交出去 <BR>　　　　} catch (InterruptedException e) {} <BR>　　} <BR><BR>　　　　　System.out.println("DONE! " + getName()); <BR>　　　　　　　　　　　　　//线程执行结束 <BR>　　　　} <BR>　　} <BR>　　public class TwoThreadsTest { <BR>　　　public static void main (String args[]) { <BR>　　　　new SimpleThread("First").start(); <BR>　　　　　　　　　　　　　//第一个线程的名字为First <BR>　　　　new SimpleThread("Second").start(); <BR>　　　　　　　　　　　　　//第二个线程的名字为Second <BR>　　} <BR>　　} <BR><BR>　　　运行结果: <BR>　　　　0 First <BR>　　　　0 Second <BR>　　　　1 Second <BR>　　　　1 First <BR>　　　　2 First <BR>　　　　2 Second <BR>　　　　3 Second <BR>　　　　3 First <BR>　　　　4 First <BR>　　　　4 Second <BR>　　　　5 First <BR>　　　　5 Second <BR>　　　　6 Second <BR>　　　　6 First <BR>　　　　7 First <BR>　　　　7 Second <BR>　　　　8 Second <BR>　　　　9 Second <BR>　　　　8 First <BR>　　　　DONE! Second <BR>　　　　9 First <BR>　　　　DONE! First <BR><BR>　　仔细分析一下运行结果，会发现两个线程是交错运行的，感觉就象是两个线程在同时运行。但是实际上一台计算机通常就只有一个CPU，在某个时刻只能是只有一个线程在运行，而java语言在设计时就充分考虑到线程的并发调度执行。对于程序员来说，在编程时要注意给每个线程执行的时间和机会，主要是通过让线程睡眠的办法（调用sleep()方法）来让当前线程暂停执行，然后由其它线程来争夺执行的机会。如果上面的程序中没有用到sleep()方法，则就是第一个线程先执行完毕，然后第二个线程再执行完毕。所以用活sleep()方法是学习线程的一个关键。 <BR><BR><BR>　　例6．2 通过接口构造线程体 <BR>　　　public class Clock extends java.applet.Applet implements Runnable {//实现接口 <BR>　　　　　　Thread clockThread; <BR>　　　　　　public void start() { <BR>　　　　　　　　　//该方法是Applet的方法，不是线程的方法 <BR>　　　　　　if (clockThread == null) { <BR>　　　　　　　　　clockThread = new Thread(this, "Clock"); <BR>　　　　　　　　　/*线程体是Clock对象本身，线程名字为"Clock"*/ <BR>　　　　　　　　　clockThread.start(); //启动线程 <BR>　　　　　　　　　} <BR>　　　　　　} <BR><BR>　　　　　　public void run() { //run()方法中是线程执行的内容 <BR>　　　　　　　　　while (clockThread != null) { <BR>　　　　　　　　　repaint(); //刷新显示画面 <BR>　　　　　　　　　try { <BR>　　　　　　　　　　　clockThread.sleep(1000); <BR>　　　　　　　　　　　//睡眠1秒，即每隔1秒执行一次 <BR>　　　　　　　　　　} catch (InterruptedException e){} <BR>　　　　　　　　　} <BR>　　　　　　} <BR><BR>　　　　　　public void paint(Graphics g) { <BR>　　　　　　　　　　Date now = new Date(); //获得当前的时间对象 <BR>　　　　　　　　　　g.drawString(now.getHours() + ":" + now.getMinutes()+ ":" +now.getSeconds(), 5, 10);//显示当前时间 <BR>　　　　　　} <BR><BR>　　　　　　public void stop() { <BR>　　　　　　　　//该方法是Applet的方法，不是线程的方法 <BR>　　　　　　　　　　clockThread.stop(); <BR>　　　　　　　　　　clockThread = null; <BR>　　　　　　} <BR>　　　} <BR><BR>　　上面这个例子是通过每隔1秒种就执行线程的刷新画面功能，显示当前的时间；看起来的效果就是一个时钟，每隔1秒就变化一次。由于采用的是实现接口Runnable的方式，所以该类Clock还继承了Applet, Clock就可以Applet的方式运行。 <BR><BR><BR>构造线程体的两种方法的比较： <BR><BR>　　1. 使用Runnable接口 <BR>　　　1) 可以将CPU，代码和数据分开，形成清晰的模型; <BR>　　　2) 还可以从其他类继承; <BR>　　　3) 保持程序风格的一致性。 <BR><BR>　　2. 直接继承Thread类 <BR>　　　1) 不能再从其他类继承; <BR>　　　2) 编写简单，可以直接操纵线程，无需使用Thread.currentThread()。 <BR><BR>　　6．1．3 线程的调度 <BR><BR><BR>　　Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程。线程调度器按照线程的优先级决定应调度哪些线程来执行。 <BR><BR>　　线程调度器按线程的优先级高低选择高优先级线程（进入运行中状态）执行，同时线程调度是抢先式调度，即如果在当前线程执行过程中，一个更高优先级的线程进入可运行状态，则这个线程立即被调度执行。 <BR><BR>　　抢先式调度又分为：时间片方式和独占方式。在时间片方式下，当前活动线程执行完当前时间片后，如果有其他处于就绪状态的相同优先级的线程，系统会将执行权交给其他就绪态的同优先级线程；当前活动线程转入等待执行队列，等待下一个时间片的调度。 <BR><BR>　　在独占方式下，当前活动线程一旦获得执行权，将一直执行下去，直到执行完毕或由于某种原因主动放弃CPU，或者是有一高优先级的线程处于就绪状态。 <BR><BR>　　下面几种情况下，当前线程会放弃CPU: <BR><BR>　　1. 线程调用了yield() 或sleep() 方法主动放弃； <BR><BR>　　2. 由于当前线程进行I/O 访问，外存读写，等待用户输入等操作，导致线程阻塞；或者是为等候一个条件变量，以及线程调用wait（）方法； <BR><BR>　　3. 抢先式系统下，由高优先级的线程参与调度；时间片方式下，当前时间片用完，由同优先级的线程参与调度。 <BR><BR>　　线程的优先级 <BR><BR>　　线程的优先级用数字来表示，范围从1到10，即Thread.MIN_PRIORITY到Thread.MAX_PRIORITY。一个线程的缺省优先级是5，即Thread.NORM_PRIORITY。下述方法可以对优先级进行操作： <BR><BR>　　int getPriority(); //得到线程的优先级 <BR>　　void setPriority(int newPriority); <BR>　　//当线程被创建后，可通过此方法改变线程的优先级 <BR><BR>　　例6．3中生成三个不同线程，其中一个线程在最低优先级下运行，而另两个线程在最高优先级下运行。 <BR><BR>　　例6．3 <BR>　　class ThreadTest{ <BR>　　　　public static void main( String args [] ) { <BR>　　　　　　Thread t1 = new MyThread("T1"); <BR>　　　　　　t1.setPriority( Thread.MIN_PRIORITY ); //设置优先级为最小 <BR>　　　　　　t1.start( ); <BR>　　　　　　Thread t2 = new MyThread("T2"); <BR>　　　　　　t2.setPriority( Thread.MAX_PRIORITY ); //设置优先级为最大 <BR>　　　　　　t2.start( ); <BR>　　　　　　Thread t3 = new MyThread("T3"); <BR>　　　　　　t3.setPriority( Thread.MAX_PRIORITY ); //设置优先级为最大 <BR>　　　　　　t3.start( ); <BR>　　　　} <BR>　　　　　　　　} <BR><BR>　　　class MyThread extends Thread { <BR>　　　　　String message; <BR>　　　　　MyThread ( String message ) { <BR>　　　　　　　　this.message = message; <BR>　　　　　} <BR>　　　　　public void run() { <BR>　　　　　　　for ( int i=0; i&lt;3; i++ ) <BR>　　　　　　　　System.out.println( message+" "+getPriority() ); <BR>　　　　　　　　　　　　　　　　　　　　　　　　　//获得线程的优先级 <BR>　　　　　} <BR>　　　　　　　　} <BR><BR>　　运行结果： <BR>　　　　　　　T2 10 <BR>　　　　　　　T2 10 <BR>　　　　　　　T2 10 <BR>　　　　　　　T3 10 <BR>　　　　　　　T3 10 <BR>　　　　　　　T3 10 <BR>　　　　　　　T1 1 <BR>　　　　　　　T1 1 <BR>　　　　　　　T1 1 <BR><BR>　　注意：并不是在所有系统中运行Java程序时都采用时间片策略调度线程，所以一个线程在空闲时应该主动放弃CPU，以使其他同优先级和低优先级的线程得到执行。 <BR><BR>　　6．1．4基本的线程控制 <BR><BR>　　1．终止线程 <BR><BR>　　线程终止后，其生命周期结束了，即进入死亡态，终止后的线程不能再被调度执行，以下几种情况，线程进入终止状态： <BR>　　1) 线程执行完其run()方法后，会自然终止。 <BR>　　2) 通过调用线程的实例方法stop()来终止线程。 <BR><BR>　　2． 测试线程状态 <BR><BR>　　可以通过Thread 中的isAlive() 方法来获取线程是否处于活动状态；线程由start() 方法启动后，直到其被终止之间的任何时刻，都处于'Alive'状态。 <BR><BR>　　3． 线程的暂停和恢复 <BR><BR>　　有几种方法可以暂停一个线程的执行，在适当的时候再恢复其执行。 <BR>　　1) sleep() 方法 <BR>　　当前线程睡眠（停止执行）若干毫秒，线程由运行中状态进入不可运行状态，停止执行时间到后线程进入可运行状态。 <BR><BR>　　2) suspend()和resume()方法 <BR>　　线程的暂停和恢复，通过调用线程的suspend()方法使线程暂时由可运行态切换到不可运行态，若此线程想再回到可运行态，必须由其他线程调用resume()方法来实现。 <BR>　　注：从JDK1.2开始就不再使用suspend()和resume()。 <BR><BR>　　3) join() <BR>　　当前线程等待调用该方法的线程结束后, 再恢复执行. <BR>　　TimerThread tt=new TimerThread(100); <BR>　　tt.start(); <BR>　　… <BR>　　public void timeout(){ <BR>　　tt.join();// 当前线程等待线程tt 执行完后再继续往下执行 <BR>　　… } <BR><BR>　　 <BR><BR>　　6．2多线程的互斥与同步 <BR><BR>　　临界资源问题 <BR><BR>　　前面所提到的线程都是独立的，而且异步执行，也就是说每个线程都包含了运行时所需要的数据或方法，而不需要外部的资源或方法，也不必关心其它线程的状态或行为。但是经常有一些同时运行的线程需要共享数据，此时就需考虑其他线程的状态和行为，否则就不能保证程序的运行结果的正确性。例6．4说明了此问题。 <BR><BR>　　例6．4 <BR>　　class stack{ <BR>　　　int idx=0; //堆栈指针的初始值为0 <BR>　　　char[ ] data = new char[6]; //堆栈有6个字符的空间 <BR><BR>　　　public void push(char c){ //压栈操作 <BR>　　　　data[idx] = c; //数据入栈 <BR>　　　　idx + +; //指针向上移动一位 <BR>　　　} <BR><BR>　　　　　public char pop(){ //出栈操作 <BR>　　　　　　　idx - -; //指针向下移动一位 <BR>　　　　　　　return data[idx]; //数据出栈 <BR>　　　　　} <BR>　　　} <BR><BR><BR>　　两个线程A和B在同时使用Stack的同一个实例对象，A正在往堆栈里push一个数据，B则要从堆栈中pop一个数据。如果由于线程A和B在对Stack对象的操作上的不完整性，会导致操作的失败，具体过程如下所示： <BR><BR>　　1) 操作之前 <BR>　　　　　data = | p | q | | | | | idx=2 <BR><BR><BR>　　2) A执行push中的第一个语句，将r推入堆栈； <BR>　　　　　data = | p | q | r | | | | idx=2 <BR><BR>　　3) A还未执行idx++语句，A的执行被B中断，B执行pop方法，返回q： <BR>　　　　　data = | p | q | r | | | | idx=1 <BR><BR>　　4〕A继续执行push的第二个语句： <BR>　　　　　data = | p | q | r | | , | | idx=2 <BR>　　 <BR>　　最后的结果相当于r没有入栈。产生这种问题的原因在于对共享数据访问的操作的不完整性。 <BR><BR>　　6．2．1 互斥锁 <BR><BR>　　为解决操作的不完整性问题，在Java 语言中，引入了对象互斥锁的概念，来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记，这个标记用来保证在任一时刻，只能有一个线程访问该对象。 关键字synchronized 来与对象的互斥锁联系。当某个对象用synchronized 修饰时，表明该对象在任一时刻只能由一个线程访问。 <BR><BR>　　　　public void push(char c){ <BR>　　　　synchronized(this){ //this表示Stack的当前对象 <BR>　　　　　　　data[idx]=c; <BR>　　　　　　　idx++; <BR>　　　　} <BR>　　　　} <BR>　　　　public char pop(){ <BR>　　　　　　　synchronized(this){ //this表示Stack的当前对象 <BR>　　　　　　　idx--; <BR>　　　　　　　return data[idx]; <BR>　　　　　　　} <BR>　　　　} <BR><BR><BR><BR>　　synchronized 除了象上面讲的放在对象前面限制一段代码的执行外，还可以放在方法声明中，表示整个方法为同步方法。 <BR>　　public synchronized void push(char c){ <BR>　　… <BR>　　　　} <BR><BR>　　如果synchronized用在类声明中，则表明该类中的所有方法都是synchronized的。 <BR><BR>　　 <BR><BR>　　6．2．2多线程的同步 <BR><BR>　　 本节将讨论如何控制互相交互的线程之间的运行进度,即多线程之间的同步问题,下面我们将通过多线程同步的模型: 生产者-消费者问题来说明怎样实现多线程的同步。 <BR><BR><BR>　我们把系统中使用某类资源的线程称为消费者，产生或释放同类资源的线程称为生产者。 <BR>　　在下面的Java的应用程序中，生产者线程向文件中写数据，消费者从文件中读数据，这样，在这个程序中同时运行的两个线程共享同一个文件资源。通过这个例子我们来了解怎样使它们同步。 <BR><BR><BR>　　例6．5 <BR>　　　class SyncStack{ //同步堆栈类 <BR>　　　private int index = 0; //堆栈指针初始值为0 <BR>　　　private char []buffer = new char[6]; //堆栈有6个字符的空间 <BR><BR>　　　public synchronized void push(char c){ //加上互斥锁 <BR>　　　　　while(index = = buffer.length){ //堆栈已满，不能压栈 <BR>　　　　　try{ <BR>　　　　　　　　this.wait(); //等待，直到有数据出栈 <BR>　　　　　　　}catch(InterruptedException e){} <BR>　　　　　　　} <BR><BR>　　　this.notify(); //通知其它线程把数据出栈 <BR>　　　buffer[index] = c; //数据入栈 <BR>　　　index++; //指针向上移动 <BR>　　　} <BR><BR>　　　public synchronized char pop(){ //加上互斥锁 <BR>　　　　　　　while(index ==0){ //堆栈无数据，不能出栈 <BR>　　　　　　　　try{ <BR>　　　　　　　　　　　this.wait(); //等待其它线程把数据入栈 <BR>　　　　　　　　}catch(InterruptedException e){} <BR>　　　　　　　　　　} <BR><BR>　　　　　　　this.notify(); //通知其它线程入栈 <BR>　　　　　　　index- -; //指针向下移动 <BR>　　　　　　　return buffer[index]; //数据出栈 <BR>　　　　} <BR>　　　　　　　} <BR><BR>　　　　class Producer implements Runnable{ //生产者类 <BR>　　　　　　　SyncStack theStack; <BR>　　　　　　　　//生产者类生成的字母都保存到同步堆栈中 <BR><BR>　　　　　　　public Producer(SyncStack s){ <BR>　　　　　　　　　　theStack = s; <BR>　　　　　　　} <BR><BR>　　　　　　　public void run(){ <BR>　　　　　　　　　　char c; <BR>　　　　　　　　　　for(int i=0; i&lt;20; i++){ <BR>　　　　　　　　　　　　c =(char)(Math.random()*26+'A'); <BR>　　　　　　　　　　　　　　　　　　　　　　　　　　//随机产生20个字符 <BR>　　　　　　　　　　　　theStack.push(c); //把字符入栈 <BR>　　　　　　　　　　　　System.out.println("Produced: "+c); //打印字符 <BR>　　　　　　　　　　　　try{ <BR>　　　　　　　　　　　　Thread.sleep((int)(Math.random()*1000)); <BR>　　　　　　　　　　　　　　　　　　　　　/*每产生一个字符线程就睡眠*/ <BR>　　　　　　　　　　　　}catch(InterruptedException e){} <BR>　　　　　　　　　　} <BR>　　　　　　　} <BR>　　　　　} <BR><BR>　　　　　class Consumer implements Runnable{ //消费者类 <BR>　　　　　　　　　SyncStack theStack; <BR>　　　　　　　　　　　　　　　　　　//消费者类获得的字符都来自同步堆栈 <BR><BR>　　　　　　　　　public Consumer(SyncStack s){ <BR>　　　　　　　　　　　　　theStack = s; <BR>　　　　　　　　　} <BR><BR>　　　　　　　　　public void run(){ <BR>　　　　　　　　　　　　　char c; <BR>　　　　　　　　　　　　　for(int i=0;i&lt;20;i++){ <BR>　　　　　　　　　　　　　　　c = theStack.pop(); //从堆栈中读取字符 <BR>　　　　　　　　　　　　　System.out.println("Consumed: "+c); <BR>　　　　　　　　　　　　　　　　　　　　　　　　　　　　　//打印字符 <BR>　　　　　　　　　　　　　try{ <BR>　　　　　　　　　　　　　Thread.sleep((int)(Math.random()*1000)); <BR>　　　　　　　　　　　　　　　　　　　　/*每读取一个字符线程就睡眠*/ <BR>　　　　　　　　　　　　　}catch(InterruptedException e){} <BR>　　　　　　　　　} <BR>　　　　　　　} <BR>　　　　　} <BR><BR>　　　　　public class SyncTest{ <BR>　　　　　　　public static void main(String args[]){ <BR>　　　　　　　　　SyncStack stack = new SyncStack(); <BR>　　　//下面的消费者类对象和生产者类对象所操作的是同一个同步堆栈对象 <BR>　　　　　　　　　Runnable source=new Producer(stack); <BR>　　　　　　　　　Runnable sink = new Consumer(stack); <BR>　　　　　　　　　Thread t1 = new Thread(source); //线程实例化 <BR>　　　　　　　　　Thread t2 = new Thread(sink); //线程实例化 <BR>　　　　　　　　　t1.start(); //线程启动 <BR>　　　　　　　　　t2.start(); //线程启动 <BR>　　　　　　　} <BR>　　　　　} <BR><BR>　　类Producer是生产者模型，其中的 run()方法中定义了生产者线程所做的操作，循环调用push()方法,将生产的20个字母送入堆栈中，每次执行完push操作后，调用sleep()方法睡眠一段随机时间，以给其他线程执行的机会。类Consumer是消费者模型，循环调用pop()方法,从堆栈中取出一个数据，一共取20次，每次执行完pop操作后，调用sleep()方法睡眠一段随机时间，以给其他线程执行的机会。 <BR><BR>　　程序执行结果 <BR>　　　　　　　　Produced:V <BR>　　　　　　　　Consumed:V <BR>　　　　　　　　Produced:E <BR>　　　　　　　　Consumed:E <BR>　　　　　　　　Produced:P <BR>　　　　　　　　Produced:L <BR>　　　　　　　　... <BR>　　　　　　　　Consumed:L <BR>　　　　　　　　Consumed:P <BR><BR>　　在上述的例子中，通过运用wait()和notify()方法来实现线程的同步，在同步中还会用到notifyAll()方法，一般来说，每个共享对象的互斥锁存在两个队列，一个是锁等待队列，另一个是锁申请队列，锁申请队列中的第一个线程可以对该共享对象进行操作，而锁等待队列中的线程在某些情况下将移入到锁申请队列。下面比较一下wait()、notify()和notifyAll()方法： <BR><BR>　　(1) wait,nofity,notifyAll必须在已经持有锁的情况下执行,所以它们只能出现在synchronized作用的范围内，也就是出现在用　　 　　　　synchronized修饰的方法或类中。 <BR><BR>　　(2) wait的作用:释放已持有的锁,进入等待队列. <BR>　　 <BR>　　(3) notify的作用:唤醒wait队列中的第一个线程并把它移入锁申请队列. <BR><BR>　　(4) notifyAll的作用:唤醒wait队列中的所有的线程并把它们移入锁申请队列. <BR><BR>　　注意： <BR>　　1） suspend()和resume() <BR>　　　　在JDK1.2中不再使用suspend()和resume(),其相应功能由wait()和notify()来实现。 <BR><BR>　　2) stop() <BR>　　　 在JDK1.2中不再使用stop(),而是通过标志位来使程序正常执行完毕。例6.6就是一个典型的例子。 <BR><BR>　　例6．6 <BR>　　　public class Xyz implements Runnable { <BR>　　　　　　private boolean timeToQuit=false; //标志位初始值为假 <BR>　　　　　　public void run() { <BR>　　　　　　　　　while(!timeToQuit) {//只要标志位为假，线程继续运行 <BR>　　　　　　　　　　　　　… <BR>　　　　　　　　　} <BR>　　　　　　} <BR><BR>　　　public void stopRunning() { <BR>　　　　　　　　　timeToQuit=true;} //标志位设为真，表示程序正常结束 <BR>　　　　　　} <BR>　　　public class ControlThread { <BR>　　　　　　private Runnable r=new Xyz(); <BR>　　　　　　private Thread t=new Thread(r); <BR>　　　　　　public void startThread() { <BR>　　　　　　　　　t.start(); <BR>　　　　　　} <BR>　　　　　　public void stopThread() { <BR>　　　　　　　　　r.stopRunning(); } <BR>　　　　　　　　　　　　　　　//通过调用stopRunning方法来终止线程运行 <BR>　　　　　　} <BR><img src ="http://www.blogjava.net/gongtao200118/aggbug/18680.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gongtao200118/" target="_blank">Write Once,Run Anywhere!</a> 2005-11-08 00:56 <a href="http://www.blogjava.net/gongtao200118/archive/2005/11/08/18680.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA教程 第五讲 AWT图形用户界面设计（二）</title><link>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18679.html</link><dc:creator>Write Once,Run Anywhere!</dc:creator><author>Write Once,Run Anywhere!</author><pubDate>Mon, 07 Nov 2005 16:53:00 GMT</pubDate><guid>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18679.html</guid><wfw:comment>http://www.blogjava.net/gongtao200118/comments/18679.html</wfw:comment><comments>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18679.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gongtao200118/comments/commentRss/18679.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gongtao200118/services/trackbacks/18679.html</trackback:ping><description><![CDATA[<DIV id=art_title>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JAVA教程 第五讲 AWT图形用户界面设计（二&nbsp; ）<BR><BR>5.2.1 事件类 <BR><BR>　　与AWT有关的所有事件类都由java.awt.AWTEvent类派生,它也是EventObject类的子类。AWT事件共有10类，可以归为两大类：低级事件和高级事件。 <BR><BR>　　java.util.EventObject类是所有事件对象的基础父类，所有事件都是由它派生出来的。AWT的相关事件继承于java.awt.AWTEvent类，这些AWT事件分为两大类：低级事件和高级事件，低级事件是指基于组件和容器的事件，当一个组件上发生事件，如：鼠标的进入，点击，拖放等，或组件的窗口开关等，触发了组件事件。高级事件是基于语义的事件，它可以不和特定的动作相关联，而依赖于触发此事件的类，如在TextField中按Enter键会触发ActionEvent事件,滑动滚动条会触发AdjustmentEvent事件，或是选中项目列表的某一条就会触发ItemEvent事件。 <BR><BR>　　◇ 低级事件 <BR>　　ComponentEvent（ 组件事件：组件尺寸的变化，移动） <BR>　　ContainerEvent（ 容器事件：组件增加，移动） <BR>　　WindowEvent（ 窗口事件：关闭窗口，窗口闭合，图标化） <BR>　　FocusEvent（ 焦点事件：焦点的获得和丢失） <BR>　　KeyEvent（ 键盘事件：键按下、释放） <BR>　　MouseEvent（ 鼠标事件：鼠标单击，移动） <BR><BR>　　◇ 高级事件（语义事件） <BR>　　ActionEvent（动作事件：按钮按下，TextField中按Enter键） <BR>　　AdjustmentEvent（调节事件：在滚动条上移动滑块以调节数值） <BR>　　ItemEvent（项目事件：选择项目，不选择"项目改变"） <BR>　　TextEvent（文本事件，文本对象改变） <BR><BR>　　5.2.2 事件监听器 <BR><BR>　　每类事件都有对应的事件监听器，监听器是接口，根据动作来定义方法。 <BR><BR>　　例如，与键盘事件KeyEvent相对应的接口是： <BR>　　public interface KeyListener extends EventListener { <BR>　　　　　public void keyPressed(KeyEvent ev); <BR>　　　　　public void keyReleased(KeyEvent ev); <BR>　　　　　public void keyTyped(KeyEvent ev); <BR>　　} <BR><BR>　　注意到在本接口中有三个方法，那么java运行时系统何时调用哪个方法？其实根据这三个方法的方法名就能够知道应该是什么时候调用哪个方法执行了。当键盘刚按下去时，将调用keyPressed( )方法执行，当键盘抬起来时，将调用keyReleased( )方法执行，当键盘敲击一次时，将调用keyTyped( )方法执行。 <BR><BR>　　又例如窗口事件接口： <BR>　　public interface WindowListener extends EventListener{ <BR>　　　　　public void windowClosing(WindowEvent e); <BR>　　　　　//把退出窗口的语句写在本方法中 <BR>　　　　　public void windowOpened(WindowEvent e); <BR>　　　　　//窗口打开时调用 <BR>　　　　　public void windowIconified(WindowEvent e); <BR>　　　　　//窗口图标化时调用 <BR>　　　　　public void windowDeiconified(WindowEvent e); <BR>　　　　　//窗口非图标化时调用 <BR>　　　　　public void windowClosed(WindowEvent e); <BR>　　　　　//窗口关闭时调用 <BR>　　　　　public void windowActivated(WindowEvent e); <BR>　　　　　//窗口激活时调用 <BR>　　　　　public void windowDeactivated(WindowEvent e); <BR>　　　　　//窗口非激活时调用 <BR>　　} <BR><BR>　　AWT的组件类中提供注册和注销监听器的方法： <BR><BR>　　◇ 注册监听器： <BR>　　public void add<LISTENERTYPE> (<LISTENERTYPE>listener); <BR><BR>　　◇ 注销监听器： <BR>　　public void remove<LISTENERTYPE> (<LISTENERTYPE>listener); <BR><BR>　　例如Button类：（查API） <BR>　　public class Button extends Component { <BR>　　　　　…… <BR>　　　　　public synchronized void addActionListener(ActionListener l); <BR>　　　　　public synchronized void removeActionListener(ActionListener l); <BR>　　　　　……} <BR><BR>　　5.2.3 AWT事件及其相应的监听器接口(1) <BR><BR>　　5.2.3 AWT事件及其相应的监听器接口(2) <BR><BR>　　例5.10说明事件处理模型的应用。 <BR><BR>　　例5.10 <BR>　　import java.awt.*; <BR>　　import java.awt.event.*; <BR>　　　　public class ThreeListener implements MouseMotionListener,MouseListener,WindowListener { <BR>　　　　//实现了三个接口 <BR>　　　　private Frame f; <BR>　　　　private TextField tf; <BR>　　　　public static void main(String args[]) <BR>　　　　{ <BR>　　　　　ThreeListener two = new ThreeListener(); <BR>　　　　　two.go(); } <BR><BR>　　　　public void go() { <BR>　　　　f = new Frame("Three listeners example"); <BR>　　　　f.add(new Label("Click and drag the mouse"),"North"); <BR>　　　　tf = new TextField(30); <BR>　　　　f.add(tf,"South"); //使用缺省的布局管理器 <BR>　　　　f.addMouseMotionListener(this); //注册监听器MouseMotionListener <BR>　　　　f.addMouseListener(this); //注册监听器MouseListener <BR>　　　　f.addWindowListener(this); //注册监听器WindowListener <BR>　　　　f.setSize(300,200); <BR>　　　　f.setVisible(true); <BR>　　　　　　} <BR><BR>　　　　public void mouseDragged (MouseEvent e) { <BR>　　　　//实现mouseDragged方法 <BR>　　　　String s = "Mouse dragging : X="+e.getX()+"Y = "+e.getY(); <BR>　　　　tf.setText(s); <BR>　　　　　　} <BR>　　　　public void mouseMoved(MouseEvent e){} <BR>　　　　//对其不感兴趣的方法可以方法体为空 <BR>　　　　public void mouseClicked(MouseEvent e){} <BR>　　　　public void mouseEntered(MouseEvent e){ <BR>　　　　　　String s = "The mouse entered"; <BR>　　　　　　tf.setText(s); <BR>　　　　　　　　} <BR><BR>　　　　public void mouseExited(MouseEvent e){ <BR>　　　　　　String s = "The mouse has left the building"; <BR>　　　　　　tf.setText(s); <BR>　　　　　　　　} <BR><BR>　　　　public void mousePressed(MouseEvent e){} <BR>　　　　public void mouseReleased(MouseEvent e){ } <BR>　　　　public void windowClosing(WindowEvent e) { <BR>　　　　//为了使窗口能正常关闭，程序正常退出，需要实现windowClosing方法 <BR>　　　　　　System.exit(1); <BR>　　　　　　　　} <BR><BR>　　　　public void windowOpened(WindowEvent e) {} <BR>　　　　//对其不感兴趣的方法可以方法体为空 <BR>　　　　public void windowIconified(WindowEvent e) {} <BR>　　　　public void windowDeiconified(WindowEvent e) {} <BR>　　　　public void windowClosed(WindowEvent e) {} <BR>　　　　public void windowActivated(WindowEvent e) { } <BR>　　　　public void windowDeactivated(WindowEvent e) {} <BR><BR>　　　　} <BR><BR>　　上例中有如下几个特点： <BR>　　1．可以声明多个接口，接口之间用逗号隔开。 <BR>　　　　……implements MouseMotionListener, MouseListener, WindowListener； <BR>　　 <BR>　　2．可以由同一个对象监听一个事件源上发生的多种事件： <BR>　　f.addMouseMotionListener(this); <BR>　　f.addMouseListener(this); <BR>　　f.addWindowListener(this); <BR>　　则对象f 上发生的多个事件都将被同一个监听器接收和处理。 <BR><BR>　　3．事件处理者和事件源处在同一个类中。本例中事件源是Frame f，事件处理者是类ThreeListener，其中事件源Frame f是类ThreeListener的成员变量。 <BR><BR>　　4．可以通过事件对象获得详细资料，比如本例中就通过事件对象获得了鼠标发生时的坐标值。 <BR>　　public void mouseDragged(MouseEvent e) { <BR>　　　String s="Mouse dragging :X="+e.getX()+"Y="+e.getY(); <BR>　　　tf.setText(s); <BR>　　} <BR><BR>　　Java语言类的层次非常分明，因而只支持单继承，为了实现多重继承的能力，Java用接口来实现，一个类可以实现多个接口，这种机制比多重继承具有更简单、灵活、更强的功能。在AWT中就经常用到声明和实现多个接口。记住无论实现了几个接口，接口中已定义的方法必须一一实现，如果对某事件不感兴趣，可以不具体实现其方法，而用空的方法体来代替。但却必须所有方法都要写上。 <BR><BR>　　5.2.4 事件适配器 <BR><BR>　　Java语言为一些Listener接口提供了适配器(Adapter)类。可以通过继承事件所对应的Adapter类，重写需要方法，无关方法不用实现。事件适配器为我们提供了一种简单的实现监听器的手段, 可以缩短程序代码。但是，由于java的单一继承机制，当需要多种监听器或此类已有父类时，就无法采用事件适配器了。 <BR><BR>　　1．事件适配器--EventAdapter <BR><BR>　　下例中采用了鼠标适配器： <BR>　　import java.awt.*; <BR>　　import java.awt.event.*; <BR>　　public class MouseClickHandler extends MouseAdaper{ <BR>　　　　public void mouseClicked(MouseEvent e) //只实现需要的方法 <BR>　　　　　　　{ ……} <BR>　　} <BR><BR>　　java.awt.event包中定义的事件适配器类包括以下几个： <BR>　　1．ComponentAdapter( 组件适配器) <BR>　　2．ContainerAdapter( 容器适配器) <BR>　　3．FocusAdapter( 焦点适配器) <BR>　　4．KeyAdapter( 键盘适配器) <BR>　　5．MouseAdapter( 鼠标适配器) <BR>　　6．MouseMotionAdapter( 鼠标运动适配器) <BR>　　7．WindowAdapter( 窗口适配器) <BR><BR>　　2. 用内部类实现事件处理 <BR><BR>　　内部类（inner class）是被定义于另一个类中的类，使用内部类的主要原因是由于： <BR>　　◇ 一个内部类的对象可访问外部类的成员方法和变量，包括私有的成员。 <BR>　　◇ 实现事件监听器时，采用内部类、匿名类编程非常容易实现其功能。 <BR>　　◇ 编写事件驱动程序，内部类很方便。　　 <BR>　　因此内部类所能够应用的地方往往是在AWT的事件处理机制中。 <BR><BR>　　例5.11 <BR>　　　import java.awt.* ; <BR>　　　import java.awt.event.*； <BR>　　　　　public class InnerClass{ <BR>　　　　　　　private Frame f; <BR>　　　　　　　private TextField tf; <BR>　　　　　　　public InnerClass(){ <BR>　　　　　　　f=new Frame("Inner classes example"); <BR>　　　　　　　tf=new TextField(30); <BR>　　　　　} <BR><BR>　　　　　public voidi launchFrame(){ <BR>　　　　　　　Label label=new Label("Click and drag the mouse"); <BR>　　　　　　　f.add(label,BorderLayout.NORTH); <BR>　　　　　　　f.add(tf,BorderLayout.SOUTH); <BR>　　　　　　　f.addMouseMotionListener(new MyMouseMotionListener());/*参数为内部类对象*/ <BR>　　　　　　　f.setSize(300,200); <BR>　　　　　　　f.setVisible(true); <BR>　　　　　} <BR><BR>　　　　　class MyMouseMotionListener extends MouseMotionAdapter{ /*内部类开始*/ <BR>　　　　　　　public void mouseDragged(MouseEvent e) { <BR>　　　　　　　　　String s="Mouse dragging: x="+e.getX()+"Y="+e.getY(); <BR>　　　　　　　　　tf.setText(s); } <BR>　　　　　　　} ; <BR><BR>　　　　　　　public static void main(String args[]) { <BR>　　　　　　　　　InnerClass obj=new InnerClass(); <BR>　　　　　　　　　obj.launchFrame(); <BR>　　　　　　　} <BR>　　　　　}//内部类结束 <BR>　　　　} <BR><BR>　3．匿名类（Anonymous Class） <BR><BR>　　当一个内部类的类声名只是在创建此类对象时用了一次，而且要产生的新类需继承于一个已有的父类或实现一个接口，才能考虑用匿名类，由于匿名类本身无名，因此它也就不存在构造方法，它需要显示地调用一个无参的父类的构造方法，并且重写父类的方法。所谓的匿名就是该类连名字都没有，只是显示地调用一个无参的父类的构造方法。 <BR><BR>　　例5.12 <BR>　　　import java.awt.* ; <BR>　　　import java.awt.event.*; <BR>　　　　public class AnonymousClass{ <BR>　　　　　private Frame f; <BR>　　　　　private TextField tf; <BR>　　　　　public AnonymousClass(){ <BR>　　　　　　f=new Frame("Inner classes example"); <BR>　　　　　　tf=new TextField(30); <BR>　　　　} <BR>　　　　public void launchFrame(){ <BR>　　　　　　Label label=new Label("Click and drag the mouse"); <BR>　　　　　　f.add(label,BorderLayout.NORTH); <BR>　　　　　　f.add(tf,BorderLayout.SOUTH); <BR>　　　　　　f.addMouseMotionListener(new MouseMotionAdapter(){ //匿名类开始 <BR>　　　　　　　public void mouseDragged(MouseEvent e){ <BR>　　　　　　　　String s="Mouse dragging: x="+e.getX()+"Y="+e.getY(); <BR>　　　　　　　　tf.setText(s); } <BR>　　　　　　} ); //匿名类结束 <BR>　　　　　　f.setSize(300,200); <BR>　　　　　　f.setVisible(true); <BR>　　　　　　} <BR>　　　　　　　public static void main(String args[]) { <BR>　　　　　　　　AnonymousClass obj=new AnonymousClass(); <BR>　　　　　　　　obj.launchFrame(); <BR>　　　　　　　　} <BR>　　　　　　} <BR><BR>　　其实大家仔细分析一下，例5.11和5.12实现的都是完全一样的功能，只不过采取的方式不同。5.11中的事件处理类是一个内部类，而5.12的事件处理类是匿名类，可以说从类的关系来说是越来越不清楚，但是程序也越来越简练。熟悉这两种方式也十分有助于大家编写图形界面的程序。 <BR><BR>　　5.3 AWT组件库(1) <BR><BR>　　本节从应用的角度进一步介绍AWT的一些组件，目的使大家加深对AWT的理解，掌握如何用各种组件构造图形化用户界面，学会控制组件的颜色和字体。下面是一些常用的组件的介绍： <BR><BR>　　1． 按钮(Button) <BR><BR>　　按钮是最常用的一个组件，其构造方法是：Button b = new Button("Quit"); <BR>　　当按钮被点击后，会产生ActionEvent事件，需ActionListener接口进行监听和处理事件。 <BR>　　ActionEvent的对象调用getActionCommand()方法可以得到按钮的标识名，缺省按钮名为label。 <BR>　　用setActionCommand()可以为按钮设置组件标识符。 <BR><BR>　　2.复选框 (Checkbox) <BR><BR>　　复选框提供简单的"on/off"开关，旁边显示文本标签。 <BR>　　 <BR>　　构造方法如下： <BR>　　setLayout(new GridLayout(3,1)); <BR>　　add(new Checkbox("one",null,true)); <BR>　　add(new Checkbox("two")); <BR>　　add(new Checkbox("three")); <BR>　　复选框用ItemListener 来监听ItemEvent事件，当复选框状态改变时用getStateChange()获取当前状态。使用getItem()获得被修改复选框的字符串对象。 <BR><BR>　　例5.13 <BR>　　　class Handler implements ItemListener { <BR>　　　　　public void itemStateChanged(ItemEvent ev){ <BR>　　　　　　　String state = "deselected"; <BR>　　　　　　　if (ev.getStateChange() = = ItemEvent.SELECTED){ <BR>　　　　　　　　　state = "selected" <BR>　　　　　　　} <BR>　　　　　System.out.println(ev.getItem()+" "+state); <BR>　　　　　} <BR>　　　} <BR><BR><BR>　　3.复选框组(CheckboxGroup) <BR><BR>　　使用复选框组，可以实现单选框的功能。方法如下： <BR>　　setLayout(new GridLayout(3, 1)); <BR>　　CheckboxGroup cbg = new CheckboxGroup(); <BR>　　add(new Checkbox("one", cbg, true)); <BR>　　add(new Checkbox("two", cbg, false)); <BR>　　add(new Checkbox("three", cbg, false)); <BR><BR>　　5.3 AWT组件库(2) <BR><BR>　　4. 下拉式菜单（Choice） <BR><BR>　　下拉式菜单每次只能选择其中的一项，它能够节省显示空间，适用于大量选项。 <BR>　　Choice Colorchooser=new Choice(); <BR>　　Colorchooser.add("Green"); <BR>　　Colorchooser.add("Red"); <BR>　　Colorchooser.add("Blue"); <BR>　　Choice 用ItemListener接口来进行监听 <BR><BR>　　5. Canvas <BR><BR>　　一个应用程序必须继承Canvas类才能获得有用的功能，比如创建一个自定义组件。如果想在画布上完成一些图形处理，则Canvas类中的paint（）方法必须被重写。 <BR>　　Canvas组件监听各种鼠标，键盘事件。当在Canvas组件中输入字符时，必须先调用requestFocus()方法。 <BR><BR>　　例5.14 <BR>　　　import java.awt.*; <BR>　　　import java.awt.event.*; <BR>　　　import java.util.*; <BR>　　　public class MyCanvas implements KeyListener, MouseListener { <BR>　　　　Canvas c; //声明一个画布对象 <BR>　　　　String s　=""; <BR>　　　　public static void main(String args[]) { <BR>　　　　　Frame f=new Frame("Canvas"); <BR>　　　　　MyCanvas mc=new MyCanvas(); <BR>　　　　　mc.c=new Canvas(); <BR>　　　　　f.add("Center",mc.c); <BR><BR>　　　　　f.setSize(150,150); <BR>　　　　　mc.c.addMouseListener(mc); //注册监听器 <BR>　　　　　mc.c.addKeyListener(mc); //注册监听器 <BR>　　　　　f.setVisible(true); <BR>　　　　} <BR><BR>　　　　public void mouseClicked(MouseEvent ev){ <BR>　　　　　System.out.println("MouseClicked"); <BR>　　　　　c.requestFocus();//获得焦点，表示该窗口将接收用户的键盘和鼠标输入 <BR>　　　　} <BR><BR>　　　　public void keyTyped(KeyEvent ev) { <BR>　　　　　System.out.println("KeyTyped"); <BR>　　　　　s+=ev.getKeyChar(); //获取每个输入的字符，依次添加到字符串s中 <BR>　　　　　c.getGraphics().drawString(s,0,20); //显示字符串s <BR>　　　　} <BR><BR>　　　　public void keyPressed(KeyEvent ev) { System.out.println("KeyPressed"); } <BR>　　　　public void keyReleased(KeyEvent ev) { System.out.println("KeyReleased"); } <BR>　　　　public void mousePressed(MouseEvent ev) {System.out.println("MousePressed"); } <BR>　　　　public void mouseReleased(MouseEvent ev) {System.out.println("MouseReleased"); } <BR>　　　　public void mouseEntered(MouseEvent ev) {System.out.println("MouseEntered"); } <BR>　　　　public void mouseExited(MouseEvent ev) {System.out.println("MouseExited"); } <BR>　　　　} <BR><BR>　　6. 单行文本输入区(TextField) <BR><BR>　　只能显示一行，当回车键被按下时，会发生ActionEvent事件，可以通过ActionListener中的actionPerformed()方法对事件进行相应处理。可以使用setEditable(boolean)方法设置为只读属性。 <BR><BR>　　单行文本输入区构造方法如下： <BR>　　TextField tf1,tf2,tf3,tf4: <BR>　　tf1=new TextField(); <BR>　　tf2=new TextField("",20); //显示区域为20列 <BR>　　tf3=new TextField("Hello!"); //按文本区域大小显示 <BR>　　tf4=new TextField("Hello!",30); //初始文本为Hello!, 显示区域为30列 <BR><BR>　　5.3 AWT组件库(3) <BR><BR>　　7. 文本输入区（TextArea） <BR><BR>　　TextArea可以显示多行多列的文本。使用setEditable(boolean)方法，可以将其设置为只读的。在TextArea中可以显示水平或垂直的滚动条。 <BR>　　要判断文本是否输入完毕，可以在TextArea旁边设置一个按钮，通过按钮点击产生的ActionEvent对输入的文本进行处理。 <BR><BR>　　8. 列表(List) <BR><BR>　　列表中提供了多个文本选项，列表支持滚动条，可以浏览多项 <BR>　　List lst=new List(4,false); //两个参数分别表示显示的行数、是否允许多选 <BR>　　lst.add("Venus"); <BR>　　lst.add("Earth"); <BR>　　lst.add("JavaSoft"); <BR>　　lst.add("Mars"); <BR>　　cnt.add(lst); <BR><BR>　　9. 框架（Frame） <BR><BR>　　Frame是顶级窗口，可以显示标题，重置大小。当Frame被关闭，将产生WindowEvent事件，Frame无法直接监听键盘输入事件。 <BR><BR>　　10. 对话框（Dialog） <BR><BR>　　它是Window类的子类。对话框和一般窗口的区别在于它依赖于其它窗口。对话框分为非模式（non-modal）和模式（modal）两种。 <BR><BR>　　11. 文件对话框(Filedialog) <BR><BR>　　当用户想打开或存储文件时，使用文件对话框进行操作。主要代码如下： <BR>　　FileDialog d=new FileDialog(ParentFr,"FileDialog"); <BR>　　d.setVisible(true); <BR>　　String filename=d.getFile(); <BR><BR>　　12. 菜单（Menu） <BR><BR>　　无法直接将菜单添加到容器的某一位置，也无法使用布局管理器对其加以控制。菜单只能被添加?quot;菜单容器"（MenuBar）中。 <BR><BR>　　13. MenuBar <BR><BR>　　只能被添加到Frame对象中，作为整个菜单树的根基。 <BR>　　Frame fr = new Frame("MenuBar"); <BR>　　MenuBar mb = new MenuBar(); <BR>　　fr.setMenuBar(mb); <BR>　　fr.setSize(150,100); <BR>　　fr.setVisible(true); <BR><BR>　　14. Menu <BR><BR>　　下拉菜单。它可以被添加到MenuBar中或其它Menu中。 <BR>　　Frame fr = new Frame("MenuBar"); <BR>　　MenuBar mb = new MenuBar(); <BR>　　fr.setMenuBar(mb); <BR>　　Menu m1 = new Menu("File"); <BR>　　Menu m2 = new Menu("Edit"); <BR>　　Menu m3 = new Menu("Help"); <BR>　　mb.add(m1); <BR>　　mb.add(m2); <BR>　　mb.setHelpMenu(m3); <BR>　　fr.setSize(200,200); <BR>　　fr.setVisible(true); <BR><BR>　　15. MenuItem <BR><BR>　　MenuItem是菜单树中的"叶子节点"。MenuItem通常被添加到一个Menu中。对于MenuItem对象可以添加ActionListener，使其能够完成相应的操作。 <BR>　　Menu m1 = new Menu("File"); <BR>　　MenuItem mi1 = new MenuItem("Save"); <BR>　　MenuItem mi2 = new MenuItem("Load"); <BR>　　MenuItem mi3 = new MenuItem("Quit"); <BR><BR>　　m1.add(mi1); <BR>　　m1.add(mi2); <BR>　　m1.addSeparator(); <BR>　　m1.add(mi3); <BR><BR>　　MenuBar和Menu都没有必要注册监听器，只需要对MenuItem添加监听器ActionListener，完成相应操作。 <BR><BR><BR></DIV><img src ="http://www.blogjava.net/gongtao200118/aggbug/18679.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gongtao200118/" target="_blank">Write Once,Run Anywhere!</a> 2005-11-08 00:53 <a href="http://www.blogjava.net/gongtao200118/archive/2005/11/08/18679.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA教程 第五讲 AWT图形用户界面设计（一）</title><link>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18677.html</link><dc:creator>Write Once,Run Anywhere!</dc:creator><author>Write Once,Run Anywhere!</author><pubDate>Mon, 07 Nov 2005 16:50:00 GMT</pubDate><guid>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18677.html</guid><wfw:comment>http://www.blogjava.net/gongtao200118/comments/18677.html</wfw:comment><comments>http://www.blogjava.net/gongtao200118/archive/2005/11/08/18677.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gongtao200118/comments/commentRss/18677.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gongtao200118/services/trackbacks/18677.html</trackback:ping><description><![CDATA[<P align=left>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JAVA教程 第五讲 AWT图形用户界面设计（一）<BR><BR>　5.1 用AWT生成图形化用户界面 <BR><BR>　　 抽象窗口工具包AWT (Abstract Window Toolkit) 是 API为Java 程序提供的建立图形用户界面GUI (Graphics User Interface)工具集，AWT可用于Java的applet和applications中。它支持图形用户界面编程的功能包括： 用户界面组件；事件处理模型；图形和图像工具，包括形状、颜色和字体类；布局管理器，可以进行灵活的窗口布局而与特定窗口的尺寸和屏幕分辨率无关；数据传送类，可以通过本地平台的剪贴板来进行剪切和粘贴。 <BR><BR>　　5.1.1 java.awt包 <BR>　　 <BR>　　java.awt包中提供了GUI设计所使用的类和接口，可从图5.1中看到主要类之间的关系。 <BR><BR>　　 java.awt包提供了基本的java程序的GUI设计工具。主要包括下述三个概念： <BR><BR>　　组件--Component <BR>　　容器--Container <BR>　　布局管理器--LayoutManager <BR><BR>　　5.1.2 组件和容器 <BR><BR>　　Java的图形用户界面的最基本组成部分是组件（Component），组件是一个可以以图形化的方式显示在屏幕上并能与用户进行交互的对象，例如一个按钮，一个标签等。组件不能独立地显示出来，必须将组件放在一定的容器中才可以显示出来。 <BR><BR>　　类java.awt.Component是许多组件类的父类，Component类中封装了组件通用的方法和属性，如图形的组件对象、大小、显示位置、前景色和背景色、边界、可见性等，因此许多组件类也就继承了Component类的成员方法和成员变量，相应的成员方法包括： <BR><BR>　　　getComponentAt(int x, int y) <BR>　　　getFont() <BR>　　　getForeground() <BR>　　　getName() <BR>　　　getSize() <BR>　　　paint(Graphics g) <BR>　　　repaint() <BR>　　　update() <BR>　　　setVisible(boolean b) <BR>　　　setSize(Dimension d) <BR>　　　setName(String name)等 <BR>　　 <BR>　　容器(Container)也是一个类，实际上是Component的子类，因此容器本身也是一个组件，具有组件的所有性质，但是它的主要功能是容纳其它组件和容器。 <BR><BR>　　布局管理器（LayoutManager）：每个容器都有一个布局管理器，当容器需要对某个组件进行定位或判断其大小尺寸时，就会调用其对应的布局管理器。 <BR><BR>　　为了使我们生成的图形用户界面具有良好的平台无关性，Java语言中，提供了布局管理器这个工具来管理组件在容器中的布局，而不使用直接设置组件位置和大小的方式。 <BR><BR>　　在程序中安排组件的位置和大小时，应该注意以下两点： <BR>　　1．容器中的布局管理器负责各个组件的大小和位置，因此用户无法在这种情况下设置组件的这些属性。如果试图使用Java 语言提供的setLocation()，setSize()，setBounds() 等方法，则都会被布局管理器覆盖。 <BR><BR><BR>　　2．如果用户确实需要亲自设置组件大小或位置，则应取消该容器的布局管理器，方法为： <BR>　　　setLayout(null)； <BR><BR>　　5.1.3 常用容器 <BR><BR>　　容器java.awt.Container是Component的子类，一个容器可以容纳多个组件，并使它们成为一个整体。容器可以简化图形化界面的设计，以整体结构来布置界面。所有的容器都可以通过add()方法向容器中添加组件。 <BR><BR>　　有三种类型的容器：Window、Panel、ScrollPane，常用的有Panel, Frame, Applet。 <BR><BR>　　1．Frame <BR><BR>　　 <BR><BR>　　以下是容器的例子： <BR><BR>　　例5．1 <BR>　　import java.awt.*; <BR>　　public class MyFrame extends Frame{ <BR>　　public static void main(String args[ ]){ <BR>　　　　　　　　MyFrame fr = new MyFrame("Hello Out There!"); <BR>　　　　　　　　　　　　　　　　　　　　　　　//构造方法 <BR>　　　　　　　　fr.setSize(200,200); <BR>　　　　　　　　　　　　　　　　//设置Frame的大小，缺省为（0，0） <BR>　　　　　　　　fr.setBackground(Color.red); <BR>　　　　　　　　　　　　　　　　//设置Frame的背景，缺省为红色 <BR>　　　　　　　　fr.setVisible(true); <BR>　　　　　　　　　　　　　　　　//设置Frame为可见，缺省为不可见 <BR>　　} <BR>　　　　　public MyFrame (String str){ <BR>　　　　　　　　super(str); //调用父类的构造方法 <BR>　　　　　} <BR>　　} <BR><BR>　　一般我们要生成一个窗口，通常是用Window的子类Frame来进行实例化，而不是直接用到Window类。Frame的外观就像我们平常在windows系统下见到的窗口，有标题、边框、菜单、大小等等。每个Frame的对象实例化以后，都是没有大小和不可见的，因此必须调用setSize( )来设置大小，调用setVisible(true)来设置该窗口为可见的。 <BR><BR>　　另外，AWT在实际的运行过程中是调用所在平台的图形系统，因此同样一段AWT程序在不同的<A class=blue href="http://www.it.com.cn/edu/systeminfo/" target=_blank>操作系统</A>平台下运行所看到的图形系统是不一样的。例如在windows下运行，则显示的窗口是windows风格的窗口；而在UNIX下运行时，则显示的是UNIX风格的窗口。 <BR><BR>　　2. Panel <BR><BR>　　 <BR><BR>　　例5．2 <BR>　　import java.awt.*; <BR>　　public class FrameWithPanel extends Frame{ <BR>　　public FrameWithPanel(String str){ <BR>　　　　　　　　super(str); <BR>　　　　　 } <BR><BR>　　　　　 public static void main(String args[]){ <BR>　　　　　　　　FrameWithPanel fr = new FrameWithPanel("Frame with Panel"); <BR>　　　　　　　　Panel pan=new Panel(); <BR>　　　　　　　　fr.setSize(200,200); <BR>　　　　　　　　fr.setBackground(Color.red); <BR>　　　　　　　　　　　　　　　//框架fr的背景颜色设置为红色 <BR>　　　　　　　　fr.setLayout(null); <BR>　　　　　　　　　　　　　　　//取消布局管理器 <BR>　　　　　　　　pan.setSize(100,100); <BR>　　　　　　　　pan.setBackground(Color.yellow); <BR>　　　　　　　　　　　　　　　//设置面板pan的背景颜色为黄色 <BR>　　　　　　　　fr.add(pan); //用add方法把面板pan添加到框架fr中 <BR>　　　　　　　　fr.setVisible(true); <BR>　　　　　　　　} <BR>　　 } <BR><BR>　　一般我们要生成一个窗口，通常是用Window的子类Frame来进行实例化，而不是直接用到Window类。Frame的外观就像我们平常在windows系统下见到的窗口，有标题、边框、菜单、大小等等。每个Frame的对象实例化以后，都是没有大小和不可见的，因此必须调用setSize( )来设置大小，调用setVisible(true)来设置该窗口为可见的。 <BR><BR>　　另外，AWT在实际的运行过程中是调用所在平台的图形系统，因此同样一段AWT程序在不同的操作系统平台下运行所看到的图形系统是不一样的。例如在windows下运行，则显示的窗口是windows风格的窗口；而在UNIX下运行时，则显示的是UNIX风格的窗口。 <BR>　5.1.4 LayoutManager 布局管理器(1) <BR><BR>　　java为了实现跨平台的特性并且获得动态的布局效果，java将容器内的所有组件安排给一个"布局管理器"负责管理，如：排列顺序，组件的大小、位置，当窗口移动或调整大小后组件如何变化等功能授权给对应的容器布局管理器来管理，不同的布局管理器使用不同算法和策略，容器可以通过选择不同的布局管理器来决定布局。 <BR><BR>　　 布局管理器主要包括：FlowLayout，BorderLayout，GridLayout，CardLayout，GridBagLayout <BR><BR>　　例5．3 <BR>　　　　import java.awt.*; <BR>　　　　public class ExGui{ <BR>　　　　　　　　private Frame f; <BR>　　　　　　　　private Button b1; <BR>　　　　　　　　private Button b2; <BR>　　　　　　　　public static void main(String args[]){ <BR>　　　　　　　　　　　　ExGui that = new ExGui(); <BR>　　　　　　　　　　　　that.go(); <BR>　　　　} <BR><BR>　　　　　　　　public void go(){ <BR>　　　　　　　　　　　　f = new Frame("GUI example"); <BR>　　　　　　　　　　　　f.setLayout(new FlowLayout()); <BR>　　　　　　　　　　　　//设置布局管理器为FlowLayout <BR>　　　　　　　　　　　　b1 = new Button("Press Me"); <BR>　　　　　　　　　　　　//按钮上显示字符"Press Me" <BR>　　　　　　　　　　　　b2 = new Button("Don't Press Me"); <BR>　　　　　　　　　　　　f.add(b1); <BR>　　　　　　　　　　　　f.add(b2); <BR>　　　　　　　　　　　　f.pack(); <BR>　　　　　　　　　　　　//紧凑排列，其作用相当于setSize()，即让窗口 <BR>　　　　　　　　　　　　尽量小，小到刚刚能够包容住b1、b2两个按钮 <BR>　　　　　　　　　　　　f.setVisible(true); <BR>　　　　　　　　} <BR>　　　　} <BR><BR>　　1. FlowLayout <BR><BR>　　FlowLayout 是Panel，Applet的缺省布局管理器。其组件的放置规律是从上到下、从左到右进行放置，如果容器足够宽，第一个组件先添加到容器中第一行的最左边，后续的组件依次添加到上一个组件的右边，如果当前行已放置不下该组件，则放置到下一行的最左边。 <BR><BR>　　构造方法主要下面几种： <BR>　　FlowLayout(FlowLayout.RIGHT,20,40); <BR>　　/*第一个参数表示组件的对齐方式，指组件在这一行中的位置是居中对齐、居右对齐还是居左对齐，第二个参数是组件之间的横向间隔，第三个参数是组件之间的纵向间隔，单位是象素。*/ <BR>　　FlowLayout(FlowLayout.LEFT); <BR>　　//居左对齐，横向间隔和纵向间隔都是缺省值5个象素 <BR>　　FlowLayout(); <BR>　　//缺省的对齐方式居中对齐，横向间隔和纵向间隔都是缺省值5个象素 <BR><BR>　　例5．4 <BR>　　　　import java.awt.*; <BR>　　　　public class myButtons{ <BR>　　　　　public static void main(String args[]) <BR>　　　　　{ <BR>　　　　　　　　Frame f = new Frame(); <BR>　　　　　　　　f.setLayout(new FlowLayout()); <BR>　　　　　　　　Button button1 = new Button("Ok"); <BR>　　　　　　　　Button button2 = new Button("Open"); <BR>　　　　　　　　Button button3 = new Button("Close"); <BR>　　　　　　　　f.add(button1); <BR>　　　　　　　　f.add(button2); <BR>　　　　　　　　f.add(button3); <BR>　　　　　　　　f.setSize(300,100); <BR>　　　　　　　　f.setVisible(true); <BR>　　　　　} <BR>　　　　} <BR><BR>　　当容器的大小发生变化时，用FlowLayout管理的组件会发生变化，其变化规律是：组件的大小不变，但是相对位置会发生变化。例如上图中有三个按钮都处于同一行，但是如果把该窗口变窄，窄到刚好能够放下一个按钮，则第二个按钮将折到第二行，第三个按钮将折到第三行。按钮"Open"本来在按钮"OK"的右边，但是现在跑到了下面，所以说"组件的大小不变，但是相对位置会发生变化"。 <BR><BR>　　2. BorderLayout <BR><BR>　　BorderLayout 是Window，Frame和Dialog的缺省布局管理器。BorderLayout布局管理器把容器分成5个区域：North，South，East，West和Center，每个区域只能放置一个组件。 <BR><BR>　　例5．5 <BR>　　　　import java.awt.*; <BR>　　　　public class buttonDir{ <BR>　　　　　public static void main(String args[]){ <BR>　　　　　　Frame f = new Frame("BorderLayout"); <BR>　　　　　　f.setLayout(new BorderLayout()); <BR>　　　　　　f.add("North", new Button("North")); <BR>　　　　　　//第一个参数表示把按钮添加到容器的North区域 <BR>　　　　　　f.add("South", new Button("South")); <BR>　　　　　　//第一个参数表示把按钮添加到容器的South区域 <BR>　　　　　　f.add("East", new Button("East")); <BR>　　　　　　//第一个参数表示把按钮添加到容器的East区域 <BR>　　　　　　f.add("West", new Button("West")); <BR>　　　　　　//第一个参数表示把按钮添加到容器的West区域 <BR>　　　　　　f.add("Center", new Button("Center")); <BR>　　　　　　//第一个参数表示把按钮添加到容器的Center区域 <BR>　　　　　　f.setSize(200,200); <BR>　　　　　　f.setVisible(true); <BR>　　　　　} <BR>　　　　} <BR><BR>　　在使用BorderLayout的时候，如果容器的大小发生变化，其变化规律为：组件的相对位置不变，大小发生变化。例如容器变高了，则North、South区域不变，West、Center、East区域变高；如果容器变宽了，West、East区域不变，North、Center、South区域变宽。不一定所有的区域都有组件，如果四周的区域（West、East、North、South区域）没有组件，则由Center区域去补充，但是如果Center区域没有组件，则保持空白。 <BR><BR>　　3. GridLayout <BR><BR>　　使容器中各个组件呈网格状布局，平均占据容器的空间。 <BR><BR>　　例5．6 <BR>　　　　import java.awt.*; <BR>　　　　public class ButtonGrid { <BR>　　　　public static void main(String args[]) { <BR>　　　　　　Frame f = new Frame("GridLayout"); <BR>　　　　　　f.setLayout(new GridLayout(3,2)); <BR>　　　　　　　　　　　　　　　　 //容器平均分成3行2列共6格 <BR>　　　　　　f.add(new Button("1")); //添加到第一行的第一格 <BR>　　　　　　f.add(new Button("2")); //添加到第一行的下一格 <BR>　　　　　　f.add(new Button("3")); //添加到第二行的第一格 <BR>　　　　　　f.add(new Button("4")); //添加到第二行的下一格 <BR>　　　　　　f.add(new Button("5")); //添加到第三行的第一格 <BR>　　　　　　f.add(new Button("6")); //添加到第三行的下一格 <BR>　　　　　　f.setSize(200,200); <BR>　　　　　　f.setVisible(true); <BR>　　　　} <BR>　　　　} <BR>5.1.4 LayoutManager 布局管理器(2) <BR><BR>　　 4. CardLayout <BR><BR>　　CardLayout布局管理器能够帮助用户处理两个以至更多的成员共享同一显示空间，它把容器分成许多层，每层的显示空间占据整个容器的大小，但是每层只允许放置一个组件，当然每层都可以利用Panel来实现复杂的用户界面。牌布局管理器（CardLayout）就象一副叠得整整齐齐的扑克牌一样，有54张牌，但是你只能看见最上面的一张牌，每一张牌就相当于牌布局管理器中的每一层。 <BR><BR>　　例5．7 <BR>　　import java.awt.*; <BR>　　import java.awt.event.*; //事件处理机制，下一节的内容 <BR>　　public class ThreePages implements MousListener { <BR>　　　　CardLayout layout=new CardLayout(); //实例化一个牌布局管理器对象 <BR>　　　　Frame f=new Frame("CardLayout"); <BR>　　　　Button page1Button; <BR>　　　　Label page2Label; //Label是标签，实际上是一行字符串 <BR>　　　　TextArea page3Text; //多行多列的文本区域 <BR>　　　　Button page3Top; <BR>　　　　Button page3Bottom; <BR><BR>　　public static void main(String args[]) <BR>　　{ new ThreePages().go(); } <BR><BR>　　Public void go() <BR>　　{ 　　f.setLayout(layout); //设置为牌布局管理器layout <BR>　　　　f.add(page1Button=new Button("Button page"),"page1Button"); /*第二个参数"page1Button"表示的是你对这层牌所取的名字*/ <BR>　　　　page1Button.addMouseListener(this); //注册监听器 <BR>　　　　f.add(page2Label=new Label("Label page"),"page2Label"); <BR>　　　　page2Label.addMouseLisener(this); //注册监听器 <BR>　　　　Panel panel=new Panel(); <BR>　　　　panel.setLayout(new BorderLayout()); <BR>　　　　panel.add(page3Text=new TextArea("Composite page"),"Center"); <BR>　　　　page3Text.addMouseListener(this); <BR>　　　　panel.add(page3Top=new Button("Top button") , "North"); <BR>　　　　page3Top.addMouseListener(this); <BR>　　　　panel.add(page3Bottom=new Button("Bottom button") ,"South"); <BR>　　　　page3Bottom.addMouseListener(this); <BR>　　　　f.add(panel,"panel"); <BR>　　　　f.setSize(200,200); <BR>　　　　f.setVisible(true); <BR>　　} <BR>　　…… <BR>　　} <BR><BR>　　5．容器的嵌套 <BR><BR>　　在复杂的图形用户界面设计中，为了使布局更加易于管理，具有简洁的整体风格，一个包含了多个组件的容器本身也可以作为一个组件加到另一个容器中去，容器中再添加容器，这样就形成了容器的嵌套。下面是一个容器嵌套的例子。 <BR><BR>　　例5．8 <BR>　　　　import java.awt.*; <BR>　　　　public class ExGui3{ <BR>　　　　private Frame f; <BR>　　　　private Panel p; <BR>　　　　private Button bw,bc; <BR>　　　　private Button bfile,bhelp; <BR>　　　　　　　public static void main(String args[]) <BR>　　　　　　　{ <BR>　　　　　　　　　ExGui3 gui = new ExGui3(); <BR>　　　　　　　　　gui.go(); <BR>　　　　　　　} <BR><BR>　　　　public void go(){ <BR>　　　　　　　f = new Frame("GUI example 3"); <BR>　　　　　　　bw=new Button("West"); <BR>　　　　　　　bc=new Button("Work space region"); <BR>　　　　　　　f.add(bw,"West"); <BR>　　　　　　　f.add(bc,"Center"); <BR>　　　　　　　p = new Panel(); <BR>　　　　　　　f.add(p,"North"); <BR>　　　　　　　bfile= new Button("File"); <BR>　　　　　　　bhelp= new Button("Help"); <BR>　　　　　　　p.add(bfile); <BR>　　　　　　　p.add(bhelp); <BR>　　　　　　　f.pack(); <BR>　　　　　　　f.setVisible(true); <BR>　　　　} <BR>　　　　} <BR><BR>　　小 结： <BR><BR>　　　1．Frame是一个顶级窗口。Frame的缺省布局管理器为BorderLayout。 <BR><BR>　　　2．Panel 无法单独显示，必须添加到某个容器中。 Panel 的缺省布局管理器为FlowLayout。 <BR><BR>　　　3．当把Panel 作为一个组件添加到某个容器中后，该Panel 仍然可以有自己的布局管理器。因此，可以利用Panel 使得BorderLayout 中某个区域显示多个组件，达到设计复杂用户界面的目的 。 <BR><BR>　　　4．如果采用无布局管理器 setLayout(null)，则必须使用setLocation(),setSize(),setBounds()等方法手工设置组件的大小和位置，此方法会导致平台相关，不鼓励使用。 <BR><BR>　　5.2 AWT事件处理模型 <BR><BR>　　上一节中的主要内容是如何放置各种组件，使图形界面更加丰富多彩，但是还不能响应用户的任何操作，要能够让图形界面接收用户的操作，就必须给各个组件加上事件处理机制。在事件处理的过程中，主要涉及三类对象： <BR><BR>　　◇ Event-事件，用户对界面操作在java语言上的描述，以类的形式出现，例如键盘操作对应的事件类是KeyEvent。 <BR><BR>　　◇ Event Source-事件源，事件发生的场所，通常就是各个组件，例如按钮Button。 <BR><BR>　　◇ Event handler-事件处理者，接收事件对象并对其进行处理的对象 <BR><BR>　　例如，如果用户用鼠标单击了按钮对象button，则该按钮button就是事件源，而java运行时系统会生成ActionEvent类的对象actionE，该对象中描述了该单击事件发生时的一些信息，然后，事件处理者对象将接收由java运行时系统传递过来的事件对象actionE并进行相应的处理。 <BR><BR>　　由于同一个事件源上可能发生多种事件，因此java采取了授权处理机制(Delegation Model)，事件源可以把在其自身所有可能发生的事件分别授权给不同的事件处理者来处理。比如在Canvas对象上既可能发生鼠标事件，也可能发生键盘事件，该Canvas对象就可以授权给事件处理者一来处理鼠标事件，同时授权给事件处理者二来处理键盘事件。有时也将事件处理者称为监听器，主要原因也在于监听器时刻监听着事件源上所有发生的事件类型，一旦该事件类型与自己所负责处理的事件类型一致，就马上进行处理。授权模型把事件的处理委托给外部的处理实体进行处理，实现了将事件源和监听器分开的机制。事件处理者（监听器）通常是一个类，该类如果要能够处理某种类型的事件，就必须实现与该事件类型相对的接口。例如例5.9中类ButtonHandler之所以能够处理ActionEvent事件，原因在于它实现了与ActionEvent事件对应的接口ActionListener。每个事件类都有一个与之相对应的接口。 <BR><BR>　　将事件源对象和事件处理器（事件监听器）分开。 <BR>　　　　 <BR>　　打个不太恰当的比喻，比如说有一位李先生，李先生可能会发生很多法律纠纷，可能是民事法律纠纷，也可能是刑事法律纠纷，那么李先生可以请律师，他可以授权王律师负责帮他打民事法律的官司，同时也可以授权张律师帮他打刑事法律的官司。这个请律师的过程从李先生的角度来看，就是授权的过程，而从王律师和张律师的角度来看，一旦被授权，他们就得时刻对李先生负责，"监听"着李先生，一旦发生民事纠纷了，王律师就要马上去处理，而一旦发生刑事纠纷了，张律师就要马上进行处理。此时此刻，李先生就是事件源，王律师是一个事件处理者，张律师是另外一个事件处理者，民事纠纷和刑事纠纷就是不同类型的事件。 <BR>　　 <BR><BR>　　例5.9 <BR>　　　　import java.awt.*; <BR>　　　　import java.awt.event.*; <BR>　　　　public class TestButton { <BR>　　　　public static void main(String args[]) <BR>　　　　{ <BR>　　　　　　Frame f = new Frame("Test"); <BR>　　　　　　Button b = new Button("Press Me!"); <BR>　　　　　　b.addActionListener(new ButtonHandler()); /*注册监听器进行授权，该方法的参数是事件处理者对象，要处理的事件类型可以从方法名中看出，例如本方法要授权处理的是ActionEvent，因为方法名是addActionListener。*/ <BR>　　　　　　f.setLayout(new FlowLayout()); //设置布局管理器 <BR>　　　　　　f.add(b); <BR>　　　　　　f.setSize(200,100); <BR>　　　　　　f.setVisible(true); <BR>　　　　　　} <BR>　　　　} <BR>　　　　class ButtonHandler implements ActionListener { <BR>　　　　//实现接口ActionListener才能做事件ActionEvent的处理者 <BR>　　　　public void actionPerformed(ActionEvent e) <BR>　　　　//系统产生的ActionEvent事件对象被当作参数传递给该方法 <BR>　　　　{ <BR>　　　　　　System.out.println("Action occurred"); <BR>　　　　//本接口只有一个方法，因此事件发生时，系统会自动调用本方法，需要做的操作就把代码写在则个方法里。 <BR>　　　　} <BR>　　　　} <BR><BR>　　使用授权处理模型进行事件处理的一般方法归纳如下： <BR><BR>　　1．对于某种类型的事件XXXEvent, 要想接收并处理这类事件，必须定义相应的事件监听器类，该类需要实现与该事件相对应的接口XXXListener； <BR><BR>　　2．事件源实例化以后，必须进行授权，注册该类事件的监听器，使用addXXXListener(XXXListener ) 方法来注册监听器。 <BR><BR><BR></P><img src ="http://www.blogjava.net/gongtao200118/aggbug/18677.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gongtao200118/" target="_blank">Write Once,Run Anywhere!</a> 2005-11-08 00:50 <a href="http://www.blogjava.net/gongtao200118/archive/2005/11/08/18677.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>