﻿<?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-行动创造奇迹-随笔分类-Core Java</title><link>http://www.blogjava.net/dorydoo/category/12567.html</link><description>Action Action Action</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 12:18:44 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 12:18:44 GMT</pubDate><ttl>60</ttl><item><title>JDBC2.0新特性 </title><link>http://www.blogjava.net/dorydoo/archive/2006/06/28/55468.html</link><dc:creator>多力宇扬</dc:creator><author>多力宇扬</author><pubDate>Wed, 28 Jun 2006 01:46:00 GMT</pubDate><guid>http://www.blogjava.net/dorydoo/archive/2006/06/28/55468.html</guid><wfw:comment>http://www.blogjava.net/dorydoo/comments/55468.html</wfw:comment><comments>http://www.blogjava.net/dorydoo/archive/2006/06/28/55468.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dorydoo/comments/commentRss/55468.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dorydoo/services/trackbacks/55468.html</trackback:ping><description><![CDATA[
		<div class="postText">
				<font color="#0000ff">JDBC 2.0比1.0有了一些不同,体现在四个比较明显的方面:</font>
				<br />1&gt;. ResutlSet对象中的Cursor能够自由上下移动<br />2&gt;. 能直接使用Java程序语言来更新DB表里的内容,而不需要额外写SQL语法<br />3&gt;. 可以一次传送许多SQL语句到DB执行----Batch<br />4&gt;. 新增2个数据类型(BLOB和CLOB)<br />   我们知道在JDBC 1.0时,只要用 connection.createStatement()就能取得Statement()对象.不过在2.0中多的createStatement()<br />多了两个参数值,需要我们自己来定义它.<br />public Statement createStatement(int resultSetType,<br />                                 int resultSetConcurrency)throws SQLException <br />   第一个参数resultSetType用来设定ResultSet对象中的光标是否可以自由上下移动,它的值有三种,TYPE_FORWARD_ONLY,TYPE_SCROLL_SENSITIVE,<br />TYPE_SCROLL_INSENSITIVE.若为TYPE_FORWARD_ONLY就表示和1.0一样只能用next()方法;然后后两者可以让Cursor随便的自由移动,不过,<br />它们两者最大的区别在于:当ResutlSet中的值有改变时,TYPE_SCROLL_SENSITIVE能取得修改后的值,而TYPE_SCROLL_INSENSITIVE则不能.<br />  第而个参数resultSetConcurrentcy,主要是设定ResultSet对象是只读(read-only)还是可以改变的(updateable),它可能的值有两种,<br />CONCUR_READ_ONLY或者是CONCUR_UPDATE.若设置为CONCUR_READ_ONLY,ResultSet对象和1.0一样;若为CONCUR_UPDATEABLE,那么就可以用<br />ResultSet对象执行数据库的修改,增加和移除功能.for example:<br />先看功能和1.0一样的写法:<br />Statement stmt=con.createStatement(ResultSet.TYPE_FORWARD_ONLY,<br />                                   ResultSet.CONCUR_READ_ONLY);<br />RestultSet rs=stmt.executeQuery("select ename,empno from emp");<br />while(rs.next())<br />{<br />   String name=rs.getString("ename");<br />   int empno=rs.getInt("empno");<br />   System.out.println("name="+name+","+"number="+empno);<br />}<br />输出结果为:<br />name=feiyang,number=1190<br />name=jack,   number=1230<br />name=BillGates number=12<br />...........<br />再看看下面这个:<br />Statement stmt=con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,<br />                                   ResultSet.CONCUR_READ_ONLY);<br />RestultSet rs=stmt.executeQuery("select ename,empno from emp");<br />rs.afterLast();<br />while(rs.previous())<br />{<br />   String name=rs.getString("ename");<br />   int empno=rs.getInt("empno");<br />   System.out.println("name="+name+","+"number="+empno);<br />}<br />输出结果为:<br />name=BillGates number=12<br />name=jack,   number=1230<br />name=feiyang,number=1190<br />.............<br />这和上面第一有点不同的是顺序颠倒了,这是因为我们使用了rs.afterLast()这个方法.其实2.0中还有很多方法,如下:<br />rs.absolute(-1); //表示cursor在最后一笔数据,即 rs.last()<br />rs.absolute(1);  //表示cursor在第一笔数据,即rs.first()<br />rs.absolute(n);  //表示cursor在第N笔数据<br />假使我们目前有1000笔数据，取得第997笔<br />rs.absolute(-4);<br />还有一个方法和absolute很相像,那就是relative(),<br />rs.absolute(5); //表示第五笔数据<br />......<br />rs.relative(-3);  //表示cursor目前在第二笔数据<br />.......<br />rs.relative(1);  //cursor目前在第三笔数据<br />看看怎么用ResultSet对象执行更新数据库动作<br />   要让ResultSet对象执行更新数据库的动作，首先在声明Statement对象时,参数必须设置为TYPE_SCROLL_SENSITIVE和<br />CUNCOR_UPDATEABLE.<br />Statement stmt=con.createStatment(RestultSet.TYPE_SCROLL_SENSITIVE,<br />                                  ResultSet.CONCUR_UPDATEABLE);<br />ResultSet rs=stmt.executeQuery("select ename,empno from emp);<br />rs.last();<br />rs.updateInt("empno",2230);<br />rs.cancelRowUpdates();<br />rs.updateInt("empno",1213);<br />rs.updateRow();<br />新增数据到数据库<br />Statement stmt=con.createStatment(RestultSet.TYPE_SCROLL_SENSITIVE,<br />                                  ResultSet.CONCUR_UPDATEABLE);<br />ResultSet rs=stmt.executeQuery("select * from emp);<br />rs.moveToInsertRow();<br />rs.updateInt("empno",2230);<br />rs.updateString("ename","feiyang");<br />rs.updateString("job","clerk");<br />rs.updateFloat("sal",123456.5);<br />rs.insertRow();<br />删除数据<br />Statement stmt=con.createStatment(RestultSet.TYPE_SCROLL_SENSITIVE,<br />                                  ResultSet.CONCUR_UPDATEABLE);<br />ResultSet rs=stmt.executeQuery("select * from emp);<br />rs.absolute(4);<br />rs.deleteRow();<br />依次执行多条SQL语句<br />Statement stmt=con.createStatment();<br />int[] rows;<br />stmt.addBatch("insert into emp values('feiyang','123456')");<br />stmt.addBatch("insert into offcie values('employee','Shanghai')");<br />rows=stmt.executeBatch();<br />当执行大量数据的时候为了数据的完整性,建议使用Transaction<br />eg:<br />con.setAutoCommit(false);<br />Statement stmt=con.createStatement();<br />int[] rows;<br />stmt.addBatch("1...........");<br />stmt.addBatch("2...........");<br />stmt.addBatch("3...........");<br />stmt.addBatch("4...........");<br />stmt.addBatch("5...........");<br />stmt.addBatch("6...........");<br />rows=stmt.executeBatch();<br />con.commit();<br />在JDBC2.0中新增加BLOB和CLOB两个数据类型<br />BOLB指的是二进制大型对象(Binary Large Object),CLOB指的是字符大型对象(Character Large Object).它们用来处理大型<br />的数据类型,他们分别代表大量的二进制数据和文字数据. </div>
<img src ="http://www.blogjava.net/dorydoo/aggbug/55468.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dorydoo/" target="_blank">多力宇扬</a> 2006-06-28 09:46 <a href="http://www.blogjava.net/dorydoo/archive/2006/06/28/55468.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java学习笔记-I/O</title><link>http://www.blogjava.net/dorydoo/archive/2006/06/27/55383.html</link><dc:creator>多力宇扬</dc:creator><author>多力宇扬</author><pubDate>Tue, 27 Jun 2006 09:40:00 GMT</pubDate><guid>http://www.blogjava.net/dorydoo/archive/2006/06/27/55383.html</guid><wfw:comment>http://www.blogjava.net/dorydoo/comments/55383.html</wfw:comment><comments>http://www.blogjava.net/dorydoo/archive/2006/06/27/55383.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dorydoo/comments/commentRss/55383.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dorydoo/services/trackbacks/55383.html</trackback:ping><description><![CDATA[
		<p>    File类</p>
		<p> 一个File类的对象，表示了磁盘上的文件或目录。<br /> File类提供了与平台无关的方法来对磁盘上的文件或目录进行操作。</p>
		<p>import java.io.*;<br />class FileTest<br />{<br /> public static void main(String[] args) throws Exception<br /> {<br />  //File f = new File("1.txt");<br />  //f.createNewFile();   创建文件<br />  //f.mkdir(); 创建文件夹<br />  //File f = new File("F:\\Java Develop\\1.txt");//使用绝对路径<br />  //f.createNewFile();<br />  /*<br />  *WINDOWS平台下有盘符，LINUX下是没有的<br />  *考虑到JAVA语言的平台性，所有用分隔符seperator/seperatorChar<br />  */<br />  /*<br />  File fDir = new File(File.separator);//创建了当前的根目录<br />  String strFile = "Java Develop"+File.separator+"1.txt";<br />  File f = new File(fDir,strFile);<br />  f.createNewFile();<br />  //f.delete();<br />  f.deleteOnExit();<br />  Thread.sleep(3000);<br />  */<br />  /*<br />  for(int i=0;i&lt;5;i++)<br />  {<br />   File.createTempFile("linshi",".tmp");<br />   f.deleteOnExit();<br />  }<br />  Thread.sleep(3000);<br />  */<br />  <br />  File fDir = new File(File.separator);<br />  String strFile ="Java Develop"+File.separator;<br />  File f = new File(fDir,strFile);<br />  //文件过滤器<br />  String[] names = f.list(new FilenameFilter()<br />  {<br />   public boolean accept(File dir,String name)<br />   {<br />    return name.indexOf(".java")!=-1;<br />   }<br />  });<br />  for(int i=0;i&lt;names.length;i++)<br />  {<br />   System.out.println(names[i]);<br />  }<br /> }<br />}</p>
		<p>            流式I/0</p>
		<p> 流(Stream)是字节的源或目的。<br /> 两种基本的流是: 输入流(Input Stream)和输出流(Output Stream)。从从中读出一系列字节的<br /> 对象称为输入流。而能向其中写入一系列字节的对象称为输出流。</p>
		<p>
				<br />           流的分类<br /> <br /> 节点流: 从特定的地方读写的流类，例如：磁盘或一块内存区域。<br /> 过滤流: 使用节点作为输入或输出。过滤流使用的是一个已经存在的输入流或输出流连接创建的。<br /> (如下图)<br /><img src="http://photo2.hexun.com/p/2006/0611/26339/b_4ABA553F60E5FD5F.jpg" /><br /> InputStream(一个抽象的基类)<br /> .三个基本的读写方法<br />  abstract int read(): 读取一个字节数据，并返回到数据，如果返回-1，表示读到了输入流的<br />                       末尾。<br />  int read(byte[] b):  将数据读入一个字节数组，同时返回实际读取的字节数。如果返回-1，<br />                       表示读到了输入流的末尾。<br />  int read(byte[] b,int off,int len): 将数据读入一个字节数组，同时返回是实际读取的字<br />                       节数。如果返回-1，表示读到了输入流的末尾。off指定在数组b中存放<br />                       数据的起始偏移位置；len指定读取的最大字节数。<br /> 其他的方法<br />  long-skip(long n): 在输入流中跳过n个字节，并返回实际跳过的字节数。<br />  int available():   返回在不发生阻塞的情况下，可读取的字节数。<br />  void close():      关闭输入流，释放和这个流相关的系统资源。<br />  void mark(int reqdlimit): 在输入流的当前位置放置一个标记，如果读取的字节数多余<br />                     readlimit设置的值，则流忽略这个标记。<br />  void reset():      返回到上一个标记。<br />  boolean markSupported(): 测试当前是否支持mark和reset方法。如果支持返回true，反之false。</p>
		<p>         java.io包中的InputStream的类层次 (下图)<br /><img src="http://photo2.hexun.com/p/2006/0611/26339/b_051C70533BCF9CF2.jpg" /><br />OutputStream</p>
		<p> 三个基本的写方法<br /> abstract void write(int b): 往输出流中写入一个字节<br /> void write(byte[] b):       往输出流中写入数组b中的所有字节<br /> void writte(byte[] b,int off,int len): 往输出流中写入数组b中从偏移量off开始的len个<br />                             字节的数据<br /> 其它方法<br /> void flush(): 刷新输出流，强制缓冲区中的输出字节被写出<br /> void close(): 关闭输出流，释放和这个流相关的系统资源</p>
		<p>        java.io包中OutputStream的类层次(如下图)<br /><img src="http://photo2.hexun.com/p/2006/0611/26339/b_A7649D38C87C4104.jpg" /><br />基本的流类</p>
		<p> FileInputStream和FileOutputStream<br /> 节点流，用于从文件中读取或往文件中写入字节流。如果在构造FileOutputStream时，文件已经<br /> 存在，则覆盖这个文件。<br /> <br /> BufferedInputStream和BufferedOutputStream<br /> 过滤流，需要使用已经存在的节点流来构造，提供带缓冲的读写，提高了读写的效率。</p>
		<p> DataInputStream和DataOutputStream<br /> 过滤流，需要使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能。</p>
		<p> PipedInputStream和PipedOutputStream<br /> 管道流，用于线程间的通信。一个线程的PipedInputStream对象从另一个线程的PipedOutputStream<br /> 对象读取输入。要使管道流有用，必须同时构造管道输入流和管道输出流。</p>
		<p>code:<br />import java.io.*;<br />class StreamTest<br />{<br /> public static void main(String[] args)throws Exception<br /> {<br />  /*<br />  int data;<br />  while((data=System.in.read())!=-1)  //从标准设备读取数据<br />  {<br />   System.out.write(data);//从标准设备输出数据<br />  }<br />  */<br />  //输出流写数据,只需要关闭尾端的流就可以了，因为fos连接到了bos<br />  FileOutputStream fos = new FileOutputStream("1.txt");<br />  //fos.write("<a href="http://www.google.cn&quot;.getBytes">http://www.google.cn".getBytes</a>());<br />  //fos.close();<br />  BufferedOutputStream bos = new BufferedOutputStream(fos);<br />  //bos.write("http//www.baidu.com".getBytes());<br />  //bos.flush();<br />  //bos.close();<br />  DataOutputStream dos=new DataOutputStream(bos); //连接到了bos和fis<br />  byte b=3;<br />  int i=78;<br />  char ch='a';<br />  float f=4.5f;<br />  dos.writeByte(b);<br />  dos.writeInt(i);<br />  dos.writeChar(ch);<br />  dos.writeFloat(f);<br />  dos.close(); //必须调用flush()或者close()不然不会写入硬盘<br />  <br />  //输入流读数据<br />  FileInputStream fis=new FileInputStream("1.txt");<br />  BufferedInputStream bis = new BufferedInputStream(fis);<br />  //byte[] buf=new byte[100];<br />  //int len=fis.read(buf);<br />  //int len=bis.read(buf);<br />  //System.out.println(new String(buf,0,len));<br />  //fis.close();<br />  //bis.close();<br />  //注意读取的顺序要和写的顺序一样<br />  DataInputStream dis = new DataInputStream(bis);<br />  System.out.println(dis.readByte());<br />  System.out.println(dis.readInt());<br />  System.out.println(dis.readChar());<br />  System.out.println(dis.readFloat());<br />  dis.close();  <br />  <br /> }<br />}</p>
		<p>
				<br />管道输入/输出流 code:<br />import java.io.*;<br />class PipedStreamTest<br />{<br /> public static void main(String[] args)<br /> {<br />  PipedOutputStream pos=new PipedOutputStream();<br />  PipedInputStream pis=new PipedInputStream();<br />  //连接<br />  try<br />  {<br />   pos.connect(pis);<br />   new Producer(pos).start();<br />   new Consumer(pis).start();<br />  }<br />  catch(Exception e)<br />  {<br />   e.printStackTrace();<br />  }<br /> }<br />}</p>
		<p>class Producer extends Thread<br />{<br /> private PipedOutputStream pos;<br /> public Producer(PipedOutputStream pos)<br /> {<br />  this.pos=pos;<br /> }<br /> public void run()<br /> {<br />  try<br />  {<br />   pos.write("hello,welcome!".getBytes());<br />   pos.close();<br />  }<br />  catch(Exception e)<br />  {<br />   e.printStackTrace();<br />  }<br /> }<br />}</p>
		<p>class Consumer extends Thread<br />{<br /> private PipedInputStream pis;<br /> Consumer(PipedInputStream pis)<br /> {<br />  this.pis=pis;<br /> }<br /> public void run()<br /> {<br />  try<br />  {<br />   byte[] buf=new byte[100];<br />   int len=pis.read(buf);<br />   System.out.println(new String(buf,0,len));<br />   pis.close();<br />  }<br />  catch(Exception e)<br />  {<br />   e.printStackTrace();<br />  }<br /> }<br />}</p>
		<p>=================================================================================<br />              Java I/O库的设计原则</p>
		<p> Java的I/O库提供了一个称做链接的机制，可以将一个流与另一个流首尾相接，形成一个流管道的链接。<br /> 这种机制实际上是一种被称做为Decorator(装饰)的设计模式的应用。<br /> <br /> 通过流的链接，可以动态的增加流的功能，而这些功能的增加是通过组合一些流的基本功能而动<br /> 态获取的。</p>
		<p> 我们要获取一个I/O对象，往往需要产生多个I/O对象，这也是Java I/O库不大容易掌握的原因，<br /> 但在I/O库中的Decorator模式的运用，给我们提供了实现上的灵活性。</p>
		<p> I/O流的链接图(如下)<br /><img src="http://photo2.hexun.com/p/2006/0611/26339/b_67BF045E1D09D7AD.jpg" /><br />  Reader和Writer</p>
		<p> Java程序语言使用Unicode来表示字符串和字符。<br /> Reader和Writer这两个抽象类主要用来读写字符流。</p>
		<p> java.io包中Reader的类层次(如下图)<br /><img src="http://photo2.hexun.com/p/2006/0611/26339/b_7D68B185CE1EE42A.jpg" /><br /> java.io包中Writer的类层次(如下图)<br /><br /><img src="http://photo2.hexun.com/p/2006/0611/26339/b_B4B95BA560BA15F9.jpg" /><br /> code:<br />import java.io.*;<br />class StreamTest<br />{<br /> public static void main(String[] args)throws Exception<br /> {<br />  /*<br />  FileOutputStream fos = new FileOutputStream("1.txt");<br />  OutputStreamWriter osw = new OutputStreamWriter(fos); <br />  BufferedWriter bw = new BufferedWriter(osw);<br />  <br />  bw.write("<a href="http://www.yahoo.com.cn">http://www.yahoo.com.cn</a>");<br />  bw.close(); <br />  <br />  FileInputStream fis = new FileInputStream("1.txt");<br />  InputStreamReader isr = new InputStreamReader(fis);<br />  BufferedReader br = new BufferedReader(isr);<br />  System.out.println(br.readLine());<br />  br.close();<br />  */<br />  //InputStreamReader/OutputStreamWriter是一个中间过度类,连接字符和字符串<br />  InputStreamReader isr = new InputStreamReader(System.in);<br />  BufferedReader br = new BufferedReader(isr);<br />  String strLine;<br />  while((strLine=br.readLine())!=null)<br />  {<br />   System.out.println(strLine);<br />  }<br />  br.close();<br /> }<br />}</p>
		<p>            字符集的编码</p>
		<p> ASCII(American Standard Code for Information Interchange,美国信息互换标准代码),是基<br /> 于常用的英文字符的一套电脑编码系统。我们知道英文中经常使用的字符，数字符号被计算机<br /> 处理时都是以二进制编码的形式出现(bit)二进制数对应。其最高位是0，相应的十进制数是0-127<br /> 如，数字1，有一些制表符和其他符号组成。ASCII是现金最通用的单字节编码系统。</p>
		<p> GB2312： GB2312码是中华人民共和国国家汉字信息交换用编码，全称《信息交换用汉字编码字<br /> 符集-基本集》。主要用于给每一个中文字符指定相应的数字，也就是进行编码。一个中文字符<br /> 用两个字节的数字来表示，为了和ASCII码有所区别，将中文字符每一个字节的最高位置都用1<br /> 来表示。</p>
		<p> GBK：为了对更多的字符进行编码，国家又发布了新的编码系统GBK（GBK的K是“扩展”的汉语<br /> 拼音的第一个字母）。在新的编码系统里，除了完全兼容GB2312外，还对繁体中文，一些不常用<br /> 的汉字和许多符号进行了编码。</p>
		<p> ISO-8859-1：是西方国家所使用的字符编码集，是一种单字节的字符集，而英文实际上只用了其<br /> 中数字小于128的部分。</p>
		<p> Unicode: 这是一种通用的字符集，对所有语言的文字进行统一编码，对每一个字符都采用2个字节<br /> 来表示，对于英文字符采取前面加“0”字节的策略实现等长兼容。如"a"的ASCII码为0x61,<br /> UNICODE就为0x00,0x61。</p>
		<p> UTF-8: Elight-bit UCS Transformation Format,(UCS,Universal Character Set,通用字符集,<br /> UCS是所有其他字符集标准的一个超集)。一个7位的ASCII码值，对应的UTF码是一个字节，如果<br /> 字符是0x0000，或在0x0080与0x007f之间，对应的UTF码是两个字节，如果字符在0x0800与0xffff<br /> 之间，对应的UTF码是三个字节。<br /> 编码：将一个Unicode码转换为本地字符表示的过程为编码。<br />  解码：将一个字节转换为一个字符（用Unicode表示），这个过程叫解码。<br />        [简单的说去获取一个Unicode码就是解码]<br /> code:</p>
		<p>import java.util.*;<br />import java.nio.charset.*;<br />class CharsetTest<br />{<br /> public static void main(String[] args)throws Exception<br /> {<br />  /*<br />  Map m=Charset.availableCharsets();<br />  Set names=m.keySet();<br />  Iterator it =names.iterator();<br />  while(it.hasNext())<br />  {<br />   System.out.println(it.next());<br />  }<br />  */<br />  Properties pps=System.getProperties();<br />  //pps.list(System.out);<br />  pps.put("file.encoding","ISO-8859-1");<br />  int data;<br />  byte[] buf=new byte[100];<br />  int i=0;<br />  while((data=System.in.read())!='q')<br />  {<br />   buf[i]=(byte)data;<br />   i++;<br />  }<br />  String str=new String(buf,0,i);<br />  //String strGBK=new String(str.getBytes("ISO-8859-1"),"GBK");<br />  //System.out.println(strGBK);<br />  System.out.println(str);<br /> }<br />}</p>
		<p> </p>
		<p>     RandomAccessFile</p>
		<p>  RandomAccessFile类同时实现了DataInput和DataOutput接口，提供了对文件随机存取的功能，<br />  利用这个类可以在文件的任何位置读取或写入数据。<br />  RandomAccessFile类提供了一个文件指针，用来标志要进行读写操作的下一位数据的位置。 </p>
		<p> <br /> code:<br />import java.io.*;<br />class RandomFileTest<br />{<br /> public static void main(String[] args)throws Exception<br /> {<br />  Student s1 = new Student(1,"zhangsan",98.5);<br />  Student s2 = new Student(2,"lisi",90.5);<br />  Student s3 = new Student(3,"wangwu",78.5);<br />  <br />  RandomAccessFile rsf=new RandomAccessFile("student.txt","rw");  //存取模式rw<br />  s1.WriteStudent(rsf);<br />  s2.WriteStudent(rsf);<br />  s3.WriteStudent(rsf);<br />  <br />  Student s =new Student();<br />  rsf.seek(0); //把文件指针移到文件首<br />  for(long i=0;i&lt;rsf.length();i=rsf.getFilePointer())<br />  {<br />   s.ReadStudent(rsf);<br />   System.out.println(s.num+":"+s.name+":"+s.score);<br />  }<br />  rsf.close();<br /> }<br />}</p>
		<p>class Student<br />{<br /> int num;<br /> String name;<br /> double score;<br /> Student()<br /> {<br />  <br /> }<br /> Student(int num,String name,double score)<br /> {<br />  this.num=num;<br />  this.name=name;<br />  this.score=score;<br /> }<br /> public void WriteStudent(RandomAccessFile raf)throws Exception<br /> {<br />  raf.writeInt(num);<br />  raf.writeUTF(name);<br />  raf.writeDouble(score);<br /> }<br /> public void ReadStudent(RandomAccessFile raf)throws Exception<br /> {<br />  raf.readInt();<br />  raf.readUTF();<br />  raf.readDouble();  <br /> }<br />}</p>
		<p>
				<br />           对象序列化</p>
		<p> .将对象转换为字节流保存起来，并在日后还原这个对象，这种机制叫做对象序列化。<br /> .将一个对象保存到永久存储设备上称为持续性。<br /> .一个对象要想能够实现序列化，必须实现Serializable接口或Externalizable接口。<br /> .当一个对象被序列化时，只保存对象的非静态成员变量，不能保存任何的成员变量和静态的<br />  成员变量。<br /> .如果一个对象的成员变量是一个对象，那么这个对象的数据成员也会被保存。<br /> .如果一个可序列化的对象包含对某个不可序列化的对象的引用，那么整个序列化操作将会失败，<br />  并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象<br />  仍然可以序列化。</p>
		<p> code:<br />import java.io.*;<br />class ObjectSerialTest<br />{<br /> public static void main(String[] args)throws Exception<br /> {<br />  Employee e1 = new Employee("zhangsan",20,2800.50);<br />  Employee e2 = new Employee("lisi",22,25000.50);<br />  Employee e3 = new Employee("wangwu",23,12800.50);<br />  Employee e4 = new Employee("blovesaga",22,3800.50);<br />  <br />  FileOutputStream fos=new FileOutputStream("employee.txt");<br />  ObjectOutputStream oos=new ObjectOutputStream(fos);<br />  oos.writeObject(e1);<br />  oos.writeObject(e2);<br />  oos.writeObject(e3);<br />  oos.writeObject(e4);<br />  oos.close();<br />  <br />  FileInputStream fis = new FileInputStream("employee.txt");<br />  ObjectInputStream ois =new ObjectInputStream(fis);<br />  Employee e;<br />  for(int i=0;i&lt;4;i++)<br />  {<br />   e=(Employee)ois.readObject();<br />   System.out.println(e.name+":"+e.age+":"+e.salary);<br />  }<br />  ois.close();<br /> }<br />}</p>
		<p>class Employee implements Serializable<br />{<br /> String name;<br /> int age;<br /> double salary;<br /> transient Thread t1 =new Thread();<br /> Employee(String name,int age,double salary)<br /> {<br />  this.name=name;<br />  this.age=age;<br />  this.salary=salary;<br /> }<br /> //可以写private void readObject()方法来控制我们自己想要实现的<br /> private void writeObject(java.io.ObjectOutputStream oos)throws Exception<br /> {<br />  //例如我们自己写想要显示的顺序和那些需要显示<br />  oos.writeInt(age);<br />  oos.writeUTF(name);<br />  System.out.println("Write Object");<br /> }<br /> private void readObject(java.io.ObjectInputStream ois)throws Exception<br /> {<br />  //按照写入的顺序来读取<br />  age=ois.readInt();<br />  name=ois.readUTF();<br />  System.out.println("Read Object");<br /> }<br />}</p>
<img src ="http://www.blogjava.net/dorydoo/aggbug/55383.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dorydoo/" target="_blank">多力宇扬</a> 2006-06-27 17:40 <a href="http://www.blogjava.net/dorydoo/archive/2006/06/27/55383.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java学习笔记-集合框架中的接口</title><link>http://www.blogjava.net/dorydoo/archive/2006/06/27/55382.html</link><dc:creator>多力宇扬</dc:creator><author>多力宇扬</author><pubDate>Tue, 27 Jun 2006 09:36:00 GMT</pubDate><guid>http://www.blogjava.net/dorydoo/archive/2006/06/27/55382.html</guid><wfw:comment>http://www.blogjava.net/dorydoo/comments/55382.html</wfw:comment><comments>http://www.blogjava.net/dorydoo/archive/2006/06/27/55382.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dorydoo/comments/commentRss/55382.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dorydoo/services/trackbacks/55382.html</trackback:ping><description><![CDATA[
		<p> Collection             Map(和Collection接口没任何关系)<br />       / \                         |<br />      /   \                        |      <br /> Set   List              SortedMap<br />    /<br />   /<br />SortedSet<br />(接口图)<br /><img src="http://photo2.hexun.com/p/2006/0609/25931/b_A974EFE2446D07E2.jpg" /></p>
		<p>所谓框架就是一个类库的集合。集合框架就是一个用来表示和操作集合的统一框架，包含了实现<br />集合的接口和类。<br /> <br /> 集合框架中的接口</p>
		<p> .Collection: 集合层次中的根接口，JDK没有提供这个接口直接的实现类。<br /> .Set: 不能包含重复的元素。SortedSet是一个按照升序排列元素的Set。<br /> .List: 是一个有序的集合，可以包含重复的元素。提供了按照索引访问的方式。<br /> .Map: 包含了key-value对。Map不能包含重复的key。SortedMap是一个按照升序排列key的Map。<br /> <br /> 集合框架中的实现类<br /> <br /> 实线表示继承类，虚线表示实现类。<br /> (图如下)<br /><img src="http://photo2.hexun.com/p/2006/0609/25931/b_E416E2DEA99C9A22.jpg" /><br />.ArrayList: 我们可以将其看做是能够自动增长容量的数组。<br /> .利用ArrayList的toArray()返回一个数组。<br /> .Arrays.asList()返回一个列表。<br /> .迭代器(Iterator)给我们提供了一种通用的方式来访问集合中的元素。</p>
		<p> 注意: 从集合类中获取一个数组 toArray(),从数组获取列表利用Arrays.asList()<br /> 例子:<br />import java.util.*;<br />class ArrayListTest<br />{<br /> public static void printElement(Collection c)<br /> {<br />  Iterator it = c.iterator();<br />  while(it.hasNext())<br />  {<br />   System.out.println(it.next());<br />  }<br /> }<br /> public static void main(String[] args)<br /> {<br />  ArrayList a = new ArrayList();<br />  /*<br />  a.add("abc");<br />  a.add("def");<br />  a.add("hjk");<br />  */<br />  <br />  a.add(new Point(1,1));<br />  a.add(new Point(2,2));<br />  a.add(new Point(3,3));<br />  /*<br />  Object[] o;<br />  o=a.toArray();  //将集合类转换为数组<br />  for(int i=0;i&lt;o.length;i++)<br />  {<br />   System.out.println(o[i]);<br />  }<br />  <br />  List b = new ArrayList();<br />  b=Arrays.asList(o);<br />  System.out.println(b);<br />  <br />  for(int i=0;i&lt;a.size();i++)<br />  {<br />   System.out.println(a.get(i));<br />  }<br />  <br />  System.out.println(a);<br />  System.out.println(a);<br />  */<br />  <br />  /*<br />  Iterator it = a.iterator();<br />   如果要删除元素，必须先调用next方法<br />  it.next();<br />  it.remove();<br />  while(it.hasNext())<br />  {<br />   System.out.println(it.next());<br />  }<br />  */<br />  //迭代器的作用: 提供一组通用的访问方式<br />  printElement(a);<br /> }<br />}</p>
		<p>class Point<br />{<br /> int x, y;<br /> Point(int x, int y)<br /> {<br />  this.x=x;<br />  this.y=y;<br /> }<br /> public String toString()<br /> {<br />  return "x="+x+","+"y="+y;<br /> }<br />}</p>
		<p> Collections类</p>
		<p> .排序: Collections.sort(); [区别与Arrays.sort()]<br />  (1) 自然排序(natural ordering);<br />  (2) 实现比较器(Comparator)接口。<br /> .取最大和最小的元素: Collections.max(),Collections.min();<br /> .在已排序的List中搜索指定的元素: Collections.binarySearch()。</p>
		<p> 代码示例:<br />import java.util.*;<br />class ArrayListTest<br />{<br /> public static void printElement(Collection c)<br /> {<br />  Iterator it = c.iterator();<br />  while(it.hasNext())<br />  {<br />   System.out.println(it.next());<br />  }<br /> }<br /> public static void main(String[] args)<br /> {<br />  /*<br />  ArrayList a = new ArrayList();<br />  <br />  a.add("abc");<br />  a.add("def");<br />  a.add("hjk");<br />  <br />  <br />  a.add(new Point(1,1));<br />  a.add(new Point(2,2));<br />  a.add(new Point(3,3));<br />  <br />  Object[] o;<br />  o=a.toArray();  //将集合类转换为数组<br />  for(int i=0;i&lt;o.length;i++)<br />  {<br />   System.out.println(o[i]);<br />  }<br />  <br />  List b = new ArrayList();<br />  b=Arrays.asList(o);<br />  System.out.println(b);<br />  <br />  for(int i=0;i&lt;a.size();i++)<br />  {<br />   System.out.println(a.get(i));<br />  }<br />  <br />  System.out.println(a);<br />  System.out.println(a);<br />  */<br />  <br />  /*<br />  Iterator it = a.iterator();<br />   如果要删除元素，必须先调用next方法<br />  it.next();<br />  it.remove();<br />  while(it.hasNext())<br />  {<br />   System.out.println(it.next());<br />  }<br />  */<br />  //迭代器的作用: 提供一组通用的访问方式<br />  //printElement(a);<br />  <br />  Student s1 = new Student(1,"zhangsan");<br />  Student s2 = new Student(2,"lisi");<br />  Student s3 = new Student(3,"wangwu");<br />  Student s4 = new Student(3,"blovesaga");<br />  <br />  ArrayList a = new ArrayList();<br />  a.add(s1);<br />  a.add(s2);<br />  a.add(s3);<br />  a.add(s4);<br />  <br />  //Collections.sort(a);<br />  Collections.sort(a,new Student.StudentComparator());<br />  printElement(a);<br /> }<br />}</p>
		<p>class Point<br />{<br /> int x, y;<br /> Point(int x, int y)<br /> {<br />  this.x=x;<br />  this.y=y;<br /> }<br /> public String toString()<br /> {<br />  return "x="+x+","+"y="+y;<br /> }<br />}</p>
		<p>class Student implements Comparable<br />{<br /> int num;<br /> String name;<br /> //实现比较器，它总是和我们的一个类相关,用内部类<br /> static class StudentComparator implements Comparator  //为了调用方便声明为静态的<br /> {<br />  public int compare(Object o1,Object o2)<br />  {<br />   Student s1 = (Student)o1;<br />   Student s2 = (Student)o2;<br />   int result=s1.num &gt; s2.num ? 1: (s1.num==s2.num ? 0 : -1);<br />   if(result==0)<br />   {<br />    return s1.name.compareTo(s2.name);<br />   }<br />   return result;<br />  }<br /> }<br /> Student(int num,String name)<br /> {<br />  this.num=num;<br />  this.name=name;<br /> }<br /> public int compareTo(Object o)<br /> {<br />  Student s=(Student)o;<br />  return num &gt; s.num ? 1 :( (num==s.num) ? 0 : -1);<br /> }<br /> <br /> public String toString()<br /> {<br />  return +num+":"+name;<br /> }<br />}</p>
<img src ="http://www.blogjava.net/dorydoo/aggbug/55382.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dorydoo/" target="_blank">多力宇扬</a> 2006-06-27 17:36 <a href="http://www.blogjava.net/dorydoo/archive/2006/06/27/55382.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java学习笔记-Runtime和Process类</title><link>http://www.blogjava.net/dorydoo/archive/2006/06/27/55379.html</link><dc:creator>多力宇扬</dc:creator><author>多力宇扬</author><pubDate>Tue, 27 Jun 2006 09:30:00 GMT</pubDate><guid>http://www.blogjava.net/dorydoo/archive/2006/06/27/55379.html</guid><wfw:comment>http://www.blogjava.net/dorydoo/comments/55379.html</wfw:comment><comments>http://www.blogjava.net/dorydoo/archive/2006/06/27/55379.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dorydoo/comments/commentRss/55379.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dorydoo/services/trackbacks/55379.html</trackback:ping><description><![CDATA[
		<p>&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;Runtime和Process类&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;<br />1&gt; 每一个Java程序都有一个Runtime类的单一实例。<br />2&gt; 通过Runtime.getRuntime()获取Runtime类的实例。<br />3&gt; Runtime类是使用单例模式的一个例子。<br />   Runtime没有public的构造方法。我们必须用Runtime的静态方法getRuntime();我们可以用<br />   Runtime的exec来执行一个外部程序，也可以用来编译一个源文件(用来做图形界面的编译器)。<br />import java.io.*;<br />class RuntimeTest<br />{<br /> public static void main(String[] args)<br /> {<br />  Runtime rt=Runtime.getRuntime();<br />  //System.out.println(rt.freeMemory());<br />  try<br />  {<br />   //rt.exec("notepad");<br />   Process p=rt.exec("java ArrayTest");<br />   InputStream is=p.getInputStream(); //从执行ArrayTest类所得来的<br />   int data;<br />   while((data=is.read())!=-1)<br />   {<br />    System.out.print((char)data);<br />   }<br />  }<br />  catch(Exception e)<br />  {<br />   e.printStackTrace();<br />  }<br /> }<br />}</p>
		<p>-------------&gt;&gt;设计模式&lt;&lt;-------------<br />1&gt; 在我们进行程序设计时,逐渐形成了一些典型问题和问题解决方案,这就是软件模式。<br />2&gt; 每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案。<br />3&gt; 当我们碰到模式所描述的问题，就可以直接用相应的解决方法去解决这个问题,这就是设计模式。<br />&lt;$&gt;单例(Singleton)模式<br />1&gt; 一个类只有一个实例，而且自行实例化并像整个系统提供这个实例，这个类称为单例类。<br />2&gt; 单例类的一个重要特点就是类的构造方法是私有的,从而避免了外部用利用构造方法直接创建多个实例。<br />   如:Runtime类。</p>
		<p>单例类的实现:(code)<br />class Singleton<br />{<br /> private static final Singleton st=new Singleton();<br /> private Singleton()<br /> {<br />  <br /> }<br /> public static Singleton getInstance()<br /> {<br />  return st;<br /> }<br />}</p>
<img src ="http://www.blogjava.net/dorydoo/aggbug/55379.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dorydoo/" target="_blank">多力宇扬</a> 2006-06-27 17:30 <a href="http://www.blogjava.net/dorydoo/archive/2006/06/27/55379.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java学习笔记-封装类&amp;&amp;Class</title><link>http://www.blogjava.net/dorydoo/archive/2006/06/27/55378.html</link><dc:creator>多力宇扬</dc:creator><author>多力宇扬</author><pubDate>Tue, 27 Jun 2006 09:29:00 GMT</pubDate><guid>http://www.blogjava.net/dorydoo/archive/2006/06/27/55378.html</guid><wfw:comment>http://www.blogjava.net/dorydoo/comments/55378.html</wfw:comment><comments>http://www.blogjava.net/dorydoo/archive/2006/06/27/55378.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dorydoo/comments/commentRss/55378.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dorydoo/services/trackbacks/55378.html</trackback:ping><description><![CDATA[
		<p>=============================封装类===============<br />针对八种基本数据类型定义的相应的引用类型-封装类(包装类，包裹类)<br />基本数据类型          封装类<br /> boolean               Boolean<br /> byte                  Byte<br /> short                 Short<br /> int                   Integer<br /> long                  Long<br /> char                  Character<br /> float                 Float<br /> double                Double<br />所有的封状类都是一个只读类（不能修改的).针对没个基本类型我们只能建立一个这读的。</p>
		<p>class Test<br />{<br /> public static void main(String[] args)<br /> {<br />  int i=3;<br />  Integer in=new Integer(i);<br />  int j=in.intValue();<br />  System.out.println(j);<br />  String str=in.toString();  //把Integer对象转换为String类型<br />  System.out.println("str="+str);<br />  <br />  String str1="123";<br />  System.out.println(Integer.valueOf(str1));  //把String类型转换为Integer类型<br />  <br />  boolean b1=false;<br />  Boolean b=new Boolean(b1);<br />  String s1=b.toString();<br />  System.out.println(s1);<br />  <br />  String s2="NO";<br />  System.out.println(Boolean.valueOf(s2));<br /> }<br />}</p>
		<p>*****************Class*********************<br />1&gt; 在Java中，每个class都有一个相应的Class对象。也就是说，当我们编写一个类，编译完成后,在生成<br />   的.class文件中,就会产生一个Class对象，用于表示这个类的类型信息。<br />2&gt; 获取Class实例的方法有三种:<br />   &lt;1&gt;利用对象调用getClass()方法获得该对象的Class实例。<br />   &lt;2&gt;使用Class类的静态方法forName(),用类的名字获取一个Class的是实例。<br />   &lt;3&gt;运用.class的方式来获取Class实例，对于基本数据类型的封装类，还可以用.TYPE来获取相应的<br />      基本数据类型的Class实例。<br />   &lt;4&gt;在运行期间，如果我们要产生某个类的对象，JAVA虚拟机(JVM)会检查该类型的Class对象是否被<br />      加载，如果没有加载,JVM会根据类的名称找到.class文件并加载它。一旦某个类型的Class对象已<br />      经被加载到内存，就可以用它来产生该类型所有的对象。<br />   &lt;5&gt;newInstance()调用类中缺省的构造方法。(好处是我们在不知道类的名字的情况下去创造一个实例）<br />import java.lang.reflect.*;       //子包必须手动导入<br />class ClassTest<br />{<br /> public static void main(String[] args)//throws Exception<br /> {<br />  /*<br />  Point pt=new Point();              <br />  Class c1=pt.getClass();//利用对象调用getClass()方法获得该对象的Class实例<br />  System.out.println(c1.getName());<br />  <br />  Class c2=Class.forName("Point");//使用Class类的静态方法forName(),用类的名字获取一个Class的是实例<br />  System.out.println(c2.getName());<br />  <br />  Class c3=Point.class;//运用.class的方式来获取Class实例<br />  System.out.println(c3.getName());<br />  <br />  Class c4=Integer.TYPE;//封装类用.TYPE来获取相应的基本数据类型的Class实例。<br />  System.out.println(c4.getName());<br />  */<br />  /*<br />  System.out.println("before new Point()");<br />  new Point();<br />  System.out.println("after new Point()");<br />  Class.forName("Line");<br />  */<br />  /*<br />  if(args.length!=1)<br />  {<br />   return;<br />  }<br />  try<br />  {<br />   Class c=Class.forName(args[0]);<br />   Point pt=(Point)c.newInstance();<br />   pt.output();<br />  }<br />  catch(Exception e)<br />  {<br />   e.printStackTrace();<br />  }<br />  */<br />  if(args.length!=1)<br />  {<br />   return;<br />  }<br />  try<br />  {<br />   Class c=Class.forName(args[0]);<br />   Constructor[] cons=c.getDeclaredConstructors();<br />   /*<br />   for(int i=0;i&lt;cons.length;i++)<br />   {<br />    System.out.println(cons[i]);<br />   }<br />   Method[] ms=c.getDeclaredMethods();<br />   for(int i=0;i&lt;ms.length;i++)<br />   {<br />    System.out.println(ms[i]);<br />   }*/<br />   Class[] params=cons[0].getParameterTypes();<br />   Object[] paramValues=new Object[params.length];<br />   for(int i=0;i&lt;params.length;i++)<br />   {<br />    if(params[i].isPrimitive())<br />    {<br />     paramValues[i]=new Integer(i+3);<br />    }<br />   }<br />   Object o=cons[0].newInstance(paramValues);<br />   Method[] ms=c.getDeclaredMethods();<br />   ms[0].invoke(o,null);<br />  }<br />  catch(Exception e)<br />  {<br />   e.printStackTrace();<br />  }<br />  <br /> }<br />}</p>
		<p>class Point<br />{<br /> static<br /> {<br />  System.out.println("Loading Point");<br /> }<br /> int x,y;<br /> void output()<br /> {<br />  System.out.println("x="+x+","+"y="+y);<br /> }<br /> Point(int x,int y)<br /> {<br />  this.x=x;<br />  this.y=y;<br /> }<br />}</p>
		<p>class Line<br />{<br /> static<br /> {<br />  System.out.println("Loading Line");<br /> }<br />}</p>
<img src ="http://www.blogjava.net/dorydoo/aggbug/55378.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dorydoo/" target="_blank">多力宇扬</a> 2006-06-27 17:29 <a href="http://www.blogjava.net/dorydoo/archive/2006/06/27/55378.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java学习笔记-函数的调用</title><link>http://www.blogjava.net/dorydoo/archive/2006/06/27/55377.html</link><dc:creator>多力宇扬</dc:creator><author>多力宇扬</author><pubDate>Tue, 27 Jun 2006 09:26:00 GMT</pubDate><guid>http://www.blogjava.net/dorydoo/archive/2006/06/27/55377.html</guid><wfw:comment>http://www.blogjava.net/dorydoo/comments/55377.html</wfw:comment><comments>http://www.blogjava.net/dorydoo/archive/2006/06/27/55377.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dorydoo/comments/commentRss/55377.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dorydoo/services/trackbacks/55377.html</trackback:ping><description><![CDATA[~~~~~~~~~~~~~~~~~~~~~~~~~~函数的调用~~~~~~~~~~~~~~~~~~~~<br />1&gt; 在java中，传参时，都是以传值的形式惊行。<br />2&gt; 对于基本数据类型，传递的是数据的拷贝，对于引用类型，传递的引用的拷贝。<br />3&gt; 当我们在打印一个对象的时候，比如System.out.println(pt);，它会自动调用类的toString()方法<br />   ，所以建议在所有的子类中重写toString()方法。<br />我们写一个函数用来交换两个变量(x,y)的值.<br /> code: <br />class StringTest<br />{<br /> public static void change(int x, int y)<br /> {<br />  x=x+y;<br />  y=x-y;<br />  x=x-y;<br /> }<br /> /*<br /> public static void change(int[] num)<br /> {<br />  num[0]=num[0]+num[1];<br />  num[1]=num[0]-num[1];<br />  num[0]=num[0]-num[1];<br /> }<br /> public static void change(Point pt)<br /> {<br />  pt.x=pt.x+pt.y;<br />  pt.y=pt.x-pt.y;<br />  pt.x=pt.x-pt.y;<br /> }<br /> */<br /> public static void main(String[] args)<br /> {<br /> int x=3;<br /> int y=4;<br /> change(3,4);<br /> System.out.println("x="+x+","+"y="+y);<br /> }<br />我们期望的输出结果是 x=4,y=3 然后你运行后发现结果为x=3,y=4,并没有达到我们的要求,为什么呢?那是因为对于基本数据类型，传递的是数据的拷贝，对于引用类型，传递的是引用(首地址)的拷贝。看看下面的内存图解应该你就能看出来了.看看引用类型怎么来实现:<br /><img src="http://tk.files.storage.msn.com/x1pIuxx1VYmtQswcHPAwKaQ-yrErau7hNtnGE6aUTj3uhpVNVypAIyC0UrmgrkQwbG_eWxcbHVi_BCUGixRsexXpmeQJm6kBIQwr0l3XGz-acoQqeNnnp3fc9gOVp8Wgp1PF3CsaXYcAgo" /><br />code:<br />class StringTest<br />{<br /> /*<br /> public static void change(int x, int y)<br /> {<br />  x=x+y;<br />  y=x-y;<br />  x=x-y;<br /> }<br /> */<br /> public static void change(int[] num)<br /> {<br />  num[0]=num[0]+num[1];<br />  num[1]=num[0]-num[1];<br />  num[0]=num[0]-num[1];<br /> }<br /> public static void change(Point pt)<br /> {<br />  pt.x=pt.x+pt.y;<br />  pt.y=pt.x-pt.y;<br />  pt.x=pt.x-pt.y;<br /> }<br /> public static void main(String[] args)<br /> {<br />  /*<br />   int x=3;<br />   int y=4;<br />   change(3,4);<br />   System.out.println("x="+x+","+"y="+y);<br />   */<br />   int[] num=new int[]{3,4};<br />   change(num);<br />   System.out.println("x="+num[0]+","+"y="+num[1]);<br />   <br />   Point pt=new Point();<br />   pt.x=3;<br />   pt.y=4;<br />   change(pt);<br />   System.out.println("x="+pt.x+","+"y="+pt.y);  <br /> }<br />class Point<br />{<br /> int x,y; <br />}<br />再看看引用类型的内存变化图:<br />以上说明了在Java中函数的调用:<br />a&gt; 在Java中，传参时，都是以传值的方式进行。<br />b&gt; 对于基本数据类型，传递的是数据的拷贝，对于引用类型，传递的是引用(首地址)的拷贝。<br /><img src="http://tk.files.storage.msn.com/x1pIuxx1VYmtQswcHPAwKaQ-7C6SaJ0CDgh0i6Ffe25lVLAiy7Nci0TffWpKmDJpM6A-jnNv27Y7frfbCio6LLPC0XSGd8QgC9wURobXzsyHEL22atxDMfr9JmxzYvdXEw2B4ptqO-QF4I" /><img src ="http://www.blogjava.net/dorydoo/aggbug/55377.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dorydoo/" target="_blank">多力宇扬</a> 2006-06-27 17:26 <a href="http://www.blogjava.net/dorydoo/archive/2006/06/27/55377.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java学习笔记-对象克隆</title><link>http://www.blogjava.net/dorydoo/archive/2006/06/27/55374.html</link><dc:creator>多力宇扬</dc:creator><author>多力宇扬</author><pubDate>Tue, 27 Jun 2006 09:24:00 GMT</pubDate><guid>http://www.blogjava.net/dorydoo/archive/2006/06/27/55374.html</guid><wfw:comment>http://www.blogjava.net/dorydoo/comments/55374.html</wfw:comment><comments>http://www.blogjava.net/dorydoo/archive/2006/06/27/55374.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dorydoo/comments/commentRss/55374.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dorydoo/services/trackbacks/55374.html</trackback:ping><description><![CDATA[
		<p>^^^^^^^^^^^^^^^对象的克隆^^^^^^^^^^^^^<br />1&gt; 为了获取对象的一份拷贝，我们可以利用Object类的clone()方法。<br />2&gt; 在派生类中覆盖基类的clone()，并声明为public。<br />3&gt; 在派生类的clone()方法中，调用super.clone()。<br />4&gt; 在派生类中实现Cloneable接口。<br />4&gt; 没有抽象方法的接口叫标识接口。<br />5&gt; 为什么我们在派生类中覆盖Object的clone()方法时,一定要调用super.clone()呢?在运行时刻,Object 的clone()方法能识别出你要复制的是哪一个对象，然后为此对象分配空间，并进行对象的复制，将原 始对象的内容一一复制到新的对象空间去。<br /><br />* 浅克隆是针对没有引用类型的变量来克隆。针对引用类型的克隆应该用Deeply Clone。<br />浅克隆:<br />Code:<br />class FleetClone<br />{<br /> public static void main(String[] args)<br /> {<br />   Professor p=new Professor("feiyang",23);<br />   Student s1=new Student("zhangshan",18,p);<br />   Student s2=(Student)s1.clone();<br />   s2.p.name="feifei";<br />   s2.p.age=30;<br />   System.out.println("name="+s1.p.name+","+"age="+s1.p.age);<br /> }<br />}<br />class Professor<br />{<br /> String name;<br /> int age;<br /> Professor(String name,int age)<br /> {<br />  this.name=name;<br />  this.age=age;<br /> }<br />}</p>
		<p>class Student implements Cloneable<br />{<br /> Professor p;<br /> String name;<br /> int age;<br /> Student(String name, int age,Professor p)<br /> {<br />  this.name=name;<br />  this.age=age;<br />  this.p=p;<br /> }<br /> public Object clone()<br /> {<br />  Object o=null;<br />  try<br />  {<br />   o=super.clone();<br />  }<br />  catch(CloneNotSupportedException e)<br />  {<br />   e.printStackTrace();<br />  }<br />  return o;<br /> }<br />}<br />改变学生s2的教授信息，打印s1教授信息,结果为:name=feifei,age=30.产生这个结果是因为String是一个常量类型.<br /> <br />深克隆<br />code:<br />class DeeplyClone<br />{<br /> public static void main(String[] args)<br /> {<br />   Professor p=new Professor("feiyang",23);<br />   Student s1=new Student("zhangshan",18,p);<br />   Student s2=(Student)s1.clone();<br />   s2.p.name="Bill.Gates";<br />   s2.p.age=30;<br />   System.out.println("name="+s1.p.name+","+"age="+s1.p.age);<br /> }<br />}<br />class Professor implements Cloneable<br />{<br /> String name;<br /> int age;<br /> Professor(String name,int age)<br /> {<br />  this.name=name;<br />  this.age=age;<br /> }<br /> public Object clone()<br /> {<br />  Object o=null;<br />  try<br />  {<br />   o=super.clone();<br />  }<br />  catch(CloneNotSupportedException e)<br />  {<br />   e.printStackTrace();<br />  }<br />  return o;<br /> }<br />}</p>
		<p>class Student implements Cloneable<br />{<br /> Professor p;<br /> String name;<br /> int age;<br /> Student(String name, int age,Professor p)<br /> {<br />  this.name=name;<br />  this.age=age;<br />  this.p=p;<br /> }<br /> public Object clone()<br /> {<br />  //Object o=null;<br />  Student o=null;<br />  try<br />  {<br />   o=(Student)super.clone();<br />  }<br />  catch(CloneNotSupportedException e)<br />  {<br />   e.printStackTrace();<br />  }<br />  o.p=(Professor)p.clone();<br />  return o;<br /> }<br />}<br />打印结果为:name=Bill.Gates,age=30,这就是深克隆.</p>
<img src ="http://www.blogjava.net/dorydoo/aggbug/55374.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dorydoo/" target="_blank">多力宇扬</a> 2006-06-27 17:24 <a href="http://www.blogjava.net/dorydoo/archive/2006/06/27/55374.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java学习笔记-数组</title><link>http://www.blogjava.net/dorydoo/archive/2006/06/27/55372.html</link><dc:creator>多力宇扬</dc:creator><author>多力宇扬</author><pubDate>Tue, 27 Jun 2006 09:22:00 GMT</pubDate><guid>http://www.blogjava.net/dorydoo/archive/2006/06/27/55372.html</guid><wfw:comment>http://www.blogjava.net/dorydoo/comments/55372.html</wfw:comment><comments>http://www.blogjava.net/dorydoo/archive/2006/06/27/55372.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dorydoo/comments/commentRss/55372.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dorydoo/services/trackbacks/55372.html</trackback:ping><description><![CDATA[
		<p>Java数组的相关操作</p>
		<p>1&gt; 在Java中所有的数组都有一个缺省的属性length，用于获取数组元素的个数。<br />2&gt; 数组的复制: System.arraycopy()。<br />3&gt; 数组的排序: Arrays.sort()。<br />4&gt; 在已排序的数组中查找某个元素：Arrays.binarySearch()。<br />具体的看看下面的2个例子:<br />code1:<br />class ArrayTest<br />{<br /> public static void main(String[] args)<br /> {<br />  /*数组的copy<br />  int[] num1=new int[]{1,2,3};<br />  int[] num2=new int[3];<br />  System.arraycopy(num1,0,num2,0,num1.length);<br />  for(int i=0;i&lt;num2.length;i++)<br />  {<br />   System.out.println(num2[i]);<br />  }<br />  */<br />  //引用类型的数组copy<br />  Point[] pts1=new Point[]{new Point(1,1),new Point(2,2),new Point(3,3)};<br />  Point[] pts2=new Point[3];<br />  System.arraycopy(pts1,0,pts2,0,pts1.length);<br />  for(int i=0;i&lt;pts2.length;i++)<br />  {<br />   System.out.println("x="+pts2[i].x+","+"y="+pts2[i].y);<br />  }<br />  /*<br />  *因为引用类型传递的是引用的拷贝，所以我们修改pts2数组的第二个点的坐标，<br />  *当我们打印pts1数组的第一个点的坐标时，它的坐标点已经被修改为(5,5)了<br />  pts2[1].x=5;<br />  pts2[1].y=5;<br />  System.out.println("x="+pts1[1].x+","+"y="+pts1[1].y);<br />  */<br /> }<br />}</p>
		<p>class Point<br />{<br /> int x, y;<br /> Point(int x,int y)<br /> {<br />  this.x=x;<br />  this.y=y;<br /> }<br />}</p>
		<p>
				<br />code2:<br />import java.util.*;<br />class TestArray<br />{<br /> public static void main(String[] args)<br /> {<br />  /*<br />  int[] num=new int[]{3,2,1};<br />  Arrays.sort(num);<br />  for(int i=0;i&lt;num.length;i++)<br />  {<br />   System.out.println(num[i]);<br />  }<br />  int index=Arrays.binarySearch(num,3);<br />  System.out.println("index="+index);<br />  System.out.println("Element="+num[index]);<br />  */<br />  Student[] ss=new Student[]{new Student("zhangshan",1),<br />                            new Student("lisi",2),<br />                            new Student("wangwu",3),<br />                            new Student("mybole",3)};<br />   Arrays.sort(ss);<br />   for(int i=0;i&lt;ss.length;i++)<br />   {<br />    System.out.println(ss[i]);<br />   }<br />   int index=Arrays.binarySearch(ss,new Student("lisi",2));<br />   System.out.println("name="+ss[index].name+","+"index="+index);<br /> }<br />}</p>
		<p>class Student implements Comparable<br />{<br /> String name;<br /> int num;<br /> Student(String name,int num)<br /> {<br />  this.name=name;<br />  this.num=num;<br /> }<br /> public String toString()<br /> {<br />  return "name="+name+","+"number="+num;<br /> }<br /> public int compareTo(Object o)  //对于Object[]排序要求实现Comparable接口<br /> {<br />  Student s=(Student)o;<br />  //return num&gt;s.num ? 1 :(num==s.num ? 0 : -1);<br />  int result=num&gt;s.num ? 1 :(num==s.num ? 0 : -1);//按名字排序<br />  if(0==result)<br />  {<br />   result=name.compareTo(s.name);<br />  }<br />  return result;<br /> }<br />}</p>
<img src ="http://www.blogjava.net/dorydoo/aggbug/55372.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dorydoo/" target="_blank">多力宇扬</a> 2006-06-27 17:22 <a href="http://www.blogjava.net/dorydoo/archive/2006/06/27/55372.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java学习笔记-继承,多态</title><link>http://www.blogjava.net/dorydoo/archive/2006/06/27/55370.html</link><dc:creator>多力宇扬</dc:creator><author>多力宇扬</author><pubDate>Tue, 27 Jun 2006 09:20:00 GMT</pubDate><guid>http://www.blogjava.net/dorydoo/archive/2006/06/27/55370.html</guid><wfw:comment>http://www.blogjava.net/dorydoo/comments/55370.html</wfw:comment><comments>http://www.blogjava.net/dorydoo/archive/2006/06/27/55370.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dorydoo/comments/commentRss/55370.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dorydoo/services/trackbacks/55370.html</trackback:ping><description><![CDATA[
		<p>理解继承是理解面向对象程序设计的关键.在Java中,通过关键字extends继承一个已有的类,被继承的类称为父类(超类，基类),新的类称为子类(派生类).在Java中不允许多继承.code:<br />class Animal<br />{<br /> int height,weight;<br /> void eat()<br /> {<br />  System.out.println("Animal eat!");<br /> }<br /> void sleep()<br /> {<br />  System.out.println("Animal sleep!");<br /> }<br /> void breathe()<br /> {<br />  System.out.println("Animal breathe!");<br /> }<br />}<br />class Fish extends Animal<br />{<br /> <br />}<br />class DoMain<br />{<br /> public static void main(String[] args)<br /> {<br />  Animal an=new Animal();<br />  Fish fn=new Fish();<br />  <br />  an.breathe();<br />  fn.breathe();<br />  fn.height=30;<br />  fn.weight=20;<br /> }<br />}<br />Result:<br />F:\Java Develop&gt;javac Animal.java</p>
		<p>F:\Java Develop&gt;java DoMain<br />Animal breathe!<br />Animal breathe!<br />(这说明派生类继承了父类的所有方法和成员变量.)</p>
		<p>方法的覆盖(override)<br />在子类中定义一个与父类同名,返回类型,参数类型均相同的一个方法,称为方法的覆盖,方法的覆盖发生在子类与父类之间.<br />code:<br />class Animal<br />{<br /> int height,weight;<br /> void eat()<br /> {<br />  System.out.println("Animal eat!");<br /> }<br /> void sleep()<br /> {<br />  System.out.println("Animal sleep!");<br /> }<br /> void breathe()<br /> {<br />  System.out.println("Animal breathe!");<br /> }<br />}<br />class Fish extends Animal<br />{<br /> int weight,height;   //隐藏了父类的weight,height;<br /> void breathe()  //override method breathe()<br /> {<br />  super.breathe();  //用super调用父类的构造方法<br />  System.out.println("Fish bubble");<br /> }<br />}<br />class DoMain<br />{<br /> public static void main(String[] args)<br /> {<br /> // Animal an=new Animal();<br />  Fish fn=new Fish();<br />  <br />  an.breathe();<br />  fn.breathe();<br />  fn.height=30;<br />  fn.weight=20;<br /> }<br />}<br />输出结果:<br />F:\Java Develop&gt;javac Animal.java</p>
		<p>F:\Java Develop&gt;java DoMain<br />Animal breathe!<br />Fish bubble</p>
		<p>特殊变量super<br />* 使用特殊变量super提供对父类的访问<br />* 可以使用super访问父类被子类隐藏的变量或覆盖的方法<br />* 每个子类构造方法的第一条语句都是隐含的调用super,如果父类没有这种形式的构造函数就会报错.<br />code:<br />class Animal<br />{<br /> int height,weight;<br /> Animal()<br /> {<br />  System.out.println("Animal construct");<br /> }<br /> void eat()<br /> {<br />  System.out.println("Animal eat!");<br /> }<br /> void sleep()<br /> {<br />  System.out.println("Animal sleep!");<br /> }<br /> void breathe()<br /> {<br />  System.out.println("Animal breathe!");<br /> }<br />}</p>
		<p>class Fish extends Animal<br />{<br /> Fish()<br /> {<br />  System.out.println("Fish construct");<br /> }<br /> void breathe()  //override method breathe()<br /> {<br />  System.out.println("Fish bubble");<br /> }<br />}<br />class DoMain<br />{<br /> public static void main(String[] args)<br /> {<br />  //Animal an=new Animal();<br />  Fish fn=new Fish();<br />  <br />  //an.breathe();<br />  //fn.breathe();<br />  //fn.height=30;<br />  //fn.weight=20;<br /> }<br />}<br />输出结果:<br />F:\Java Develop&gt;javac Animal.java</p>
		<p>F:\Java Develop&gt;java DoMain<br />Animal construct<br />Fish construct<br /><br /><br /><br /> 通过覆盖父类的方法来实现,在运行时根据传递对象的引用,来调用相应的方法.<br />code:<br />class Animal<br />{<br /> int height,weight;<br /> Animal()<br /> {<br />  System.out.println("Animal construct");<br /> }<br /> void eat()<br /> {<br />  System.out.println("Animal eat!");<br /> }<br /> void sleep()<br /> {<br />  System.out.println("Animal sleep!");<br /> }<br /> void breathe()<br /> {<br />  System.out.println("Animal breathe!");<br /> }<br />}</p>
		<p>class Fish extends Animal<br />{<br /> Fish()<br /> {<br />  System.out.println("Fish construct");<br /> }<br /> void breathe()  //override method breathe()<br /> {<br />  System.out.println("Fish bubble");<br /> }<br />}<br />class DoMain<br />{<br /> static void fn(Animal an)<br /> {<br />  an.breathe();<br /> }<br /> public static void main(String[] args)<br /> {<br />  //Animal an=new Animal();<br />  Fish fh=new Fish();<br />  Animal an;<br />  an=fh;<br />  DoMain.fn(an);<br /> }<br />}</p>
<img src ="http://www.blogjava.net/dorydoo/aggbug/55370.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dorydoo/" target="_blank">多力宇扬</a> 2006-06-27 17:20 <a href="http://www.blogjava.net/dorydoo/archive/2006/06/27/55370.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java学习笔记-类的定义</title><link>http://www.blogjava.net/dorydoo/archive/2006/06/27/55369.html</link><dc:creator>多力宇扬</dc:creator><author>多力宇扬</author><pubDate>Tue, 27 Jun 2006 09:19:00 GMT</pubDate><guid>http://www.blogjava.net/dorydoo/archive/2006/06/27/55369.html</guid><wfw:comment>http://www.blogjava.net/dorydoo/comments/55369.html</wfw:comment><comments>http://www.blogjava.net/dorydoo/archive/2006/06/27/55369.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dorydoo/comments/commentRss/55369.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dorydoo/services/trackbacks/55369.html</trackback:ping><description><![CDATA[从今天开始从零学习JAVA,希望可以认识到更多的朋友,可以让自己的JAVA之路走得更为顺利一些!买了几本书来看也听了几接课,觉得JAVA很吸引我,我想我可以走得更远的.自信是最重要的.<br />    OOP(Object Oriented Programming)描述的是对象与对象之间的相互作用.听老师将面向过程与面向对象的最大区别是: 过程化程序设计先确定算法,再确定数据结构,再确定运算.面向过程编程,习惯于先建立数据结构存放数据并定义方法(函数)来操作数据;而面向对象的则是构建一个模型,将数据与方法组织在一起.<br />    我们可以把现实世界的事物抽象为对象.对象一般都有两个特征:状态(Status),行为(Behavior).软件的对象概念是由显示世界对象抽象而来.把现实世界的状态保存软件对象的变量中;现实世界对象的行为通过软件对象的方法(函数)来实现.<br />    我们把相似的对象划分成一个类.在软件中类就是一个模板,它定义了通用于一个特定种类的所有对象的状态(变量)和行为(方法).类是创建对象的模板,对象是类的实例.<br />    面向对象编程的难点在于思路的转变.我们通常习惯与考虑解决问题的方法，而不是抽象成对象再去解决它.<br /> 类的构造方法<br />* 构造方法的名字和类名相同,并且没有返回值.<br />* 构造方法主要用于定义类的初始化状态.<br />* 我们不能直接调用构造方法,必须通过new关键字来自动调用,从而创建类的实例.<br />* Java的类都要求有构造方法,如果没有定义构造方法,Java编译器会提供一个缺省的构造方法,也就是不参数的构造方法.<br />方法的重载(overload)<br /> 重载构成的条件:方法的名称相同,但参数类型或参数个数不同,才能构成方法的重载.<br />code:<br />class Point<br />{<br /> int x,y;<br /> /*<br />  *带参数的构造方法和不带参数的构造方法就构成了方法(函数)的重载<br /> */<br /> Point(int a,int b)<br /> {<br />  x=a;<br />  y=b;<br /> }<br /> Point()<br /> {<br />  <br /> }<br /> void output()<br /> {<br />  System.out.println(x);<br />  System.out.println(y);<br /> }<br /> public static void main(String[] args)<br /> {<br />  //调用不带参数的构造方法<br />  //Point p=new Point();<br />  //pt.x=10;<br />  //pt.y=20;<br />  //p.output();<br />  Point p1=new Point(3,3); //调用带参数的构造方法<br />  p1.output();<br /> }<br />}<br />特殊变量this<br />* this变量代表对象本身<br />* 当类中有两个同名变量,一个属于类(类的成员变量),一个属于某个特定的方法(方法中的局部变量),使用this区分成员变量和局部变量.<br />* 使用this简化构造函数的调用<br />code:<br />class Point<br />{<br /> int x,y;<br /> /*<br />  *带参数的构造方法和不带参数的构造方法就构成了方法(函数)的重载<br /> */<br /> Point(int a,int b)<br /> {<br />  x=a;<br />  y=b;<br /> }<br /> Point()<br /> {<br />  this(1,1);<br /> }<br /> void output()<br /> {<br />  System.out.println(x);<br />  System.out.println(y);<br /> }<br /> /*output()方法定义的形参与成员变量同名了，<br /> *那么在output()里就看不到成员变量的x,y了，它被隐藏了.<br /> */<br /> void output(int x, int y)<br /> {<br />  this.x=x;<br />  this.y=y;<br /> }<br /> public static void main(String[] args)<br /> {<br />  Point pt=new Point(3,3);<br />  pt.output(5,5);<br />  pt.output();<br /> }<br />}<br />一个类所有的实例(对象)调用的成员方法在内存中只有一份拷贝,尽管在内存中可能有多个对象,而数据成员在内的没个对象中都存在着一份拷贝.this变量允许相同的实例方法为不同的对象工作.每当调用一个实例方法时,this变量被设置成引用该实例方法的特定的类的对象.方法的代码接着会与this所代表的对象的特定数据建立关联.<img src ="http://www.blogjava.net/dorydoo/aggbug/55369.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dorydoo/" target="_blank">多力宇扬</a> 2006-06-27 17:19 <a href="http://www.blogjava.net/dorydoo/archive/2006/06/27/55369.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA程序员面试32问</title><link>http://www.blogjava.net/dorydoo/archive/2006/06/27/55368.html</link><dc:creator>多力宇扬</dc:creator><author>多力宇扬</author><pubDate>Tue, 27 Jun 2006 09:15:00 GMT</pubDate><guid>http://www.blogjava.net/dorydoo/archive/2006/06/27/55368.html</guid><wfw:comment>http://www.blogjava.net/dorydoo/comments/55368.html</wfw:comment><comments>http://www.blogjava.net/dorydoo/archive/2006/06/27/55368.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dorydoo/comments/commentRss/55368.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dorydoo/services/trackbacks/55368.html</trackback:ping><description><![CDATA[
		<p>JAVA 程序员面试 32 问 </p>
		<p>第一，谈谈 final ， finally ， finalize 的区别？ <br /><br />Final ：修饰符（关键字）如果一个类被声明为 final ，意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract 的，又被声明为 final 的。将变 量或方法声明为 final ，可以保证它们在使用中不被改变。被声明为 final 的变量必须在声 明时给定初值，而在以后的引用中只能读取，不可修改。被声明为 final 的方法也同样只能 使用，不能重载 finally ？再异常处理时提供 finally{} 块来执行任何清除操作。如果抛出一个异常，那么 相匹配的 catch 子句就会执行，然后控制就会进入 finally 块（如果有的话）。 finalize ：方法名。 Java 技术允许使用 finalize （）方法在垃圾收集器将对象从内存中 <br />清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时 对这个对象调用的。它是在 Object 类中定义的，因此所有的类都继承了它。子类覆盖 fi nalize （）方法以整理系统资源或者执行其他清理工作。 finalize （） 方法是在垃圾收集 器删除对象之前对这个对象调用的。<br /> </p>
		<p>第二， Anonymous Inner Class （匿名内部类） 是否可以 extends （继承）其它类，是否 可以 implements （实现） interface （接口）？ <br /><br />匿名的内部类是没有名字的内部类。不能 extends （继承） 其它类，但一个内部类可以作 为一个接口，由另一个内部类实现。 </p>
		<p>第三， Static Nested Class 和 Inner Class 的不同，说得越多越好（面试题有的很笼统）？<br /> <br />Nested Class （一般是 C++ 的说法）， Inner Class （一般是 JAVA 的说法）。 Java 内部类 <br />与 C++ 嵌套类最大的不同就在于是否有指向外部的引用上。 <br />具体可见 http ： //www.frontfree.net/articles/services/view.asp ?id=704&amp;page=1  注:静态内部类（ Inner Class ）意味着 1 创建一个 static 内部类的对象，不需要一个外部类对象,2 不能从一个 static 内部类的一个对象访问一个外部类对象。 </p>
		<p>第四， &amp; 和 &amp;&amp; 的区别？<br /> <br />&amp; 是位运算符。 &amp;&amp; 是布尔逻辑运算符。 </p>
		<p>第五， HashMap 和 Hashtable 的区别？<br /> <br />都属于 Map 接口的类，实现了将惟一键映射到特定的值上。 HashMap 类没有分类或者排序。它允许一个 null 键和多个 null 值。 Hashtable 类似于 HashMap ，但是不允许 null 键和 null 值。它也比 HashMap 慢，因为 它是同步的。 </p>
		<p>第六， Collection 和 Collections 的区别？ <br /><br />Collections 是个 java.util 下的类，它包含有各种有关集合操作的静态方法.Collection 是个 java.util 下的接口，它是各种集合结构的父接口。 </p>
		<p>第七，什么时候用 assert ？ <br /><br />断言是一个包含布尔表达式的语句，在执行这个语句时假定该表达式为 true 。如果表达式 计算为false ，那么系统会报告一个 AssertionError 。它用于调试目的:assert(a &gt; 0); // throws an AssertionError if a &lt;= 0 ： 断言可以有两种形式： <br />assert Expression1 ; <br />assert Expression1 : Expression2 ; <br />Expression1 应该总是产生一个布尔值。 <br />Expression2 可以是得出一个值的任意表达式。这个值用于生成显示更多调试信息的 Str ing 消息.断言在默认情况下是禁用的。要在编译时启用断言，需要使用 source 1.4 标记： <br />javac -source 1.4 Test.java <br />要在运行时启用断言，可使用 -enableassertions 或者 -ea 标记。 <br />要在运行时选择禁用断言，可使用 -da 或者 -disableassertions 标记。 <br />要系统类中启用断言，可使用 -esa 或者 -dsa 标记。还可以在包的基础上启用或者禁用 断言.可以在预计正常情况下不会到达的任何位置上放置断言。断言可以用于验证传递给私有方法的参数。不过，断言不应该用于验证传递给公有方法的参数，因为不管是否启用了断言 ，公有方法都必须检查其参数。不过，既可以在公有方法中，也可以在非公有方法中利用 断言测试后置条件。另外，断言不应该以任何方式改变程序的状态。 </p>
		<p>第八， GC 是什么 ? 为什么要有 GC? ( 基础 ) ？ <br /><br />GC 是垃圾收集器。 Java 程序员不用担心内存管理，因为垃圾收集器会自动进行管理。要请求垃圾收集，可以调用下面的方法之一：<br />System.gc() <br /> Runtime.getRuntime().gc() </p>
		<p>第九， String s = new String("xyz"); 创建了几个 String Object? <br />两个对象，一个是 “xyx”, 一个是指向 “xyx” 的引用对象 s 。 <br /></p>
		<p>第十， Math.round(11.5) 等於多少 ? Math.round(-11.5) 等於多少 ? <br />Math.round(11.5) 返回（ long ） 12 ， Math.round(-11.5) 返回（ long ） -11; <br /></p>
		<p>第十一， short s1 = 1; s1 = s1 + 1; 有什么错 ? short s1 = 1; s1 += 1; 有什么错 ? </p>
		<p>short s1 = 1; s1 = s1 + 1; 有错， s1 是 short 型， s1+1 是 int 型 , 不能显式转化为 short 型.可修改为 <br />s1 =(short)(s1 + 1) 。 short s1 = 1; s1 += 1 正确。 </p>
		<p>第十二， sleep() 和 wait() 有什么区别 ? <br />搞线程的最爱 sleep() 方法是使线程停止一段时间的方法。在 sleep 时间间隔期满后，线程不一定立即恢复执行。这是因为在那个时刻，其它线程可能正在运行而且没有被调度为放弃执行，除非 (a)“ 醒来 ” 的线程具有更高的优先级， (b) 正在运行的线程因为其它原因 而阻塞。wait() 是线程交互时，如果线程对一个同步对象 x 发出一个 wait() 调用，该线程会暂停执行，被调对象进入等待状态，直到被唤醒或等待时间到。 </p>
		<p>第十三， Java 有没有 goto? <br />Goto?java 中的保留字，现在没有在 java 中使用。 </p>
		<p>第十四，数组有没有 length() 这个方法 ? String 有没有 length() 这个方法？ <br />数组没有 length() 这个方法，有 length 的属性。 <br />String 有有 length() 这个方法。 </p>
		<p>第十五， Overload 和 Override 的区别。 Overloaded 的方法是否可以改变返回值的类型 ? </p>
		<p>方法的重写 Overriding 和重载 Overloading 是 Java 多态性的不同表现。重写 Overriding 是父类与子类之间多态性的一种表现，重载 Overloading 是一个类中多态性的一种表现。如果在 子类中定义某方法与其父类有相同的名称和参数，我们说该方法被重写 (Overriding) 。子类的对象使用这个方法时，将调用子类中的定义，对它而言，父类中的定义如同被 “ 屏蔽” 了。如果在一个类中定义了多个同名的方法，它们或有不同的参数个数或有不同的参数 类型，则称为方法的重载 (Overloading) 。 Overloaded 的方法是可以改变返回值的类型。 </p>
		<p>
				<br />第十六， Set 里的元素是不能重复的，那么用什么方法来区分重复与否呢 ? 是用 == 还是 equ <br />als()? 它们有何区别 ? <br />Set 里的元素是不能重复的，那么用 iterator() 方法来区分重复与否。 equals() 是判读两个Set 是否相等。 <br />equals() 和 == 方法决定引用值是否指向同一对象 equals() 在类中被覆盖，为的是当两个分离的对象的内容和类型相配的话，返回真值。 </p>
		<p>第十七，给我一个你最常见到的 runtime exception ？ <br />ArithmeticException, ArrayStoreException, BufferOverflowException, <br />BufferUnderflowException, CannotRedoException, <br />CannotUndoException, ClassCastException, CMMException, <br />ConcurrentModificationException, <br />DOMException, EmptyStackException, IllegalArgumentException, <br />IllegalMonitorStateException, <br />IllegalPathStateException, IllegalStateException, <br />ImagingOpException, <br />IndexOutOfBoundsException, MissingResourceException, <br />NegativeArraySizeException, NoSuchElementException, <br />NullPointerException, ProfileDataException, ProviderException, <br />RasterFormatException, SecurityException, SystemException, <br />UndeclaredThrowableException, <br />UnmodifiableSetException, UnsupportedOperationException </p>
		<p>第十八， error 和 exception 有什么区别 ? <br />error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况. </p>
		<p>第十九， List, Set, Map 是否继承自 Collection 接口 ? <br />List ， Set 是.Map 不是 </p>
		<p>第二十， abstract class 和 interface 有什么区别 ? </p>
		<p>声明方法的存在而不去实现它的类被叫做抽象类（ abstract class ），它用于要创建一个体现某些基本行为的类，并为该类声明方法，但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量，其类型是一个抽象类，并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。 Abstract 类的子类为它们父类中的所 有抽象方法提供实现，否则它们也是抽象类为。取而代之，在子类中实现该方法。知道其 行为的其它类可以在类中实现这些方法。<br />接口（ interface ）是抽象类的变体。在接口中，所有方法都是抽象的。多继承性可通过实 现这样的接口而获得。接口中的所有方法都是抽象的，没有一个有程序体。接口只可以定 义 static final 成员变量。接口的实现与子类相似，除了该实现类不能从接口定义中继承 行为。当类实现特殊接口时，它定义（即将程序体给予）所有这种接口的方法。然后，它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类，它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换， instanceof 运算符可以用来决定某对象的类是否实现了接口。 </p>
		<p>第二十一， abstract 的 method 是否可同时是 static, 是否可同时是 native ，是否可同时是 s <br />ynchronized? <br />都不能 </p>
		<p>第二十二,接口是否可继承接口?抽象类是否可实现 (implements) 接口?抽象类是否可继承实体类 (concrete class)? <br /><br />接口可以继承接口。抽象类可以实现 (implements) 接口，抽象类是否可继承实体类，但前提是实体类必须有明确的构造函数。 </p>
		<p>第二十三，启动一个线程是用 run() 还是 start()? <br />启动一个线程是调用 start() 方法，使线程所代表的虚拟处理机处于可运行状态，这意味着它可以由 JVM 调度并执行。这并不意味着线程就会立即运行。 run() 方法可以产生必须退出 的标志来停止一个线程。 </p>
		<p>
				<br />第二十四，构造器 Constructor 是否可被 override? <br />构造器 Constructor 不能被继承，因此不能重写 Overriding ，但可以被重载 Overloading 。 </p>
		<p>
				<br />第二十五，是否可以继承 String 类 ? <br />String 类是 final 类故不可以继承。 </p>
		<p>第二十六，当一个线程进入一个对象的一个synchronized 方法后,其它线程是否可进入此对象的其它方法?<br />不能，一个对象的一个 synchronized 方法只能由一个线程访问。 </p>
		<p>第二十七，try {} 里有一个 return 语句，那么紧跟在这个 try 后的 finally {} 里的 code 会不会被执行,什么时候被执行，在 return 前还是后 ? <br />会执行，在 return 前执行。 </p>
		<p>第二十八，编程题 : 用最有效率的方法算出 2 乘以 8 等於几 ? <br />有 C 背景的程序员特别喜欢问这种问题。 <br />2 &lt;&lt; 3 </p>
		<p>第二十九，两个对象值相同 (x.equals(y) == true) ，但却可有不同的 hash code ，这句话 <br />对不对 ? <br />不对，有相同的 hash code 。 </p>
		<p>第三十，当一个对象被当作参数传递到一个方法后，此方法可改变这个对象的属性，并可返回变化后的结果，那么这里到底是值传递还是引用传递 ? 是值传递。 Java 编程语言只由值传递参数。当一个对象实例作为一个参数被传递到方法中时，参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变，但对象的引用是永远不会改变的。 </p>
		<p>第三十一， swtich 是否能作用在 byte 上，是否能作用在 long 上，是否能作用在 String 上 ? </p>
		<p>switch （ expr1 ）中， expr1 是一个整数表达式。因此传递给 switch 和 case 语句的参数应该是 int 、 short 、 char 或者 byte 。 long,string 都不能作用于 swtich 。 </p>
		<p>第三十二，编程题 : 写一个 Singleton 出来？ <br />Singleton 模式主要作用是保证在 Java 应用程序中，一个类 Class 只有一个实例存在。 </p>
		<p>一般 Singleton 模式通常有几种种形式 : <br />第一种形式 : 定义一个类，它的构造函数为 private 的，它有一个 static 的 private 的该类变量，在类初始化时实例话，通过一个 public 的 getInstance 方法获取对它的引用 , 继而调用其中的方法。 <br />public class Singleton { <br />private Singleton(){} <br />// 在自己内部定义自己一个实例，是不是很奇怪？ <br />// 注意这是 private 只供内部调用 <br />private static Singleton instance = new Singleton(); <br />// 这里提供了一个供外部访问本 class 的静态方法，可以直接访问 <br />public static Singleton getInstance() { <br />　　 return instance; 　　 <br />} <br />} </p>
		<p>第二种形式 : </p>
		<p>public class Singleton { <br />private static Singleton instance = null; <br />public static synchronized Singleton getInstance() { <br />// 这个方法比上面有所改进，不用每次都进行生成对象，只是第一次　　　 　 <br />// 使用时生成实例，提高了效率！ <br />if (instance==null) <br />　　 instance ＝ new Singleton(); <br />return instance; 　　 } <br />} </p>
		<p>其他形式 : <br />定义一个类，它的构造函数为 private 的，所有方法为 static 的。 <br />一般认为第一种形式要更加安全些 </p>
		<p>第三十三 Hashtable 和 HashMap ？ <br />Hashtable 继承自 Dictionary 类，而 HashMap 是 Java1.2 引进的 Map interface 的一个实现 </p>
		<p>HashMap 允许将 null 作为一个 entry 的 key 或者 value ，而 Hashtable 不允许还有就是， HashMap 把 Hashtable 的 contains 方法去掉了,改成 containsvalue 和 containsKey.因为contains 方法容易让人引起误解。 </p>
		<p>最大的不同是,Hashtable 的方法是Synchronize 的,而HashMap 不是，在多个线程访问 Hashtable 时，不需要自己为它的方法实现同步，而 HashMap 就必须为之提供外同步.Hashtable 和 HashMap 采用的 hash/rehash 算法都大概一样，所以性能不会有很大的差异。</p>
<img src ="http://www.blogjava.net/dorydoo/aggbug/55368.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dorydoo/" target="_blank">多力宇扬</a> 2006-06-27 17:15 <a href="http://www.blogjava.net/dorydoo/archive/2006/06/27/55368.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>找零</title><link>http://www.blogjava.net/dorydoo/archive/2006/06/27/55357.html</link><dc:creator>多力宇扬</dc:creator><author>多力宇扬</author><pubDate>Tue, 27 Jun 2006 09:03:00 GMT</pubDate><guid>http://www.blogjava.net/dorydoo/archive/2006/06/27/55357.html</guid><wfw:comment>http://www.blogjava.net/dorydoo/comments/55357.html</wfw:comment><comments>http://www.blogjava.net/dorydoo/archive/2006/06/27/55357.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dorydoo/comments/commentRss/55357.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dorydoo/services/trackbacks/55357.html</trackback:ping><description><![CDATA[
		<p>blovesaga在一家小超级市场购买一个1.10元棒棒糖,但是他的钱报中都是两块一张的钞票.如果他用一张两块的钞票买这个棒棒糖,那么应该找给他多少零钱呢?<br />     编写一个程序解决这个问题.<br />code:<br />class Change<br />{<br /> public static void main(String[] args)<br /> {<br />  System.out.println(2.00-1.10);<br /> }<br />}</p>
		<p>       blovesage写下这段代码我们期望得到应该找回的零钞0.90,但是当运行后他发现数据不兑，运行结果为:0.8999999999999999,与预期的0.90不一样。为什么呢?搞了半天原因在于1.1这个数不能被精确的表示为一个double,因此被表示为最接近它的double值.该程序从2中减去这个值得.遗憾的是,这个结果打印出来并不是接近0.9的double值.这说明: 并不是所有的小数都可以用二进制浮点数精确表示.二进制浮点对于货币计算是非常不适合的.<br />      要解决这个问题有两个办法:一是使用某种整数类型,例如int或long,并且分单位来计算.如下:<br />System.out.println((200-110)+"fen");<br />结果为90分.二是使用执行小数运算的BigDecimal.它还可以通过JDBC与SQL DECIMAL类型进行互操作.这里需要注意的是: 一定要用BigDecimal(String)构造器,而千万不要用BigDecimal(double).后一个构造器将用它的参数值来创建一个实例.例如new BigDecimal(.1),它将返回一个BigDecimal,也即0.10000000000000000555111512312578270211815834041015625.正确使用我们就可以得到期望的结果0.90:<br />code:<br />import java.math.BigDecimal;<br />class Change<br />{<br /> public static void main(String[] args)<br /> {<br />  System.out.println(new BigDecimal("2.00").<br />                     subtract(new BigDecimal("1.10")));<br /> }<br />}<br />Print:<br />F:\Java Develop&gt;java Change<br />0.90</p>
<img src ="http://www.blogjava.net/dorydoo/aggbug/55357.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dorydoo/" target="_blank">多力宇扬</a> 2006-06-27 17:03 <a href="http://www.blogjava.net/dorydoo/archive/2006/06/27/55357.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转晕乎了吧</title><link>http://www.blogjava.net/dorydoo/archive/2006/06/27/55356.html</link><dc:creator>多力宇扬</dc:creator><author>多力宇扬</author><pubDate>Tue, 27 Jun 2006 09:02:00 GMT</pubDate><guid>http://www.blogjava.net/dorydoo/archive/2006/06/27/55356.html</guid><wfw:comment>http://www.blogjava.net/dorydoo/comments/55356.html</wfw:comment><comments>http://www.blogjava.net/dorydoo/archive/2006/06/27/55356.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dorydoo/comments/commentRss/55356.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dorydoo/services/trackbacks/55356.html</trackback:ping><description><![CDATA[
		<p>转型用于将一种类型转换到另一种类型.看看下面的code运行后你猜会打印什么?<br /> public class Multicast<br />{<br /> public static void main(String[] args)<br /> {<br />  System.out.println((int)(char)(byte)-1);<br /> }<br />}<br /> 转,转,转，我给转晕了,从int数值-1开始,然后从int转换为byte,之后转为char,最后转型回int.第一个转型将数值从32为窄化到8位,第二个转型从8位拓宽为16位,最后从16位拓宽到32位.这个数值最终回到起点了吗?运行一看不就知道了吗?<br />Print:<br />F:\Java Develop&gt;javac Multicast.java</p>
		<p>F:\Java Develop&gt;java Multicast<br />65535<br />啊,这么会是65535?<br />oh,my god!有条规则: 如果最初的数值类型是有符号的,那么就执行符号扩展;如果他是char,那么不管它将要被转换成什么类型,都执行另扩展.<br />   用这条规则来44看.因为byte是有符号的,所以在将byte数值-1转换成char时.会发生符号扩展.作为结果的char数值16位就都被置位了,因此它等于2^16-1(2的16次方减1),就是65535.从char到int的转型也是一个扩展,<br />用规则来说它将执行另扩展,而不是符号扩展.作为int的结果数值就是65535和打印的一样.<br />   从这个例子我们得到一个教训:如果通过观察不能确定程序将要做什么,那么它做的就很有可能不是你想要的.</p>
<img src ="http://www.blogjava.net/dorydoo/aggbug/55356.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dorydoo/" target="_blank">多力宇扬</a> 2006-06-27 17:02 <a href="http://www.blogjava.net/dorydoo/archive/2006/06/27/55356.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>优柔寡断</title><link>http://www.blogjava.net/dorydoo/archive/2006/06/27/55353.html</link><dc:creator>多力宇扬</dc:creator><author>多力宇扬</author><pubDate>Tue, 27 Jun 2006 09:01:00 GMT</pubDate><guid>http://www.blogjava.net/dorydoo/archive/2006/06/27/55353.html</guid><wfw:comment>http://www.blogjava.net/dorydoo/comments/55353.html</wfw:comment><comments>http://www.blogjava.net/dorydoo/archive/2006/06/27/55353.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/dorydoo/comments/commentRss/55353.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/dorydoo/services/trackbacks/55353.html</trackback:ping><description><![CDATA[
		<p>下面这个可怜的小程序并不能干脆的做决定。它的decisive方法将返回true。但是它也返回false。那么，它到底打印的是什么呢？甚至，合法吗? </p>
		<p>class Indecisive<br />{<br /> public static void main(String[] args)<br /> {<br />  System.out.println(decisive());<br /> }<br /> static boolean decisive()<br /> {<br />  try<br />  {<br />   return true;<br />  }<br />  finally<br />  {<br />   return false;<br />  }<br /> }<br />}<br />   你可能认为这个程序不合法。毕竟，decisive方法不能同时返回true和false。如果你尝试一下，就会发现它<br />编译时没有任何错误，并且它打印的是false。为什么呢?<br />    原因在于就是在：在一个try-finally语句中，finally语句块总是在控制权离开try语句块时执行。无论try<br />语句块是正常结束的，还是意外结束，情况都是如此。在一条语句或一个语句块抛出一个异常，或者对某个封闭类型语句执行了一个break或continue，或是像这个程序一样执行了一个return时，将发生意外结束。之所以称为意外结束，是因为它们阻止程序按顺序执行下面的语句。<br />    当try语句块和finally语句块都意外结束时，在try语句块中引发意外结束的原因将被丢弃，而整个try-finally<br />语句意外结束的原因将与finally语句块意外结束的原因相同。在这个程序中，在try语句块中的return语句所<br />引发的意外结束将被丢弃，而try-finally语句意外结束是由finally语句块中的return造成的。简单的讲，程序<br />尝试着(try)返回(return)true,但是它最终(finally)返回(return)的是false。<br />    总之，每一个finally语句块都应该正常结束，除非抛出不受检查的异常。千万不要用return,break,continue或throw来退出finally语句块，并且千万不要允许让受检查的异常传播到finally语句块之外。</p>
<img src ="http://www.blogjava.net/dorydoo/aggbug/55353.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/dorydoo/" target="_blank">多力宇扬</a> 2006-06-27 17:01 <a href="http://www.blogjava.net/dorydoo/archive/2006/06/27/55353.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>