﻿<?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>IT博客-mordecai-文章分类-java</title><link>http://www.cnitblog.com/mordecai/category/6232.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 15 Oct 2011 21:49:15 GMT</lastBuildDate><pubDate>Sat, 15 Oct 2011 21:49:15 GMT</pubDate><ttl>60</ttl><item><title>关于JAVA匿名内部类</title><link>http://www.cnitblog.com/mordecai/articles/34032.html</link><dc:creator>mordecai</dc:creator><author>mordecai</author><pubDate>Wed, 26 Sep 2007 00:38:00 GMT</pubDate><guid>http://www.cnitblog.com/mordecai/articles/34032.html</guid><wfw:comment>http://www.cnitblog.com/mordecai/comments/34032.html</wfw:comment><comments>http://www.cnitblog.com/mordecai/articles/34032.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/mordecai/comments/commentRss/34032.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/mordecai/services/trackbacks/34032.html</trackback:ping><description><![CDATA[<p><font face="Verdana">&nbsp;基本理论:<br>－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br>关于JAVA内部类:一个内部类的定义是定义在另一个类内部的类。<br>　　存在它的原因是:<br>　　1.一个内部类的对象能够访问创建它的对象的实现，包括私有数据。即内部类实例对包含它的哪个类的实例来说，是特权的。<br>　　2.对于同一个包中的其他类来说,内部类能够隐藏起来,换句话说，内部类不管方法的可见性如何，那怕是public，除了包容类，其他类都无法使用它。<br>　　3.匿名内部类可以很方便的定义回调。<br>　　4.使用内部类可以非常方便的编写事件驱动程序。</font></p>
<p><font face="Verdana">其实它真正的目的仅仅为了定义回调－－进一步就是事件驱动。<br>接口和回调：编程一个常用的模式是回调模式,在这种模式中你可以指定当一个特定时间发生时回调对象上的方法。<br>－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br>&nbsp;&nbsp;&nbsp; 注意事项:<br>&nbsp;<br>&nbsp;匿名类和内部类中的中的this :<br>&nbsp;有时候，我们会用到一些内部类和匿名类。当在匿名类中用this时，这个this则指的是匿名类或内部类本身。<br>&nbsp;这时如果我们要使用外部类的方法和变量的话，则应该加上外部类的类名。如下面这个例子：<br>&nbsp;<br>public class A {<br>&nbsp; int i = 1;<br>&nbsp; public A() {<br>&nbsp;&nbsp;&nbsp; Thread thread = new Thread() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void run() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(;;) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A.this.run();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sleep(1000);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch(InterruptedException ie) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; };<br>&nbsp;&nbsp;&nbsp; thread.start();<br>&nbsp; } <br>&nbsp; public void run() {<br>&nbsp;&nbsp;&nbsp; System.out.println("i = " + i);<br>&nbsp;&nbsp;&nbsp; i++;<br>&nbsp; }<br>&nbsp; public static void main(String[] args) throws Exception {<br>&nbsp;&nbsp;&nbsp; new A();<br>&nbsp; }<br>}<br>&nbsp;&nbsp;&nbsp; 在上面这个例子中, thread 是一个匿名类对象，在它的定义中，它的 run 函数里用到了外部类的 run 函数。<br>&nbsp;&nbsp;&nbsp; 这时由于函数同名，直接调用就不行了。这时有两种办法，一种就是把外部的 run 函数换一个名字，但这种办法对于一个开发到中途的应用来说是不可取的<br>&nbsp;&nbsp;&nbsp; 。那么就可以用这个例子中的办法用外部类的类名加上 this 引用来说明要调用的是外部类的方法 run。<br>&nbsp;&nbsp;&nbsp; －－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－<br>&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 对于这个例子：</font></p>
<p><font face="Verdana">this.test(new Inner(){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void method1(){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.print("1111");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void method2(){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.print("22222");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>});<br>这个时候调用test()方法，那Inner类的method1和method2是什么时候被调用的？难道也是this对象向他们发消息（比如传入一个参数）吗？还是直接显式的调用？？<br>&nbsp;<br>对
于Inner类，除了this这个类，就是this.test(...那句中的this，它能够调用Inner类的方法，其他地方都不行，然而，这也需要
你在类中有个地方保存有对这个内部类实例的引用才可以。再说明一次，内部类是用来在某个时刻调用外面的方法而存在的－－这就是回调。<br>为了说明内部类实例的方法只能在包容类的实例中调用，其他地方无法调用，给个例子如下：<br>JAVA2实用教程源码：<br>&nbsp;<br>&nbsp;/** 一个应用程序，用来演示内部类的使用 */<br>/** 类Outer */<br>class Outer{<br>private static int size;<br>/** 内部类Inner的声明 */<br>public class Inner{<br>private int size;<br>/** 方法doStuff() */<br>public void doStuff(int size){<br>size++; //存取局部变量<br>this.size++;&nbsp; //存取其内部类的成员变量<br>Outer.this.size++; //存取其外部类的成员变量<br>System.out.println(size+" "+this.size+" "+Outer.this.size);<br>}<br>}//内部类Inner结束<br>/** 类Outer中定义的实例方法testInner()方法 */<br>public void testInner(){<br>Inner i=new Inner();<br>i.doStuff(5);<br>}<br>/** main()方法 */<br>public static void main(String[] a){<br>Outer o=new Outer();<br>o.testInner();<br>}<br>}//类Outer结束<br>那么，如何使用内部类,匿名类实现事件处理呢？<br>JAVA---事件适配器</font></p>
<p><font face="Verdana">&nbsp;1．事件适配器--EventAdapter<br>　　下例中采用了鼠标适配器：<br>　　</font></p>
<p><font face="Verdana">import java.awt.*;<br>　　import java.awt.event.*;<br>　　public class MouseClickHandler extends MouseAdaper{<br>　　　　public void mouseClicked(MouseEvent e) //只实现需要的方法<br>　　　　　　　{ &#8230;&#8230;}<br>　　}<br>&nbsp;<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>　2. 用内部类实现事件处理<br>　　内部类（inner class）是被定义于另一个类中的类，使用内部类的主要原因是由于：<br>　　◇ 一个内部类的对象可访问外部类的成员方法和变量，包括私有的成员。<br>　　◇ 实现事件监听器时，采用内部类、匿名类编程非常容易实现其功能。<br>　　◇ 编写事件驱动程序，内部类很方便。　　<br>　　因此内部类所能够应用的地方往往是在AWT的事件处理机制中。<br>例5.11<br>　　　<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>　　　　　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>　　　　　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>　　　　　　　public static void main(String args[]) {<br>　　　　　　　　　InnerClass obj=new InnerClass();<br>　　　　　　　　　obj.launchFrame();<br>　　　　　　　}<br>　　　　　}//内部类结束<br>　　　　}<br>　3．匿名类（Anonymous Class）<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>　　其实仔细分析，例5.11和5.12实现的都是完全一样的功能，只不过采取的方式不同。5.11中的事件处理类是一个内部类，而5.12的事件处理类是匿名类，可以说从类的关系来说是越来越不清楚，但<br>是程序也越来越简练。熟悉这两种方式也十分有助于编写图形界面的程序。</font></p>
<br><img src ="http://www.cnitblog.com/mordecai/aggbug/34032.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/mordecai/" target="_blank">mordecai</a> 2007-09-26 08:38 <a href="http://www.cnitblog.com/mordecai/articles/34032.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于Java栈与堆的思考</title><link>http://www.cnitblog.com/mordecai/articles/34027.html</link><dc:creator>mordecai</dc:creator><author>mordecai</author><pubDate>Tue, 25 Sep 2007 23:57:00 GMT</pubDate><guid>http://www.cnitblog.com/mordecai/articles/34027.html</guid><wfw:comment>http://www.cnitblog.com/mordecai/comments/34027.html</wfw:comment><comments>http://www.cnitblog.com/mordecai/articles/34027.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/mordecai/comments/commentRss/34027.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/mordecai/services/trackbacks/34027.html</trackback:ping><description><![CDATA[<p><font face="Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同，Java自动管理栈和堆，程序员不能直接地设置栈或堆。 </font></p>
<p><font face="Times New Roman">　　2.
栈的优势是，存取速度比堆要快，仅次于直接位于CPU中的寄存器。但缺点是，存在栈中的数据大小与生存期必须是确定的，缺乏灵活性。另外，栈数据可以共
享，详见第3点。堆的优势是可以动态地分配内存大小，生存期也不必事先告诉编译器，Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是，由于要
在运行时动态分配内存，存取速度较慢。</font></p>
<p><font face="Times New Roman">　　3. Java中的数据类型有两种。</font></p>
<p><font face="Times New Roman">　　一种是基本类型(primitive types), 共有8种，即int,
short, long, byte, float, double, boolean,
char(注意，并没有string的基本类型)。这种类型的定义是通过诸如int a = 3; long b =
255L;的形式来定义的，称为自动变量。值得注意的是，自动变量存的是字面值，不是类的实例，即不是类的引用，这里并没有类的存在。如int a =
3;
这里的a是一个指向int类型的引用，指向3这个字面值。这些字面值的数据，由于大小可知，生存期可知(这些字面值固定定义在某个程序块里面，程序块退出
后，字段值就消失了)，出于追求速度的原因，就存在于栈中。</font></p>
<p><font face="Times New Roman">　　另外，栈有一个很重要的特殊性，就是存在栈中的数据可以共享。假设我们同时定义：<br>int a = 3; <br>int b = 3；</font></p>
<p><font face="Times New Roman">　　编译器先处理int a =
3；首先它会在栈中创建一个变量为a的引用，然后查找有没有字面值为3的地址，没找到，就开辟一个存放3这个字面值的地址，然后将a指向3的地址。接着处
理int b = 3；在创建完b的引用变量后，由于在栈中已经有3这个字面值，便将b直接指向3的地址。这样，就出现了a与b同时均指向3的情况。</font></p>
<p><font face="Times New Roman">　　特别注意的是，这种字面值的引用与类对象的引用不同。假定两个类对象的引用同时指
向一个对象，如果一个对象引用变量修改了这个对象的内部状态，那么另一个对象引用变量也即刻反映出这个变化。相反，通过字面值的引用来修改其值，不会导致
另一个指向此字面值的引用的值也跟着改变的情况。如上例，我们定义完a与b的值后，再令a=4；那么，b不会等于4，还是等于3。在编译器内部，遇到a=
4；时，它就会重新搜索栈中是否有4的字面值，如果没有，重新开辟地址存放4的值；如果已经有了，则直接将a指向这个地址。因此a值的改变不会影响到b的
值。</font></p>
<p><font face="Times New Roman">　　另一种是包装类数据，如Integer, String,
Double等将相应的基本数据类型包装起来的类。这些类数据全部存在于堆中，Java用new()语句来显示地告诉编译器，在运行时才根据需要动态创
建，因此比较灵活，但缺点是要占用更多的时间。 4. String是一个特殊的包装类数据。即可以用String str = new
String("abc");的形式来创建，也可以用String str = "abc"；的形式来创建(作为对比，在JDK
5.0之前，你从未见过Integer i = 3;的表达式，因为类与字面值是不能通用的，除了String。而在JDK
5.0中，这种表达式是可以的！因为编译器在后台进行Integer i = new
Integer(3)的转换)。前者是规范的类的创建过程，即在Java中，一切都是对象，而对象是类的实例，全部通过new()的形式来创建。Java
中的有些类，如DateFormat类，可以通过该类的getInstance()方法来返回一个新创建的类，似乎违反了此原则。其实不然。该类运用了单
例模式来返回类的实例，只不过这个实例是在该类内部通过new()来创建的，而getInstance()向外部隐藏了此细节。那为什么在String
str = "abc"；中，并没有通过new()来创建实例，是不是违反了上述原则？其实没有。</font></p>
<p><font face="Times New Roman">　　5. 关于String str = "abc"的内部工作。Java内部将此语句转化为以下几个步骤：</font></p>
<p><font face="Times New Roman">　　(1)先定义一个名为str的对String类的对象引用变量：String str；</font></p>
<p><font face="Times New Roman">　　(2)在栈中查找有没有存放值为"abc"的地址，如果没有，则开辟一个存放字面
值为"abc"的地址，接着创建一个新的String类的对象o，并将o的字符串值指向这个地址，而且在栈中这个地址旁边记下这个引用的对象o。如果已经
有了值为"abc"的地址，则查找对象o，并返回o的地址。</font></p>
<p><font face="Times New Roman">　　(3)将str指向对象o的地址。</font></p>
<p><font face="Times New Roman">　　值得注意的是，一般String类中字符串值都是直接存值的。但像String str = "abc"；这种场合下，其字符串值却是保存了一个指向存在栈中数据的引用！</font></p>
<p><font face="Times New Roman">　　为了更好地说明这个问题，我们可以通过以下的几个代码进行验证。<br>String str1 = "abc";<br>String str2 = "abc";<br>System.out.println(str1==str2); //true</font></p>
<p><font face="Times New Roman">　　注意，我们这里并不用str1.equals(str2)；的方式，因为这将比较两个字符串的值是否相等。==号，根据JDK的说明，只有在两个引用都指向了同一个对象时才返回真值。而我们在这里要看的是，str1与str2是否都指向了同一个对象。<br>结果说明，JVM创建了两个引用str1和str2，但只创建了一个对象，而且两个引用都指向了这个对象。</font></p>
<p><font face="Times New Roman">　　我们再来更进一步，将以上代码改成：<br>String str1 = "abc";<br>String str2 = "abc";<br>str1 = "bcd";<br>System.out.println(str1 + "," + str2); //bcd, abc<br>System.out.println(str1==str2); //false</font></p>
<p><font face="Times New Roman">　　这就是说，赋值的变化导致了类对象引用的变化，str1指向了另外一个新对象！而str2仍旧指向原来的对象。上例中，当我们将str1的值改为"bcd"时，JVM发现在栈中没有存放该值的地址，便开辟了这个地址，并创建了一个新的对象，其字符串的值指向这个地址。</font></p>
<p><font face="Times New Roman">　　事实上，String类被设计成为不可改变(immutable)的类。如果你要
改变其值，可以，但JVM在运行时根据新值悄悄创建了一个新对象，然后将这个对象的地址返回给原来类的引用。这个创建过程虽说是完全自动进行的，但它毕竟
占用了更多的时间。在对时间要求比较敏感的环境中，会带有一定的不良影响。</font></p>
<p><font face="Times New Roman">　　再修改原来代码：<br>String str1 = "abc";<br>String str2 = "abc";</font></p>
<p><font face="Times New Roman">str1 = "bcd";</font></p>
<p><font face="Times New Roman">String str3 = str1;<br>System.out.println(str3); //bcd</font></p>
<p><font face="Times New Roman">String str4 = "bcd";<br>System.out.println(str1 == str4); //true</font></p>
<p><font face="Times New Roman">　　str3这个对象的引用直接指向str1所指向的对象(注意，str3并没有创建
新对象)。当str1改完其值后，再创建一个String的引用str4，并指向因str1修改值而创建的新的对象。可以发现，这回str4也没有创建新
的对象，从而再次实现栈中数据的共享。</font></p>
<p><font face="Times New Roman">　　我们再接着看以下的代码。<br>String str1 = new String("abc");<br>String str2 = "abc";<br>System.out.println(str1==str2); //false</font></p>
<p><font face="Times New Roman">　　创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象。<br>String str1 = "abc";<br>String str2 = new String("abc");<br>System.out.println(str1==str2); //false</font></p>
<p><font face="Times New Roman">　　创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象。</font></p>
<p><font face="Times New Roman">　　以上两段代码说明，只要是用new()来新建对象的，都会在堆中创建，而且其字符串是单独存值的，即使与栈中的数据相同，也不会与栈中的数据共享。</font></p>
<p><font face="Times New Roman">　　6. 数据类型包装类的值不可修改。不仅仅是String类的值不可修改，所有的数据类型包装类都不能更改其内部的值。 7. 结论与建议：</font></p>
<p><font face="Times New Roman">　　(1)我们在使用诸如String str =
"abc"；的格式定义类时，总是想当然地认为，我们创建了String类的对象str。担心陷阱！对象可能并没有被创建！唯一可以肯定的是，指向
String类的引用被创建了。至于这个引用到底是否指向了一个新的对象，必须根据上下文来考虑，除非你通过new()方法来显要地创建一个新的对象。因
此，更为准确的说法是，我们创建了一个指向String类的对象的引用变量str，这个对象引用变量指向了某个值为"abc"的String类。清醒地认
识到这一点对排除程序中难以发现的bug是很有帮助的。</font></p>
<p><font face="Times New Roman">　　(2)使用String str =
"abc"；的方式，可以在一定程度上提高程序的运行速度，因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String
str = new
String("abc")；的代码，则一概在堆中创建新对象，而不管其字符串值是否相等，是否有必要创建新对象，从而加重了程序的负担。这个思想应该是
享元模式的思想，但JDK的内部在这里实现是否应用了这个模式，不得而知。</font></p>
<p><font face="Times New Roman">　　(3)当比较包装类里面的数值是否相等时，用equals()方法；当测试两个包装类的引用是否指向同一个对象时，用==。</font></p>
<p><font face="Times New Roman">　　(4)由于String类的immutable性质，当String变量需要经常变换其值时，应该考虑使用StringBuffer类，以提高程序效率。</font></p>
<br><img src ="http://www.cnitblog.com/mordecai/aggbug/34027.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/mordecai/" target="_blank">mordecai</a> 2007-09-26 07:57 <a href="http://www.cnitblog.com/mordecai/articles/34027.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>