﻿<?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-lanxin1020-随笔分类-j2se</title><link>http://www.blogjava.net/lanxin1020/category/38973.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 16 May 2009 10:44:35 GMT</lastBuildDate><pubDate>Sat, 16 May 2009 10:44:35 GMT</pubDate><ttl>60</ttl><item><title>try…catch…finally(转)</title><link>http://www.blogjava.net/lanxin1020/archive/2009/05/08/269621.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Fri, 08 May 2009 07:23:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2009/05/08/269621.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/269621.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2009/05/08/269621.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/269621.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/269621.html</trackback:ping><description><![CDATA[<div class="date"><a href="http://jdlsfl.javaeye.com/blog/209385">java的异常处理机制(try&#8230;catch&#8230;<span class="hilite1">finally</span>)</a><a href="http://jdlsfl.javaeye.com/blog/209385"></a></div>
<div class="blog_content">
<p>1 引子<br />
try&#8230;catch&#8230;<span class="hilite1">finally</span>恐怕是大家再熟悉不过的语句了，而且感觉用起来也是很简单，逻辑上似乎也是很容易理解。不过，我亲自体验的&#8220;教训&#8221;告诉我，这个东西可不是想象中的那么简单、听话。不信？那你看看下面的代码，&#8220;猜猜&#8221;它执行后的结果会是什么？不要往后看答案、也不许执行代码看真正答案哦。如果你的答案是正确，那么这篇文章你就不用浪费时间看啦。<br />
public class TestException<br />
{<br />
&nbsp;&nbsp;&nbsp; public TestException()<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; boolean testEx() throws Exception<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean ret = true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = testEx1();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (Exception e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("testEx, catch exception");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw e;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="hilite1">finally</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("testEx, <span class="hilite1">finally</span>; return value=" + ret);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; boolean testEx1() throws Exception<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean ret = true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = testEx2();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!ret)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("testEx1, at the end of try");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (Exception e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("testEx1, catch exception");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw e;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="hilite1">finally</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("testEx1, <span class="hilite1">finally</span>; return value=" + ret);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; boolean testEx2() throws Exception<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean ret = true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int b = 12;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int c;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 2; i &gt;= -2; i--)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = b / i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("i=" + i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (Exception e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("testEx2, catch exception");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw e;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="hilite1">finally</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("testEx2, <span class="hilite1">finally</span>; return value=" + ret);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public static void main(String[] args)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TestException testException1 = new TestException();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; testException1.testEx();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (Exception e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
你的答案是什么？是下面的答案吗？<br />
i=2<br />
i=1<br />
testEx2, catch exception<br />
testEx2, <span class="hilite1">finally</span>; return value=false<br />
testEx1, catch exception<br />
testEx1, <span class="hilite1">finally</span>; return value=false<br />
testEx, catch exception<br />
testEx, <span class="hilite1">finally</span>; return value=false<br />
如果你的答案真的如上面所说，那么你错啦。^_^，那就建议你仔细看一看这篇文章或者拿上面的代码按各种不同的情况修改、执行、测试，你会发现有很多事情不是原来想象中的那么简单的。<br />
现在公布正确答案：<br />
i=2<br />
i=1<br />
testEx2, catch exception<br />
testEx2, <span class="hilite1">finally</span>; return value=false<br />
testEx1, <span class="hilite1">finally</span>; return value=false<br />
testEx, <span class="hilite1">finally</span>; return value=false</p>
<p>2 基础知识</p>
<p>2.1 相关概念<br />
例外是在程序运行过程中发生的异常事件，比如除0溢出、数组越界、文件找不到等，这些事件的发生将阻止程序的正常运行。为了加强程序的鲁棒性，程序设计时，必须考虑到可能发生的异常事件并做出相应的处理。C语言中，通过使用if语句来判断是否出现了例外，同时，调用函数通过被调用函数的返回值感知在被调用函数中产生的例外事件并进行处理。全程变量ErroNo常常用来反映一个异常事件的类型。但是，这种错误处理机制会导致不少问题。<br />
Java通过面向对象的方法来处理例外。在一个方法的运行过程中，如果发生了例外，则这个方法生成代表该例外的一个对象，并把它交给运行时系统，运行时系统寻找相应的代码来处理这一例外。我们把生成例外对象并把它提交给运行时系统的过程称为抛弃(throw)一个例外。运行时系统在方法的调用栈中查找，从生成例外的方法开始进行回朔，直到找到包含相应例外处理的方法为止，这一个过程称为捕获(catch)一个例外。<br />
2.2 Throwable类及其子类<br />
　用面向对象的方法处理例外，就必须建立类的层次。类 Throwable位于这一类层次的最顶层，只有它的后代才可以做为一个例外被抛弃。图1表示了例外处理的类层次。<br />
从图中可以看出，类Throwable有两个直接子类：Error和Exception。Error类对象（如动态连接错误等），由Java虚拟机生成并抛弃（通常，Java程序不对这类例外进行处理）；Exception类对象是Java程序处理或抛弃的对象。它有各种不同的子类分别对应于不同类型的例外。其中类RuntimeException代表运行时由Java虚拟机生成的例外，如算术运算例外ArithmeticException(由除0错等导致)、数组越界例外ArrayIndexOutOfBoundsException等；其它则为非运行时例外，如输入输出例外IOException等。Java编译器要求Java程序必须捕获或声明所有的非运行时例外，但对运行时例外可以不做处理。<br />
　</p>
<p>2.3 　异常处理关键字<br />
Java的异常处理是通过5个关键字来实现的：try，catch，throw，throws，<span class="hilite1">finally</span>。JB的在线帮助中对这几个关键字是这样解释的：<br />
Throws:&nbsp; Lists the exceptions a method could throw.<br />
Throw:&nbsp;&nbsp; Transfers control of the method to the exception handler.<br />
Try：&nbsp;&nbsp;&nbsp; Opening exception-handling statement.<br />
Catch：&nbsp; Captures the exception.<br />
<span class="hilite1">Finally</span>： Runs its code before terminating the program.<br />
2.3.1 try语句　<br />
try语句用大括号{}指定了一段代码，该段代码可能会抛弃一个或多个例外。<br />
2.3.2 catch语句　<br />
catch语句的参数类似于方法的声明，包括一个例外类型和一个例外对象。例外类型必须为Throwable类的子类，它指明了catch语句所处理的例外类型，例外对象则由运行时系统在try所指定的代码块中生成并被捕获，大括号中包含对象的处理，其中可以调用对象的方法。<br />
catch语句可以有多个，分别处理不同类的例外。Java运行时系统从上到下分别对每个catch语句处理的例外类型进行检测，直到找到类型相匹配的catch语句为止。这里，类型匹配指catch所处理的例外类型与生成的例外对象的类型完全一致或者是它的父类，因此，catch语句的排列顺序应该是从特殊到一般。<br />
也可以用一个catch语句处理多个例外类型，这时它的例外类型参数应该是这多个例外类型的父类，程序设计中要根据具体的情况来选择catch语句的例外处理类型。　<br />
2.3.3 <span class="hilite1">finally</span>语句　<br />
try所限定的代码中，当抛弃一个例外时，其后的代码不会被执行。通过<span class="hilite1">finally</span>语句可以指定一块代码。无论try所指定的程序块中抛弃或不抛弃例外，也无论catch语句的例外类型是否与所抛弃的例外的类型一致，<span class="hilite1">finally</span>所指定的代码都要被执行，它提供了统一的出口。通常在<span class="hilite1">finally</span>语句中可以进行资源的清除工作。如关闭打开的文件等。<br />
2.3.4 throws语句　<br />
throws总是出现在一个函数头中，用来标明该成员函数可能抛出的各种异常。对大多数Exception子类来说，Java 编译器会强迫你声明在一个成员函数中抛出的异常的类型。如果异常的类型是Error或 RuntimeException， 或它们的子类，这个规则不起作用， 因为这在程序的正常部分中是不期待出现的。 如果你想明确地抛出一个RuntimeException，你必须用throws语句来声明它的类型。<br />
2.3.5 throw语句　<br />
throw总是出现在函数体中，用来抛出一个异常。程序会在throw语句后立即终止，它后面的语句执行不到，然后在包含它的所有try块中（可能在上层调用函数中）从里向外寻找含有与其匹配的catch子句的try块。</p>
<p>3 关键字及其中语句流程详解</p>
<p>3.1 try的嵌套<br />
你可以在一个成员函数调用的外面写一个try语句，在这个成员函数内部，写另一个try语句保护其他代码。每当遇到一个try语句，异常的框架就放到堆栈上面，直到所有的try语句都完成。如果下一级的try语句没有对某种异常进行处理，堆栈就会展开，直到遇到有处理这种异常的try语句。下面是一个try语句嵌套的例子。 <br />
class MultiNest {<br />
&nbsp;&nbsp;&nbsp; static void procedure() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int a = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int b = 42/a;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch(java.lang.ArithmeticException e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("in procedure, catch ArithmeticException: " + e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public static void main(String args[]) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; procedure();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch(java.lang. Exception e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("in main, catch Exception: " + e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
这个例子执行的结果为：<br />
in procedure, catch ArithmeticException: java.lang.ArithmeticException: / by zero<br />
成员函数procedure里有自己的try/catch控制，所以main不用去处理 ArrayIndexOutOfBoundsException；当然如果如同最开始我们做测试的例子一样，在procedure中catch到异常时使用throw e;语句将异常抛出，那么main当然还是能够捕捉并处理这个procedure抛出来的异常。例如在procedure函数的catch中的System.out语句后面增加throw e;语句之后，执行结果就变为：<br />
in procedure, catch ArithmeticException: java.lang.ArithmeticException: / by zero<br />
in main, catch Exception: java.lang.ArithmeticException: / by zero</p>
<p>3.2 try-catch程序块的执行流程以及执行结果<br />
相对于try-catch-<span class="hilite1">finally</span>程序块而言，try-catch的执行流程以及执行结果还是比较简单的。<br />
首先执行的是try语句块中的语句，这时可能会有以下三种情况：<br />
&nbsp;&nbsp;&nbsp; 1．如果try块中所有语句正常执行完毕，那么就不会有其他的&#8220;动做&#8221;被执行，整个try-catch程序块正常完成。<br />
&nbsp;&nbsp;&nbsp; 2．如果try语句块在执行过程中碰到异常V，这时又分为两种情况进行处理：<br />
--&gt;如果异常V能够被与try相应的catch块catch到，那么第一个catch到这个异常的catch块（也是离try最近的一个与异常V匹配的catch块）将被执行；如果catch块执行正常，那么try-catch程序块的结果就是&#8220;正常完成&#8221;；如果该catch块由于原因R突然中止，那么try-catch程序块的结果就是&#8220;由于原因R突然中止（completes abruptly）&#8221;。<br />
--&gt;如果异常V没有catch块与之匹配，那么这个try-catch程序块的结果就是&#8220;由于抛出异常V而突然中止（completes abruptly）&#8221;。<br />
&nbsp;&nbsp;&nbsp; 3． 如果try由于其他原因R突然中止（completes abruptly），那么这个try-catch程序块的结果就是&#8220;由于原因R突然中止（completes abruptly）&#8221;。</p>
<p>3.3 try-catch-<span class="hilite1">finally</span>程序块的执行流程以及执行结果<br />
try-catch-<span class="hilite1">finally</span>程序块的执行流程以及执行结果比较复杂。<br />
首先执行的是try语句块中的语句，这时可能会有以下三种情况：<br />
1．如果try块中所有语句正常执行完毕，那么<span class="hilite1">finally</span>块的居于就会被执行，这时分为以下两种情况：<br />
--&gt;如果<span class="hilite1">finally</span>块执行顺利，那么整个try-catch-<span class="hilite1">finally</span>程序块正常完成。<br />
--&gt;如果<span class="hilite1">finally</span>块由于原因R突然中止，那么try-catch-<span class="hilite1">finally</span>程序块的结局是&#8220;由于原因R突然中止（completes abruptly）&#8221;<br />
2．如果try语句块在执行过程中碰到异常V，这时又分为两种情况进行处理：<br />
--&gt;如果异常V能够被与try相应的catch块catch到，那么第一个catch到这个异常的catch块（也是离try最近的一个与异常V匹配的catch块）将被执行；这时就会有两种执行结果：<br />
--&gt;如果catch块执行正常，那么<span class="hilite1">finally</span>块将会被执行，这时分为两种情况：<br />
--&gt;如果<span class="hilite1">finally</span>块执行顺利，那么整个try-catch-<span class="hilite1">finally</span>程序块正常完成。<br />
--&gt;如果<span class="hilite1">finally</span>块由于原因R突然中止，那么try-catch-<span class="hilite1">finally</span>程序块的结局是&#8220;由于原因R突然中止（completes abruptly）&#8221;<br />
--&gt;如果catch块由于原因R突然中止，那么<span class="hilite1">finally</span>模块将被执行，分为两种情况：<br />
--&gt;如果如果<span class="hilite1">finally</span>块执行顺利，那么整个try-catch-<span class="hilite1">finally</span>程序块的结局是&#8220;由于原因R突然中止（completes abruptly）&#8221;。<br />
--&gt;如果<span class="hilite1">finally</span>块由于原因S突然中止，那么整个try-catch-<span class="hilite1">finally</span>程序块的结局是&#8220;由于原因S突然中止（completes abruptly）&#8221;，原因R将被抛弃。<br />
（注意，这里就正好和我们的例子相符合，虽然我们在testEx2中使用throw e抛出了异常，但是由于testEx2中有<span class="hilite1">finally</span>块，而<span class="hilite1">finally</span>块的执行结果是complete abruptly的（别小看这个用得最多的return，它也是一种导致complete abruptly的原因之一啊——后文中有关于导致complete abruptly的原因分析），所以整个try-catch-<span class="hilite1">finally</span>程序块的结果是&#8220;complete abruptly&#8221;，所以在testEx1中调用testEx2时是捕捉不到testEx1中抛出的那个异常的，而只能将<span class="hilite1">finally</span>中的return结果获取到。<br />
如果在你的代码中期望通过捕捉被调用的下级函数的异常来给定返回值，那么一定要注意你所调用的下级函数中的<span class="hilite1">finally</span>语句，它有可能会使你throw出来的异常并不能真正被上级调用函数可见的。当然这种情况是可以避免的，以testEx2为例：如果你一定要使用<span class="hilite1">finally</span>而且又要将catch中throw的e在testEx1中被捕获到，那么你去掉testEx2中的<span class="hilite1">finally</span>中的return就可以了。<br />
这个事情已经在OMC2.0的MIB中出现过啦：服务器的异常不能完全被反馈到客户端。）<br />
--&gt;如果异常V没有catch块与之匹配，那么<span class="hilite1">finally</span>模块将被执行，分为两种情况：<br />
--&gt;如果<span class="hilite1">finally</span>块执行顺利，那么整个try-catch-<span class="hilite1">finally</span>程序块的结局就是&#8220;由于抛出异常V而突然中止（completes abruptly）&#8221;。<br />
--&gt;如果<span class="hilite1">finally</span>块由于原因S突然中止，那么整个try-catch-<span class="hilite1">finally</span>程序块的结局是&#8220;由于原因S突然中止（completes abruptly）&#8221;，异常V将被抛弃。<br />
3．如果try由于其他原因R突然中止（completes abruptly），那么<span class="hilite1">finally</span>块被执行，分为两种情况：<br />
--&gt;如果<span class="hilite1">finally</span>块执行顺利，那么整个try-catch-<span class="hilite1">finally</span>程序块的结局是&#8220;由于原因R突然中止（completes abruptly）&#8221;。<br />
--&gt;如果<span class="hilite1">finally</span>块由于原因S突然中止，那么整个try-catch-<span class="hilite1">finally</span>程序块的结局是&#8220;由于原因S突然中止（completes abruptly）&#8221;，原因R将被抛弃。<br />
3.4 try-catch-<span class="hilite1">finally</span>程序块中的return<br />
从上面的try-catch-<span class="hilite1">finally</span>程序块的执行流程以及执行结果一节中可以看出无论try或catch中发生了什么情况，<span class="hilite1">finally</span>都是会被执行的，那么写在try或者catch中的return语句也就不会真正的从该函数中跳出了，它的作用在这种情况下就变成了将控制权（语句流程）转到<span class="hilite1">finally</span>块中；这种情况下一定要注意返回值的处理。<br />
例如，在try或者catch中return false了，而在<span class="hilite1">finally</span>中又return true，那么这种情况下不要期待你的try或者catch中的return false的返回值false被上级调用函数获取到，上级调用函数能够获取到的只是<span class="hilite1">finally</span>中的返回值，因为try或者catch中的return语句只是转移控制权的作用。<br />
3.5 如何抛出异常<br />
如果你知道你写的某个函数有可能抛出异常，而你又不想在这个函数中对异常进行处理，只是想把它抛出去让调用这个函数的上级调用函数进行处理，那么有两种方式可供选择：<br />
第一种方式：直接在函数头中throws SomeException，函数体中不需要try/catch。比如将最开始的例子中的testEx2改为下面的方式，那么testEx1就能捕捉到testEx2抛出的异常了。<br />
&nbsp;&nbsp;&nbsp; boolean testEx2() throws Exception{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean ret = true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int b=12;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int c;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i=2;i&gt;=-2;i--){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c=b/i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("i="+i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;&nbsp;&nbsp;&nbsp; <br />
}<br />
第二种方式：使用try/catch，在catch中进行一定的处理之后（如果有必要的话）抛出某种异常。例如上面的testEx2改为下面的方式，testEx1也能捕获到它抛出的异常：<br />
&nbsp;&nbsp;&nbsp; boolean testEx2() throws Exception{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean ret = true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int b=12;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int c;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i=2;i&gt;=-2;i--){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c=b/i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("i="+i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }catch (Exception e){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("testEx2, catch exception");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Throw e;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
第三种方法：使用try/catch/<span class="hilite1">finally</span>，在catch中进行一定的处理之后（如果有必要的话）抛出某种异常。例如上面的testEx2改为下面的方式，testEx1也能捕获到它抛出的异常：<br />
&nbsp;&nbsp;&nbsp; boolean testEx2() throws Exception{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean ret = true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int b=12;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int c;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i=2;i&gt;=-2;i--){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c=b/i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("i="+i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new Exception("aaa");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }catch (java.lang.ArithmeticException e){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("testEx2, catch exception");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new Exception("aaa");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<span class="hilite1">finally</span>{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("testEx2, <span class="hilite1">finally</span>; return value="+ret);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
4&nbsp; 关于abrupt completion<br />
前面提到了complete abruptly（暂且理解为&#8220;突然中止&#8221;或者&#8220;异常结束&#8221;吧），它主要包含了两种大的情形：abrupt completion of expressions and statements，下面就分两种情况进行解释。<br />
4.1 Normal and Abrupt Completion of Evaluation<br />
每一个表达式（expression）都有一种使得其包含的计算得以一步步进行的正常模式，如果每一步计算都被执行且没有异常抛出，那么就称这个表达式&#8220;正常结束（complete normally）&#8221;；如果这个表达式的计算抛出了异常，就称为&#8220;异常结束（complete abruptly）&#8221;。异常结束通常有一个相关联的原因（associated reason），通常也就是抛出一个异常V。<br />
与表达式、操作符相关的运行期异常有：<br />
--&gt;A class instance creation expression, array creation expression , or string concatenation operatior expression throws an OutOfMemoryError if there is insufficient memory available. <br />
--&gt;An array creation expression throws a NegativeArraySizeException if the value of any dimension expression is less than zero. <br />
--&gt;A field access throws a NullPointerException if the value of the object reference&nbsp; expression is null. <br />
--&gt;A method invocation expression that invokes an instance method throws a NullPointerException if the target reference is null. <br />
--&gt;An array access throws a NullPointerException if the value of the array reference&nbsp; expression is null. <br />
--&gt;An array access throws an ArrayIndexOutOfBoundsException if the value of the array index expression is negative or greater than or equal to the length of the array. <br />
--&gt;A cast throws a ClassCastException if a cast is found to be impermissible at run time. <br />
--&gt;An integer division or integer remainder operator throws an ArithmeticException if the value of the right-hand operand expression is zero. <br />
--&gt;An assignment to an array component of reference type throws an ArrayStoreException when the value to be assigned is not compatible with the component type of the array.<br />
4.2 Normal and Abrupt Completion of Statements <br />
正常情况我们就不多说了，在这里主要是列出了abrupt completion的几种情况：<br />
--&gt;break, continue, and return 语句将导致控制权的转换，从而使得statements不能正常地、完整地执行。 <br />
--&gt;某些表达式的计算也可能从java虚拟机抛出异常，这些表达式在上一小节中已经总结过了；一个显式的的throw语句也将导致异常的抛出。抛出异常也是导致控制权的转换的原因（或者说是阻止statement正常结束的原因）。 <br />
如果上述事件发生了，那么这些statement就有可能使得其正常情况下应该都执行的语句不能完全被执行到，那么这些statement也就是被称为是complete abruptly. <br />
导致abrupt completion的几种原因：<br />
--&gt;A break with no label <br />
--&gt;A break with a given label <br />
--&gt;A continue with no label <br />
--&gt;A continue with a given label <br />
--&gt;A return with no value <br />
--&gt;A return with a given value A <br />
--&gt;throw with a given value, including exceptions thrown by the Java virtual machine<br />
5 关于我们的编程的一点建议<br />
弄清楚try-catch-<span class="hilite1">finally</span>的执行情况后我们才能正确使用它。<br />
如果我们使用的是try-catch-<span class="hilite1">finally</span>语句块，而我们又需要保证有异常时能够抛出异常，那么在<span class="hilite1">finally</span>语句中就不要使用return语句了（<span class="hilite1">finally</span>语句块的最重要的作用应该是释放申请的资源），因为<span class="hilite1">finally</span>中的return语句会导致我们的throw e被抛弃，在这个try-catch-<span class="hilite1">finally</span>的外面将只能看到<span class="hilite1">finally</span>中的返回值（除非在<span class="hilite1">finally</span>中抛出异常）。（我们需要记住：不仅throw语句是abrupt completion 的原因，return、break、continue等这些看起来很正常的语句也是导致abrupt completion的原因。） </p>
</div>
<img src ="http://www.blogjava.net/lanxin1020/aggbug/269621.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2009-05-08 15:23 <a href="http://www.blogjava.net/lanxin1020/archive/2009/05/08/269621.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>xml解析</title><link>http://www.blogjava.net/lanxin1020/archive/2009/05/08/269551.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Fri, 08 May 2009 02:52:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2009/05/08/269551.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/269551.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2009/05/08/269551.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/269551.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/269551.html</trackback:ping><description><![CDATA[&nbsp;<br />
&nbsp;&nbsp;&nbsp; 1.详解 <br />
<br />
&nbsp;&nbsp;&nbsp; 1）DOM（JAXP Crimson解析器） <br />
&nbsp;&nbsp;&nbsp; DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构，然后才能做任何工作。由于它是基于信息层次的，因而DOM被认为是基于树或基于对象的。DOM以及广义的基于树的处理具有几个优点。首先，由于树在内存中是持久的，因此可以修改它以便应用程序能对数据和结构作出更改。它还可以在任何时候在树中上下导航，而不是像SAX那样是一次性的处理。DOM使用起来也要简单得多。 <br />
<br />
&nbsp;&nbsp;&nbsp; 2）SAX <br />
<br />
&nbsp;&nbsp;&nbsp; SAX处理的优点非常类似于流媒体的优点。分析能够立即开始，而不是等待所有的数据被处理。而且，由于应用程序只是在读取数据时检查数据，因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上，应用程序甚至不必解析整个文档；它可以在某个条件得到满足时停止解析。一般来说，SAX还比它的替代者DOM快许多。 <br />
<br />
&nbsp;&nbsp;&nbsp; 选择DOM还是选择SAX？ 对于需要自己编写代码来处理XML文档的开发人员来说， 选择DOM还是SAX解析模型是一个非常重要的设计决策。 DOM采用建立树形结构的方式访问XML文档，而SAX采用的事件模型。 <br />
<br />
&nbsp;&nbsp;&nbsp; DOM解析器把XML文档转化为一个包含其内容的树，并可以对树进行遍历。用DOM解析模型的优点是编程容易，开发人员只需要调用建树的指令，然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用DOM解析器的时候需要处理整个XML文档，所以对性能和内存的要求比较高，尤其是遇到很大的XML文件的时候。由于它的遍历能力，DOM解析器常用于XML文档需要频繁的改变的服务中。 <br />
<br />
&nbsp;&nbsp;&nbsp; SAX解析器采用了基于事件的模型，它在解析XML文档的时候可以触发一系列的事件，当发现给定的tag的时候，它可以激活一个回调方法，告诉该方法制定的标签已经找到。SAX对内存的要求通常会比较低，因为它让开发人员自己来决定所要处理的tag.特别是当开发人员只需要处理文档中所包含的部分数据时，SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难，而且很难同时访问同一个文档中的多处不同数据。 <br />
<br />
&nbsp;&nbsp;&nbsp; 3）JDOM http://www.jdom.org <br />
<br />
&nbsp;&nbsp;&nbsp; JDOM的目的是成为Java特定文档模型，它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型，JDOM一直得到大力推广和促进。正在考虑通过&#8220;Java规范请求JSR-102&#8221;将它最终用作&#8220;Java标准扩展&#8221;。从2000年初就已经开始了JDOM开发。 <br />
<br />
&nbsp;&nbsp;&nbsp; JDOM与DOM主要有两方面不同。首先，JDOM仅使用具体类而不使用接口。这在某些方面简化了API，但是也限制了灵活性。第二，API大量使用了Collections类，简化了那些已经熟悉这些类的Java开发者的使用。 <br />
<br />
&nbsp;&nbsp;&nbsp; JDOM文档声明其目的是&#8220;使用20%（或更少）的精力解决80%（或更多）Java/XML问题&#8221;（根据学习曲线假定为20%）。JDOM对于大多数Java/XML应用程序来说当然是有用的，并且大多数开发者发现API比DOM容易理解得多。JDOM还包括对程序行为的相当广泛检查以防止用户做任何在XML中无意义的事。然而，它仍需要您充分理解XML以便做一些超出基本的工作（或者甚至理解某些情况下的错误）。这也许是比学习DOM或JDOM接口都更有意义的工作。 <br />
<br />
&nbsp;&nbsp;&nbsp; JDOM自身不包含解析器。它通常使用SAX2解析器来解析和验证输入XML文档（尽管它还可以将以前构造的DOM表示作为输入）。它包含一些转换器以将JDOM表示输出成SAX2事件流、DOM模型或XML文本文档。JDOM是在Apache许可证变体下发布的开放源码。 <br />
<br />
&nbsp;&nbsp;&nbsp; 4）DOM4J http://dom4j.sourceforge.net <br />
<br />
&nbsp;&nbsp;&nbsp; 虽然DOM4J代表了完全独立的开发结果，但最初，它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能，包括集成的XPath支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项，它通过DOM4J API和标准DOM接口具有并行访问功能。从2000下半年开始，它就一直处于开发之中。 <br />
<br />
&nbsp;&nbsp;&nbsp; 为支持所有这些功能，DOM4J使用接口和抽象基本类方法。DOM4J大量使用了API中的Collections类，但是在许多情况下，它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是，虽然DOM4J付出了更复杂的API的代价，但是它提供了比JDOM大得多的灵活性。 <br />
<br />
&nbsp;&nbsp;&nbsp; 在添加灵活性、XPath集成和对大文档处理的目标时，DOM4J的目标与JDOM是一样的：针对Java开发者的易用性和直观操作。它还致力于成为比JDOM更完整的解决方案，实现在本质上处理所有Java/XML问题的目标。在完成该目标时，它比JDOM更少强调防止不正确的应用程序行为。 <br />
<br />
&nbsp;&nbsp;&nbsp; DOM4J是一个非常非常优秀的Java XML API，具有性能优异、功能强大和极端易用使用的特点，同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML，特别值得一提的是连Sun的JAXM也在用DOM4J. <br />
<br />
&nbsp;&nbsp;&nbsp; 2。比较 <br />
<br />
&nbsp;&nbsp;&nbsp; 1）DOM4J性能最好，连Sun的JAXM也在用DOM4J.目前许多开源项目中大量采用DOM4J，例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性，那就采用DOM4J. <br />
<br />
&nbsp;&nbsp;&nbsp; 2）JDOM和DOM在性能测试时表现不佳，在测试10M文档时内存溢出。在小文档情况下还值得考虑使用DOM和JDOM.虽然JDOM的开发者已经说明他们期望在正式发行版前专注性能问题，但是从性能观点来看，它确实没有值得推荐之处。另外，DOM仍是一个非常好的选择。DOM实现广泛应用于多种编程语言。它还是许多其它与XML相关的标准的基础，因为它正式获得W3C推荐（与基于非标准的Java模型相对），所以在某些类型的项目中可能也需要它（如在JavaScript中使用DOM）。 <br />
<br />
&nbsp;&nbsp;&nbsp; 3）SAX表现较好，这要依赖于它特定的解析方式－事件驱动。一个SAX检测即将到来的XML流，但并没有载入到内存（当然当XML流被读入时，会有部分文档暂时隐藏在内存中）。 <br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 3. 四种xml操作方式的基本使用方法 <br />
&nbsp;&nbsp;&nbsp; xml文件：
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Xml代码 </div>
</div>
<ol class="dp-xml">
    <li><span><span class="tag">&lt;?</span><span class="tag-name">xml</span><span>&nbsp;</span><span class="attribute">version</span><span>=</span><span class="attribute-value">"1.0"</span><span>&nbsp;</span><span class="attribute">encoding</span><span>=</span><span class="attribute-value">"gbk"</span><span class="tag">?&gt;</span><span class="tag">&lt;</span><span class="tag-name">list</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">node</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">name</span><span class="tag">&gt;</span><span>weidewei</span><span class="tag">&lt;/</span><span class="tag-name">name</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">space</span><span class="tag">&gt;</span><span>http://wishlife.<span class="hilite2">javaeye</span>.com</span><span class="tag">&lt;/</span><span class="tag-name">space</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">node</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">node</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">name</span><span class="tag">&gt;</span><span>flying</span><span class="tag">&lt;/</span><span class="tag-name">name</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">space</span><span class="tag">&gt;</span><span>http://user.qzone.qq.com/94611981</span><span class="tag">&lt;/</span><span class="tag-name">space</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">node</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">list</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre style="display: none" class="xml" name="code">&lt;?xml version="1.0" encoding="gbk"?&gt;&lt;list&gt;&lt;node&gt;&lt;name&gt;weidewei&lt;/name&gt;&lt;space&gt;http://wishlife.<span class="hilite2">javaeye</span>.com&lt;/space&gt;&lt;/node&gt;&lt;node&gt;&lt;name&gt;flying&lt;/name&gt;&lt;space&gt;http://user.qzone.qq.com/94611981&lt;/space&gt;&lt;/node&gt;&lt;/list&gt;
</pre>
<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; 程序代码: <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 </div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">import</span><span>&nbsp;java.io.File; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;java.util.Iterator; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;java.util.List; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;javax.xml.parsers.DocumentBuilder; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;javax.xml.parsers.DocumentBuilderFactory; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;javax.xml.parsers.SAXParser; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;javax.xml.parsers.SAXParserFactory; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.dom4j.io.SAXReader; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.jdom.Element; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.jdom.input.SAXBuilder; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.w3c.dom.Document; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.w3c.dom.NodeList; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.xml.sax.Attributes; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.xml.sax.InputSource; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.xml.sax.SAXException; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;org.xml.sax.helpers.DefaultHandler; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;MyXMLReader&nbsp;</span><span class="keyword">extends</span><span>&nbsp;DefaultHandler&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;java.util.Stack&nbsp;tags&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;java.util.Stack(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;MyXMLReader()&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">super</span><span>(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;DOM方式 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;V2.0 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@author&nbsp;David.Wei </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@date&nbsp;2008-4-11 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;void </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;DOM()&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">long</span><span>&nbsp;lasting&nbsp;=&nbsp;System.currentTimeMillis(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File&nbsp;f&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;File(</span><span class="string">"F:/xmltest.xml"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DocumentBuilderFactory&nbsp;factory&nbsp;=&nbsp;DocumentBuilderFactory &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.newInstance(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DocumentBuilder&nbsp;builder&nbsp;=&nbsp;factory.newDocumentBuilder(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Document&nbsp;doc&nbsp;=&nbsp;builder.parse(f); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NodeList&nbsp;nl&nbsp;=&nbsp;doc.getElementsByTagName(</span><span class="string">"node"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">for</span><span>&nbsp;(</span><span class="keyword">int</span><span>&nbsp;i&nbsp;=&nbsp;</span><span class="number">0</span><span>;&nbsp;i&nbsp;&lt;&nbsp;nl.getLength();&nbsp;i++)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"||&nbsp;Name:&nbsp;&nbsp;|"</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&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;doc.getElementsByTagName(</span><span class="string">"name"</span><span>).item(i) &nbsp;&nbsp;</span></span></li>
    <li><span>&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;.getFirstChild().getNodeValue()); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"||Space:&nbsp;&nbsp;|"</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&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;doc.getElementsByTagName(</span><span class="string">"space"</span><span>).item(i) &nbsp;&nbsp;</span></span></li>
    <li><span>&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;.getFirstChild().getNodeValue()); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"-------------------------------------------------"</span><span>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(Exception&nbsp;e)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"DOM&nbsp;RUNTIME："</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+&nbsp;(System.currentTimeMillis()&nbsp;-&nbsp;lasting)&nbsp;+&nbsp;</span><span class="string">"&nbsp;MS"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;SAX方式 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;V2.0 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@author&nbsp;David.Wei </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@date&nbsp;2008-4-11 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;void </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;SAX()&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">long</span><span>&nbsp;lasting&nbsp;=&nbsp;System.currentTimeMillis(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SAXParserFactory&nbsp;sf&nbsp;=&nbsp;SAXParserFactory.newInstance(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SAXParser&nbsp;sp&nbsp;=&nbsp;sf.newSAXParser(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyXMLReader&nbsp;reader&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;MyXMLReader(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sp.parse(</span><span class="keyword">new</span><span>&nbsp;InputSource(</span><span class="string">"F:/xmltest.xml"</span><span>),&nbsp;reader); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(Exception&nbsp;e)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"SAX&nbsp;RUNTIME："</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+&nbsp;(System.currentTimeMillis()&nbsp;-&nbsp;lasting)&nbsp;+&nbsp;</span><span class="string">"&nbsp;MS"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;startElement(String&nbsp;uri,&nbsp;String&nbsp;localName,&nbsp;String&nbsp;qName, &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Attributes&nbsp;attrs)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tags.push(qName); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;characters(</span><span class="keyword">char</span><span>&nbsp;ch[],&nbsp;</span><span class="keyword">int</span><span>&nbsp;start,&nbsp;</span><span class="keyword">int</span><span>&nbsp;length) &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">throws</span><span>&nbsp;SAXException&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;tag&nbsp;=&nbsp;(String)&nbsp;tags.peek(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(tag.equals(</span><span class="string">"name"</span><span>))&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"||&nbsp;Name:&nbsp;&nbsp;|"</span><span>&nbsp;+&nbsp;</span><span class="keyword">new</span><span>&nbsp;String(ch,&nbsp;start,&nbsp;length)); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(tag.equals(</span><span class="string">"space"</span><span>))&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"||Space:&nbsp;&nbsp;|"</span><span>&nbsp;+&nbsp;</span><span class="keyword">new</span><span>&nbsp;String(ch,&nbsp;start,&nbsp;length)); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"-------------------------------------------------"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;JDOM方式 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;V2.0 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@author&nbsp;David.Wei </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@date&nbsp;2008-4-11 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;void </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;JDOM()&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">long</span><span>&nbsp;lasting&nbsp;=&nbsp;System.currentTimeMillis(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SAXBuilder&nbsp;builder&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;SAXBuilder(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.jdom.Document&nbsp;doc&nbsp;=&nbsp;builder.build(</span><span class="keyword">new</span><span>&nbsp;File(</span><span class="string">"F:/xmltest.xml"</span><span>)); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Element&nbsp;foo&nbsp;=&nbsp;doc.getRootElement(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;allChildren&nbsp;=&nbsp;foo.getChildren(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">for</span><span>&nbsp;(</span><span class="keyword">int</span><span>&nbsp;i&nbsp;=&nbsp;</span><span class="number">0</span><span>;&nbsp;i&nbsp;&lt;&nbsp;allChildren.size();&nbsp;i++)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"||&nbsp;Name:&nbsp;&nbsp;|"</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&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;((Element)&nbsp;allChildren.get(i)).getChild(</span><span class="string">"name"</span><span>) &nbsp;&nbsp;</span></span></li>
    <li><span>&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;.getText()); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"||Space:&nbsp;&nbsp;|"</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&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;((Element)&nbsp;allChildren.get(i)).getChild(</span><span class="string">"space"</span><span>) &nbsp;&nbsp;</span></span></li>
    <li><span>&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;.getText()); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"-------------------------------------------------"</span><span>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(Exception&nbsp;e)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"JDOM&nbsp;RUNTIME："</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+&nbsp;(System.currentTimeMillis()&nbsp;-&nbsp;lasting)&nbsp;+&nbsp;</span><span class="string">"&nbsp;MS"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;DOM4J方式 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@since&nbsp;V2.0 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@author&nbsp;David.Wei </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@date&nbsp;2008-4-11 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;void </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;DOM4J()&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">long</span><span>&nbsp;lasting&nbsp;=&nbsp;System.currentTimeMillis(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File&nbsp;f&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;File(</span><span class="string">"F:/xmltest.xml"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SAXReader&nbsp;reader&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;SAXReader(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.dom4j.Document&nbsp;doc&nbsp;=&nbsp;reader.read(f); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.dom4j.Element&nbsp;root&nbsp;=&nbsp;doc.getRootElement(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;org.dom4j.Element&nbsp;foo; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">for</span><span>&nbsp;(Iterator&nbsp;i&nbsp;=&nbsp;root.elementIterator(</span><span class="string">"node"</span><span>);&nbsp;i.hasNext();)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foo&nbsp;=&nbsp;(org.dom4j.Element)&nbsp;i.next(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"||&nbsp;Name:&nbsp;&nbsp;|"</span><span>&nbsp;+&nbsp;foo.elementText(</span><span class="string">"name"</span><span>)); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"||Space:&nbsp;&nbsp;|"</span><span>&nbsp;+&nbsp;foo.elementText(</span><span class="string">"space"</span><span>)); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"-------------------------------------------------"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(Exception&nbsp;e)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"DOM4J&nbsp;RUNTIME："</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+&nbsp;(System.currentTimeMillis()&nbsp;-&nbsp;lasting)&nbsp;+&nbsp;</span><span class="string">"&nbsp;MS"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String&nbsp;arge[])&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MyXMLReader&nbsp;myXML&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;MyXMLReader(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"=====================DOM========================="</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myXML.DOM(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"=====================SAX========================="</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myXML.SAX(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"=====================JDOM========================"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myXML.JDOM(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"=====================DOM4J======================="</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myXML.DOM4J(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"================================================="</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">import java.io.File;
import java.util.Iterator;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.dom4j.io.SAXReader;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class MyXMLReader extends DefaultHandler {
java.util.Stack tags = new java.util.Stack();
public MyXMLReader() {
super();
}
/**
* DOM方式
* @since V2.0
* @author David.Wei
* @date 2008-4-11
* @return void
*/
public void DOM() {
long lasting = System.currentTimeMillis();
try {
File f = new File("F:/xmltest.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(f);
NodeList nl = doc.getElementsByTagName("node");
for (int i = 0; i &lt; nl.getLength(); i++) {
System.out.println("|| Name:  |"
+ doc.getElementsByTagName("name").item(i)
.getFirstChild().getNodeValue());
System.out.println("||Space:  |"
+ doc.getElementsByTagName("space").item(i)
.getFirstChild().getNodeValue());
System.out.println("-------------------------------------------------");			}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("DOM RUNTIME："
+ (System.currentTimeMillis() - lasting) + " MS");
}
/**
* SAX方式
* @since V2.0
* @author David.Wei
* @date 2008-4-11
* @return void
*/
public void SAX() {
long lasting = System.currentTimeMillis();
try {
SAXParserFactory sf = SAXParserFactory.newInstance();
SAXParser sp = sf.newSAXParser();
MyXMLReader reader = new MyXMLReader();
sp.parse(new InputSource("F:/xmltest.xml"), reader);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("SAX RUNTIME："
+ (System.currentTimeMillis() - lasting) + " MS");
}
public void startElement(String uri, String localName, String qName,
Attributes attrs) {
tags.push(qName);
}
public void characters(char ch[], int start, int length)
throws SAXException {
String tag = (String) tags.peek();
if (tag.equals("name")) {
System.out.println("|| Name:  |" + new String(ch, start, length));
}
if (tag.equals("space")) {
System.out.println("||Space:  |" + new String(ch, start, length));
}
System.out.println("-------------------------------------------------");
}
/**
* JDOM方式
* @since V2.0
* @author David.Wei
* @date 2008-4-11
* @return void
*/
public void JDOM() {
long lasting = System.currentTimeMillis();
try {
SAXBuilder builder = new SAXBuilder();
org.jdom.Document doc = builder.build(new File("F:/xmltest.xml"));
Element foo = doc.getRootElement();
List allChildren = foo.getChildren();
for (int i = 0; i &lt; allChildren.size(); i++) {
System.out.println("|| Name:  |"
+ ((Element) allChildren.get(i)).getChild("name")
.getText());
System.out.println("||Space:  |"
+ ((Element) allChildren.get(i)).getChild("space")
.getText());
System.out.println("-------------------------------------------------");			}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("JDOM RUNTIME："
+ (System.currentTimeMillis() - lasting) + " MS");
}
/**
* DOM4J方式
* @since V2.0
* @author David.Wei
* @date 2008-4-11
* @return void
*/
public void DOM4J() {
long lasting = System.currentTimeMillis();
try {
File f = new File("F:/xmltest.xml");
SAXReader reader = new SAXReader();
org.dom4j.Document doc = reader.read(f);
org.dom4j.Element root = doc.getRootElement();
org.dom4j.Element foo;
for (Iterator i = root.elementIterator("node"); i.hasNext();) {
foo = (org.dom4j.Element) i.next();
System.out.println("|| Name:  |" + foo.elementText("name"));
System.out.println("||Space:  |" + foo.elementText("space"));
System.out.println("-------------------------------------------------");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("DOM4J RUNTIME："
+ (System.currentTimeMillis() - lasting) + " MS");
}
public static void main(String arge[]) {
MyXMLReader myXML = new MyXMLReader();
System.out.println("=====================DOM=========================");
myXML.DOM();
System.out.println("=====================SAX=========================");
myXML.SAX();
System.out.println("=====================JDOM========================");
myXML.JDOM();
System.out.println("=====================DOM4J=======================");
myXML.DOM4J();
System.out.println("=================================================");
}
}</pre>
<br />
<br />
运行结果: <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Html代码 </div>
</div>
<ol class="dp-xml">
    <li><span><span>=====================</span><span class="attribute">DOM</span><span>========================= &nbsp;&nbsp;</span></span></li>
    <li><span>||&nbsp;Name:&nbsp;&nbsp;|weidewei &nbsp;&nbsp;</span></li>
    <li><span>||Space:&nbsp;&nbsp;|http://wishlife.<span class="hilite2">javaeye</span>.com &nbsp;&nbsp;</span></li>
    <li><span>------------------------------------------------- &nbsp;&nbsp;</span></li>
    <li><span>||&nbsp;Name:&nbsp;&nbsp;|flying &nbsp;&nbsp;</span></li>
    <li><span>||Space:&nbsp;&nbsp;|http://user.qzone.qq.com/94611981 &nbsp;&nbsp;</span></li>
    <li><span>------------------------------------------------- &nbsp;&nbsp;</span></li>
    <li><span>DOM&nbsp;RUNTIME：62&nbsp;</span><span class="attribute">MS</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>=====================</span><span class="attribute">SAX</span><span>========================= &nbsp;&nbsp;</span></span></li>
    <li><span>||&nbsp;Name:&nbsp;&nbsp;|weidewei &nbsp;&nbsp;</span></li>
    <li><span>------------------------------------------------- &nbsp;&nbsp;</span></li>
    <li><span>||Space:&nbsp;&nbsp;|http://wishlife.<span class="hilite2">javaeye</span>.com &nbsp;&nbsp;</span></li>
    <li><span>------------------------------------------------- &nbsp;&nbsp;</span></li>
    <li><span>||&nbsp;Name:&nbsp;&nbsp;|flying &nbsp;&nbsp;</span></li>
    <li><span>------------------------------------------------- &nbsp;&nbsp;</span></li>
    <li><span>||Space:&nbsp;&nbsp;|http://user.qzone.qq.com/94611981 &nbsp;&nbsp;</span></li>
    <li><span>------------------------------------------------- &nbsp;&nbsp;</span></li>
    <li><span>SAX&nbsp;RUNTIME：16&nbsp;</span><span class="attribute">MS</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>=====================</span><span class="attribute">JDOM</span><span>======================== &nbsp;&nbsp;</span></span></li>
    <li><span>||&nbsp;Name:&nbsp;&nbsp;|weidewei &nbsp;&nbsp;</span></li>
    <li><span>||Space:&nbsp;&nbsp;|http://wishlife.<span class="hilite2">javaeye</span>.com &nbsp;&nbsp;</span></li>
    <li><span>------------------------------------------------- &nbsp;&nbsp;</span></li>
    <li><span>||&nbsp;Name:&nbsp;&nbsp;|flying &nbsp;&nbsp;</span></li>
    <li><span>||Space:&nbsp;&nbsp;|http://user.qzone.qq.com/94611981 &nbsp;&nbsp;</span></li>
    <li><span>------------------------------------------------- &nbsp;&nbsp;</span></li>
    <li><span>JDOM&nbsp;RUNTIME：78&nbsp;</span><span class="attribute">MS</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>=====================</span><span class="attribute">DOM4J</span><span>======================= &nbsp;&nbsp;</span></span></li>
    <li><span>||&nbsp;Name:&nbsp;&nbsp;|weidewei &nbsp;&nbsp;</span></li>
    <li><span>||Space:&nbsp;&nbsp;|http://wishlife.<span class="hilite2">javaeye</span>.com &nbsp;&nbsp;</span></li>
    <li><span>------------------------------------------------- &nbsp;&nbsp;</span></li>
    <li><span>||&nbsp;Name:&nbsp;&nbsp;|flying &nbsp;&nbsp;</span></li>
    <li><span>||Space:&nbsp;&nbsp;|http://user.qzone.qq.com/94611981 &nbsp;&nbsp;</span></li>
    <li><span>------------------------------------------------- &nbsp;&nbsp;</span></li>
    <li><span>DOM4J&nbsp;RUNTIME：78&nbsp;</span><span class="attribute">MS</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>=================================================&nbsp;&nbsp;</span></li>
</ol>
</div>
<img src ="http://www.blogjava.net/lanxin1020/aggbug/269551.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2009-05-08 10:52 <a href="http://www.blogjava.net/lanxin1020/archive/2009/05/08/269551.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> instanceof(转)</title><link>http://www.blogjava.net/lanxin1020/archive/2009/05/07/269393.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Thu, 07 May 2009 05:14:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2009/05/07/269393.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/269393.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2009/05/07/269393.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/269393.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/269393.html</trackback:ping><description><![CDATA[Java中的instanceof关键字 <cite class="fav_csdnstylebykimi"><a class="fav_csdnstylebykimi" title="收藏到我的网摘中，并分享给我的朋友" href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(saveit=window.open('http://wz.csdn.net/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'saveit','scrollbars=no,width=590,height=300,left=75,top=20,status=no,resizable=yes'));saveit.focus();">收藏</a></cite>
<div class="blogstory"><script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>&nbsp;instanceof是Java的一个二元操作符，和==，&gt;，&lt;是同一类东东。由于它是由字母组成的，所以也是Java的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例，返回boolean类型的数据。举个例子：<br />
<br />
　　String s = "I AM an Object!";<br />
　　boolean isObject = s instanceof Object;<br />
<br />
　　我们声明了一个String对象引用，指向一个String对象，然后用instancof来测试它所指向的对象是否是Object类的一个实例，显然，这是真的，所以返回true，也就是isObject的值为True。<br />
　　instanceof有一些用处。比如我们写了一个处理账单的系统，其中有这样三个类：<br />
<br />
　　public class Bill {//省略细节}<br />
　　public class PhoneBill extends Bill {//省略细节}<br />
　　public class GasBill extends Bill {//省略细节}<br />
<br />
　　在处理程序里有一个方法，接受一个Bill类型的对象，计算金额。假设两种账单计算方法不同，而传入的Bill对象可能是两种中的任何一种，所以要用instanceof来判断：<br />
<br />
　　public double calculate(Bill bill) {<br />
　　if (bill instanceof PhoneBill) {<br />
　　//计算电话账单<br />
　　}<br />
　　if (bill instanceof GasBill) {<br />
　　//计算燃气账单<br />
　　}<br />
　　...<br />
　　}<br />
　　这样就可以用一个方法处理两种子类。<br />
<br />
　　然而，这种做法通常被认为是没有好好利用面向对象中的多态性。其实上面的功能要求用方法重载完全可以实现，这是面向对象变成应有的做法，避免回到结构化编程模式。只要提供两个名字和返回值都相同，接受参数类型不同的方法就可以了：<br />
<br />
　　public double calculate(PhoneBill bill) {<br />
　　//计算电话账单<br />
　　}<br />
<br />
　　public double calculate(GasBill bill) {<br />
　　//计算燃气账单<br />
　　}<br />
<br />
　　所以，使用instanceof在绝大多数情况下并不是推荐的做法，应当好好利用多态。</div>
<img src ="http://www.blogjava.net/lanxin1020/aggbug/269393.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2009-05-07 13:14 <a href="http://www.blogjava.net/lanxin1020/archive/2009/05/07/269393.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java.io.File</title><link>http://www.blogjava.net/lanxin1020/archive/2009/05/07/269369.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Thu, 07 May 2009 03:16:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2009/05/07/269369.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/269369.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2009/05/07/269369.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/269369.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/269369.html</trackback:ping><description><![CDATA[<ol class="dp-j">
    <li><span><span class="keyword">package</span><span>&nbsp;cn.edu.tongji.cims.wade.system; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">import</span><span>&nbsp;java.io.*; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;FileOperate&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;FileOperate()&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;新建目录 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;folderPath&nbsp;String&nbsp;如&nbsp;c:/fqf </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;boolean </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;newFolder(String&nbsp;folderPath)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;filePath&nbsp;=&nbsp;folderPath; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filePath&nbsp;=&nbsp;filePath.toString(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;java.io.File&nbsp;myFilePath&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;java.io.File(filePath); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(!myFilePath.exists())&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myFilePath.mkdir(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(Exception&nbsp;e)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"新建目录操作出错"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;新建文件 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;filePathAndName&nbsp;String&nbsp;文件路径及名称&nbsp;如c:/fqf.txt </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;fileContent&nbsp;String&nbsp;文件内容 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;boolean </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;newFile(String&nbsp;filePathAndName,&nbsp;String&nbsp;fileContent)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;filePath&nbsp;=&nbsp;filePathAndName; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filePath&nbsp;=&nbsp;filePath.toString(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File&nbsp;myFilePath&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;File(filePath); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(!myFilePath.exists())&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myFilePath.createNewFile(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileWriter&nbsp;resultFile&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;FileWriter(myFilePath); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PrintWriter&nbsp;myFile&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;PrintWriter(resultFile); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;strContent&nbsp;=&nbsp;fileContent; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myFile.println(strContent); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resultFile.close(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(Exception&nbsp;e)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"新建目录操作出错"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;删除文件 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;filePathAndName&nbsp;String&nbsp;文件路径及名称&nbsp;如c:/fqf.txt </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;fileContent&nbsp;String </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;boolean </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;delFile(String&nbsp;filePathAndName)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;filePath&nbsp;=&nbsp;filePathAndName; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filePath&nbsp;=&nbsp;filePath.toString(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;java.io.File&nbsp;myDelFile&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;java.io.File(filePath); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myDelFile.delete(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(Exception&nbsp;e)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"删除文件操作出错"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;删除文件夹 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;filePathAndName&nbsp;String&nbsp;文件夹路径及名称&nbsp;如c:/fqf </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;fileContent&nbsp;String </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;boolean </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;delFolder(String&nbsp;folderPath)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delAllFile(folderPath);&nbsp;</span><span class="comment">//删除完里面所有内容 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;filePath&nbsp;=&nbsp;folderPath; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filePath&nbsp;=&nbsp;filePath.toString(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;java.io.File&nbsp;myFilePath&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;java.io.File(filePath); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myFilePath.delete();&nbsp;</span><span class="comment">//删除空文件夹 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(Exception&nbsp;e)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"删除文件夹操作出错"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;删除文件夹里面的所有文件 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;path&nbsp;String&nbsp;文件夹路径&nbsp;如&nbsp;c:/fqf </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;delAllFile(String&nbsp;path)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;File&nbsp;file&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;File(path); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(!file.exists())&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(!file.isDirectory())&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;String[]&nbsp;tempList&nbsp;=&nbsp;file.list(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;File&nbsp;temp&nbsp;=&nbsp;</span><span class="keyword">null</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">for</span><span>&nbsp;(</span><span class="keyword">int</span><span>&nbsp;i&nbsp;=&nbsp;</span><span class="number">0</span><span>;&nbsp;i&nbsp;&lt;&nbsp;tempList.length;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(path.endsWith(File.separator))&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;File(path&nbsp;+&nbsp;tempList[i]); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">else</span><span>&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;File(path&nbsp;+&nbsp;File.separator&nbsp;+&nbsp;tempList[i]); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(temp.isFile())&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp.delete(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(temp.isDirectory())&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delAllFile(path+</span><span class="string">"/"</span><span>+&nbsp;tempList[i]);</span><span class="comment">//先删除文件夹里面的文件 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delFolder(path+</span><span class="string">"/"</span><span>+&nbsp;tempList[i]);</span><span class="comment">//再删除空文件夹 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;复制单个文件 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;oldPath&nbsp;String&nbsp;原文件路径&nbsp;如：c:/fqf.txt </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;newPath&nbsp;String&nbsp;复制后路径&nbsp;如：f:/fqf.txt </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;boolean </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;copyFile(String&nbsp;oldPath,&nbsp;String&nbsp;newPath)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>&nbsp;bytesum&nbsp;=&nbsp;</span><span class="number">0</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>&nbsp;byteread&nbsp;=&nbsp;</span><span class="number">0</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File&nbsp;oldfile&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;File(oldPath); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(oldfile.exists())&nbsp;{&nbsp;</span><span class="comment">//文件存在时 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InputStream&nbsp;inStream&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;FileInputStream(oldPath);&nbsp;</span><span class="comment">//读入原文件 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileOutputStream&nbsp;fs&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;FileOutputStream(newPath); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">byte</span><span>[]&nbsp;buffer&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;</span><span class="keyword">byte</span><span>[</span><span class="number">1444</span><span>]; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>&nbsp;length; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">while</span><span>&nbsp;(&nbsp;(byteread&nbsp;=&nbsp;inStream.read(buffer))&nbsp;!=&nbsp;-</span><span class="number">1</span><span>)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bytesum&nbsp;+=&nbsp;byteread;&nbsp;</span><span class="comment">//字节数&nbsp;文件大小 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(bytesum); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fs.write(buffer,&nbsp;</span><span class="number">0</span><span>,&nbsp;byteread); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inStream.close(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(Exception&nbsp;e)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"复制单个文件操作出错"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;复制整个文件夹内容 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;oldPath&nbsp;String&nbsp;原文件路径&nbsp;如：c:/fqf </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;newPath&nbsp;String&nbsp;复制后路径&nbsp;如：f:/fqf/ff </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;boolean </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;copyFolder(String&nbsp;oldPath,&nbsp;String&nbsp;newPath)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span class="keyword">new</span><span>&nbsp;File(newPath)).mkdirs();&nbsp;</span><span class="comment">//如果文件夹不存在&nbsp;则建立新文件夹 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File&nbsp;a=</span><span class="keyword">new</span><span>&nbsp;File(oldPath); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String[]&nbsp;file=a.list(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File&nbsp;temp=</span><span class="keyword">null</span><span>; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">for</span><span>&nbsp;(</span><span class="keyword">int</span><span>&nbsp;i&nbsp;=&nbsp;</span><span class="number">0</span><span>;&nbsp;i&nbsp;&lt;&nbsp;file.length;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(oldPath.endsWith(File.separator)){ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp=</span><span class="keyword">new</span><span>&nbsp;File(oldPath+file[i]); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">else</span><span>{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp=</span><span class="keyword">new</span><span>&nbsp;File(oldPath+File.separator+file[i]); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(temp.isFile()){ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileInputStream&nbsp;input&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;FileInputStream(temp); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileOutputStream&nbsp;output&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;FileOutputStream(newPath&nbsp;+&nbsp;</span><span class="string">"/"</span><span>&nbsp;+ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(temp.getName()).toString()); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">byte</span><span>[]&nbsp;b&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;</span><span class="keyword">byte</span><span>[</span><span class="number">1024</span><span>&nbsp;*&nbsp;</span><span class="number">5</span><span>]; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">int</span><span>&nbsp;len; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">while</span><span>&nbsp;(&nbsp;(len&nbsp;=&nbsp;input.read(b))&nbsp;!=&nbsp;-</span><span class="number">1</span><span>)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;output.write(b,&nbsp;</span><span class="number">0</span><span>,&nbsp;len); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;output.flush(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;output.close(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;input.close(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(temp.isDirectory()){</span><span class="comment">//如果是子文件夹 </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;copyFolder(oldPath+</span><span class="string">"/"</span><span>+file[i],newPath+</span><span class="string">"/"</span><span>+file[i]); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(Exception&nbsp;e)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"复制整个文件夹内容操作出错"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;移动文件到指定目录 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;oldPath&nbsp;String&nbsp;如：c:/fqf.txt </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;newPath&nbsp;String&nbsp;如：d:/fqf.txt </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;moveFile(String&nbsp;oldPath,&nbsp;String&nbsp;newPath)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;copyFile(oldPath,&nbsp;newPath); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;delFile(oldPath); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;移动文件到指定目录 </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;oldPath&nbsp;String&nbsp;如：c:/fqf.txt </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;newPath&nbsp;String&nbsp;如：d:/fqf.txt </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;moveFolder(String&nbsp;oldPath,&nbsp;String&nbsp;newPath)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;copyFolder(oldPath,&nbsp;newPath); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;delFolder(oldPath); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
<img src ="http://www.blogjava.net/lanxin1020/aggbug/269369.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2009-05-07 11:16 <a href="http://www.blogjava.net/lanxin1020/archive/2009/05/07/269369.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java Native Access （转）</title><link>http://www.blogjava.net/lanxin1020/archive/2009/05/07/269365.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Thu, 07 May 2009 03:08:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2009/05/07/269365.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/269365.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2009/05/07/269365.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/269365.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/269365.html</trackback:ping><description><![CDATA[<center><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果在Java程序中你使用Java Native Interface(JNI) 来调用某个特定平台下的本地库文件，你就会发现这个过程很单调、乏味。Jeff Friesen一直在介绍一个知名度很低的Java开源项目：Java Native Access---它能够避免因使用JNI导致的错误和乏味，同时它还能让你通过编程的方式调用C语言库。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在Java语言没有提供必要的APIs的情况下，Java程序使用Java Native Interface (JNI)来调用特定平台下的本地库是必要的。例如：在Windows XP平台中，我使用过JNI来调用通用串行总线和基于TWAIN的扫描仪器的库；在更古老的Windows NT平台中，调用过智能卡的库。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我按照一个基本的、乏味的流程来解决这些问题：首先，我创建一个Java类用来载入JNI-friendly库（这个库能过访问其他的库）并且声明这个类的本地方法。然后，在使用JDK中的javah工具为JNI-friendly库中的函数---函数和这个类中的本地方法一一对应---创建一个代理。最后，我使用C语言写了一个库并用C编译器编译了这些代码。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;尽管完成这些流程并不是很困难，但是写C代码是一个很缓慢的过程---例如： C语言中的字符串处理是通过指针来实现的，这会很复杂的。而且，使用JNI很容易出现错误，导致内存泄漏、很难找到程序崩溃的原因。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在<a href="http://www.javaworld.com/javaworld/jw-02-2008/jw-02-opensourcejava-jna.html#resources" target="_new">Java开源系列</a>的第二篇文章中，我要介绍一个更简单、更安全的解决方法：Todd Fast and Timothy Wall的<a href="http://www.javaworld.com/javaworld/jw-02-2008/jw-02-opensourcejava-jna.html#resources" target="_new">Java Native Access (JNA)</a> 项目。JNA能够让你在Java程序中调用本地方法时避免使用C和Java Native Interface。在这篇文章中，让我以简要的介绍&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JNA和运行示例必需的软件来开始下面的内容。然后，向你展示如何使用JNA将3个Windows本地库中的有用代码移植到Java程序中。<br />
<br />
<strong><span style="font-size: 14px"><span style="color: blue">Get started with JNA（JNA入门）</span></span></strong><br />
<br />
<a href="https://jna.dev.java.net/" target="_new">Java Native Access 项目</a> 在Java.net上，你可以到这个网站上现在这个项目的代码和在线帮助文档。虽然在下载有5个相关的jar文件，在本文中你仅仅需要下载其中的jna.jar和example.jar。<br />
<br />
Jna.jar提供基本的、运行这些示例文件必需的jna运行环境。这个jna.jar文件除了有Unix、Linux、Windows和Mac OS X平台相关的JNT-friendly本地库外，还包含其他几个类包。每一个本地库都是用来访问相对应平台下的本地方法的。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;example.jar包含了不同的示例来表明JNA的用途。其中的一个例子是使用JNA来实现一个在不同平台下的透明视窗技术的API。在文章最后的示例中将要展示如何使用这个API修复上个月的文章关于VerifyAge2应用中辨认透明效果的问题。<br />
<br />
<strong><span style="font-size: 14px"><span style="color: blue">获取本地时间（Get local time）</span></span></strong><br />
<br />
如果你在<a href="https://jna.dev.java.net/" target="_new">Java Native Access</a> 首页 看过&#8220;JNA如何入门&#8221;，你就会知道一个很简单的关于调用Windows 平台下的API函数：GetSystemTime（） 的JNA示例。这个不完整的例子只是展示了JNA的基本特点。（在例子的基础上，我做了一个更完整的基于Windows的例子来介绍JNA）我在Windows平台下完善了这个例子来介绍JNA。<br />
<br />
第一例子基于Windows GetLocalTime() API函数返回本地当前的时间和日期。和GetSystemTime()不同的是，返回的时间/日期是<a href="http://en.wikipedia.org/wiki/Coordinated_Universal_Time" target="_new">协调通用时间</a>(UTC)格式的，GetLocalTime()返回的时间/日期信息的格式是根据当前时区来表示。<br />
<br />
在一个Java程序中使用JNA调用GetLocalTime，你需要知道这个函数所在的Windows平台下的动态链接库（DLL）的名称（和可能所在的地理区域）。我们发现GetLocalTime()和GetSystemTime在同一个DLL文件中：kernel32.dll。你还需要知道GetLocalTime()在C语言环境中的申明。申明如下Listing 1：<br />
<br />
<strong><span style="font-size: 12px"><span style="color: green">Listing 1. GetLocalTime在C语言中的申明</span></span></strong><br />
<br />
</center>
<pre class="overflow">typedef struct<br />
{<br />
&nbsp;&nbsp; WORD wYear;<br />
&nbsp;&nbsp; WORD wMonth;<br />
&nbsp;&nbsp; WORD wDayOfWeek;<br />
&nbsp;&nbsp; WORD wDay;<br />
&nbsp;&nbsp; WORD wHour;<br />
&nbsp;&nbsp; WORD wMinute;<br />
&nbsp;&nbsp; WORD wSecond;<br />
&nbsp;&nbsp; WORD wMilliseconds;<br />
}<br />
SYSTEMTIME, *LPSYSTEMTIME;<br />
<br />
VOID GetLocalTime(LPSYSTEMTIME lpst);</pre>
<br />
<br />
这个基于C语言的申明表明传到这个函数的参数数目和类型。在这个例子中，只有一个参数---一个指向Windows SYSTEMTIME结构体的指针。而且，每个结构体成员的类型是16bit长度的无符号整型。根据这些信息，你能够创建一个完全描述GetLocalTime()函数的接口，如Listing 2中所示：<br />
<br />
<strong><span style="font-size: 12px"><span style="color: green">Listing 2. Kernel32.java</span></span></strong><br />
<br />
<pre class="overflow">// Kernel32.java<br />
<br />
import com.sun.jna.*;<br />
import com.sun.jna.win32.*;<br />
<br />
public interface Kernel32 extends StdCallLibrary<br />
{<br />
&nbsp;&nbsp; public static class SYSTEMTIME extends Structure<br />
&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public short wYear;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public short wMonth;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public short wDayOfWeek;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public short wDay;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public short wHour;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public short wMinute;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public short wSecond;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public short wMilliseconds;<br />
&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp; void GetLocalTime (SYSTEMTIME result);<br />
}</pre>
<br />
<br />
<strong><span style="font-size: 14px"><span style="color: blue">Kernel32 接口（The Kernel32 interface）</span></span></strong><br />
<br />
因为JNA使用通过一个接口来访问某个库中的函数，Listing 2表示了一个描述GetLocalTime()的接口。根据约定，我把接口命名为Kernel32是因为GetLocalTime()在Windows的kernel32.dll库。<br />
<br />
这个接口必须继承com.sun..jna.Library接口。因为Windows API函数遵循stdcall调用协议（stdcall calling convention），为Windows API申明的接口也必须继承com.sun.jna.win32. StdCallLibrary接口。因此这个接口共继承了Library 和 com.sun.jna.win32.StdCall两个接口。<br />
<br />
在前面，你已经知道了GetLocalTime() 需要一个指向SYSTEMTIME结构体的指针作为它唯一的参数。因为Java不支持指针，JNA是通过申明一个com.sun.jna.Structure的子类来代替的。根据java文档中抽象类的概念，在参数环境中，Structure相当于C语言的struct*。<br />
<br />
在SYSTEMTIME类中的字段和C结构体中的相对应的属性字段的顺序是一一对应的。保证字段顺序的一致性是非常重要的。例如，我发现交换wYear和wMonth会导致wYear和wMonth值互换。<br />
<br />
每个字段在java中是short integer类型的。按照JNA首页上 &#8220;默认类型映射&#8221;章节给出的提示，这个short integer分配类型是正确。然而，我们应该知道一个重要的区别：Windows平台下的WORD类型等同于C语言环境中的16-bit的无符号的short integer，而java中short integer是16-bit有符号的short integer。<br />
<br />
<strong><span style="font-size: 12px"><span style="color: green">一个类型映射的问题</span></span></strong><br />
<br />
通过比较一个API 函数返回的整型值，你会发现Windows/C 语言的无符号整型和Java语言的有符号整型的JNA类型映射是有问题的。在比较的过程中，如果你不细心，那么错误的执行过程可能导致决定性情况。导致这种后果是因为忘记任何数值的符号位的确定是根据：在无符号整型的情况下会被解释为正号，而在有符号整型的进制中被理解为负号的。<br />
<br />
<strong><span style="font-size: 12px"><span style="color: green">通过Kernel32获取本地时间（Access the local time with Kernel32）</span></span></strong><br />
<br />
JNA首页上的GetSystemTime()示例已经表明必须使用预先申明的接口为本地库分配一个实例对象。你可以通过com.sun.jna.Native类中静态公用方法loadLibrary(String name, Class interfaceClass)来完成上述的目标。Listing 3 所示：<br />
<br />
<strong><span style="font-size: 12px"><span style="color: green">Listing 3. LocalTime.java</span></span></strong><br />
<br />
<pre class="overflow">// LocalTime.java<br />
<br />
import com.sun.jna.*;<br />
<br />
public class LocalTime<br />
{<br />
&nbsp;&nbsp; public static void main (String [] args)<br />
&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Kernel32 lib = (Kernel32) Native.loadLibrary ("kernel32",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Kernel32.class);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Kernel32.SYSTEMTIME time = new Kernel32.SYSTEMTIME ();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lib.GetLocalTime (time);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println ("Year is "+time.wYear);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println ("Month is "+time.wMonth);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println ("Day of Week is "+time.wDayOfWeek);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println ("Day is "+time.wDay);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println ("Hour is "+time.wHour);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println ("Minute is "+time.wMinute);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println ("Second is "+time.wSecond);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println ("Milliseconds are "+time.wMilliseconds);<br />
&nbsp;&nbsp; }<br />
}</pre>
<br />
<br />
Listing 3 执行Kernel32 lib = (Kernel32) Native.loadLibrary ("kernel32", Kernel32.class);来分配一个Kernel32实例对象并且装载kernel32.dll。因为kernel32.dll是Windows平台下标准的dll文件，所以不要指定访问这个库的路径。然而，如果找不到这个dll文件，loadLibrary()会抛出一个UnsatisfiedLinkError异常。<br />
<br />
Kernel32.SYSTEMTIME time = new Kernel32.SYSTEMTIME ();创建了一个SYSTEMTIME结构体的示例。初始化后下面是lib.GetLocalTime (time);，这句话使用本地的时间/日期来给这个实例赋值。几个System.out.println()语句是输出这些值。<br />
<br />
<strong><span style="font-size: 14px"><span style="color: blue">编译和运行这个应用（Compile and run the application）</span></span></strong><br />
<br />
这部分很容易。假设jna.jar、Kernel32.java和LocalTime.java是放在当前文件夹中，调用java &#8211;cp jna.jar;. LocalTime.java来编译这个应用的源代码。如果在Windows平台下，调用invoke java &#8211;cp jna.jar;. LocalTime 来运行这个应用。你可以得到类似与Listing 4的输出结果：<br />
<br />
<strong><span style="font-size: 12px"><span style="color: green">Listing 4. 从LocalTime.java生成的输出</span></span></strong><br />
<br />
<pre class="overflow">Year is 2007<br />
Month is 12<br />
Day of Week is 3<br />
Day is 19<br />
Hour is 12<br />
Minute is 35<br />
Second is 13<br />
Milliseconds are 156</pre>
<br />
<br />
<strong><span style="font-size: 14px"><span style="color: blue">获取操纵杆信息（Accessing joystick device info）</span></span></strong><br />
<br />
上面的例子已经介绍了JNA，但是这个获取本地时间和日期的例子并没有很好的利用这个技术，甚至也没有体现JNI的价值。Java语言中的System.currentTimeMillis()函数已经以毫秒的格式返回了这些信息。因为Java语言没有为游戏控制器提供API，所以获取操纵杆的信息更适合JNA的使用。<br />
<br />
例如，你要构建一个平台无关的Java库，而且这些库使用JNA调用Linux, Mac OS X, Windwos和Unix平台中本地的操纵杆API。为了简洁和方便起见，这个例子仅仅是调用Windows平台下的操纵杆API。而且我将重点介绍这个API很小的一部分。<br />
<br />
类似GetLocalTime()，第一步是辨别出操作杆API的DLL，这个DLL是winmm.dll，和kernel32.dll在同一个文件夹中，它包含了操作杆的API和其他的多媒体APIs。还需知道要被使用的操作杆函数基于C语言的声明。这些函数声明已经在Listing 5中列出来了。<br />
<br />
<strong><span style="font-size: 12px"><span style="color: green">Listing 5. C-based declarations for some Joystick API functions</span></span></strong><br />
<br />
<pre class="overflow">#define MAXPNAMELEN 32<br />
<br />
typedef struct<br />
{<br />
&nbsp;&nbsp; WORD&nbsp;&nbsp;wMid;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// manufacturer identifier<br />
&nbsp;&nbsp; WORD&nbsp;&nbsp;wPid;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// product identifier<br />
&nbsp;&nbsp; TCHAR szPname&nbsp;&nbsp;<strong><a class="wiki_link" title="wiki link" href="http://wiki.matrix.org.cn/Wiki.jsp?page=MAXPNAMELEN">MAXPNAMELEN</a></strong> ; // product name<br />
&nbsp;&nbsp; UINT&nbsp;&nbsp;wXmin;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // minimum x position<br />
&nbsp;&nbsp; UINT&nbsp;&nbsp;wXmax;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // maximum x position<br />
&nbsp;&nbsp; UINT&nbsp;&nbsp;wYmin;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // minimum y position<br />
&nbsp;&nbsp; UINT&nbsp;&nbsp;wYmax;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // maximum y position<br />
&nbsp;&nbsp; UINT&nbsp;&nbsp;wZmin;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // minimum z position<br />
&nbsp;&nbsp; UINT&nbsp;&nbsp;wZmax;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // maximum z position<br />
&nbsp;&nbsp; UINT&nbsp;&nbsp;wNumButtons;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // number of buttons<br />
&nbsp;&nbsp; UINT&nbsp;&nbsp;wPeriodMin;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// smallest supported polling interval when captured<br />
&nbsp;&nbsp; UINT&nbsp;&nbsp;wPeriodMax;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// largest supported polling interval when captured<br />
}<br />
JOYCAPS, *LPJOYCAPS;<br />
<br />
MMRESULT joyGetDevCaps(UINT IDDevice, LPJOYCAPS lpjc, UINT cbjc);<br />
<br />
UINT joyGetNumDevs(VOID);</pre>
<br />
<br />
<strong><span style="font-size: 14px"><span style="color: blue">操作杆API的函数（Functions of the Joystick API）</span></span></strong><br />
<br />
在Windows平台下是通过以joy作为函数名开始的函数以及被各种函数调用的结构体来实现操作杆API的。例如，joyGetNumDevs()返回的是这个平台下支持的操作杆设备最多的数目；joyGetDevCaps()返回的是每个连接上的操纵杆的质量。<br />
<br />
joyGetDevCaps()函数需要3个参数：<br />
* 处在0到joyGetNumDevs()-1之间的操作杆ID<br />
* 保存返回的质量信息的JOYCAPS结构体的地址<br />
* JOYCAPS结构体的字节大小<br />
虽然它的结果不同，这个函数返回的是一个32位的无符号整型结果，而且0表示一个已经连接的操纵杆。<br />
<br />
JOYCAPS结构体有3种类型。Windows平台下的WORD（16位无符号短整型）类型对应的是Java语言中16位有符号短整型。除此之外，Windows下的UINT（32位无符号整型）类型是和Java语言中32位有符号整型相对应的。而Windows平台上的text character就是TCHAR类型。<br />
<br />
微软通过TCHAR类型使开发人员能够从ASCII类型的函数参数平滑的转移到Unicode字符类型的函数参数上。而且，拥有text类型参数的函数的实现是通过宏转变为对应的ASCII或者wide-character的函数。例如，joyGetDevCaps()是一个对应joyGetDevCapsA() 和 joyGetDevCapsW()的宏。<br />
<br />
<strong><span style="font-size: 14px"><span style="color: blue">使用TCHAR（Working with TCHAR）</span></span></strong><br />
<br />
使用TCHAR和将TCHAR转变的宏会导致基于C语言的申明向基于JNA接口的转换<br />
变得有点复杂—你在使用ASCII或者wide-character版本的操纵杆函数吗？两种版本都在如下的接口中展示了：<br />
<br />
<strong><span style="font-size: 12px"><span style="color: green">Listing 6. WinMM.java</span></span></strong><br />
<br />
<pre class="overflow">// WinMM.java<br />
<br />
import com.sun.jna.*;<br />
import com.sun.jna.win32.*;<br />
<br />
public interface WinMM extends StdCallLibrary<br />
{<br />
&nbsp;&nbsp; final static int JOYCAPSA_SIZE = 72;<br />
<br />
&nbsp;&nbsp; public static class JOYCAPSA extends Structure<br />
&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public short wMid;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public short wPid;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public byte szPname [] = new byte [32];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wXmin;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wXmax;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wYmin;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wYmax;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wZmin;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wZmax;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wNumButtons;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wPeriodMin;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wPeriodMax;<br />
&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp; int joyGetDevCapsA (int id, JOYCAPSA caps, int size);<br />
<br />
&nbsp;&nbsp; final static int JOYCAPSW_SIZE = 104;<br />
<br />
&nbsp;&nbsp; public static class JOYCAPSW extends Structure<br />
&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public short wMid;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public short wPid;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public char szPname [] = new char [32];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wXmin;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wXmax;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wYmin;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wYmax;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wZmin;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wZmax;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wNumButtons;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wPeriodMin;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int wPeriodMax;<br />
&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp; int joyGetDevCapsW (int id, JOYCAPSW caps, int size);<br />
<br />
&nbsp;&nbsp; int joyGetNumDevs ();<br />
}</pre>
<br />
<br />
Listing 6没有介绍JNA的新特性。实际上，JNA强调了对本地库的接口命名规则。同时，还展示了如何将TCHAR映射到Java语言中的byte和char数组。最后，它揭示了以常量方式声明的结构体的大小。Listing 7展示了当调用joyGetDevCapsA() 和 joyGetDevCapsW()时如何使用这些常量。<br />
<br />
<strong><span style="font-size: 12px"><span style="color: green">Listing 7. JoystickInfo.java</span></span></strong><br />
<br />
<pre class="overflow">// JoystickInfo.java<br />
<br />
import com.sun.jna.*;<br />
<br />
public class JoystickInfo<br />
{<br />
&nbsp;&nbsp; public static void main (String [] args)<br />
&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WinMM lib = (WinMM) Native.loadLibrary ("winmm", WinMM.class);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int numDev = lib.joyGetNumDevs ();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println ("joyGetDevCapsA() Demo");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println ("---------------------\n");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WinMM.JOYCAPSA caps1 = new WinMM.JOYCAPSA ();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt; numDev; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (lib.joyGetDevCapsA (i, caps1, WinMM.JOYCAPSA_SIZE) == 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pname = new String (caps1.szPname);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pname = pname.substring (0, pname.indexOf ('\0'));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("Device #"+i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wMid = "+caps1.wMid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wPid = "+caps1.wPid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;szPname = "+pname);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wXmin = "+caps1.wXmin);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wXmax = "+caps1.wXmax);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wYmin = "+caps1.wYmin);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wYmax = "+caps1.wYmax);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wZmin = "+caps1.wZmin);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wZmax = "+caps1.wZmax);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wNumButtons = "+caps1.wNumButtons);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wPeriodMin = "+caps1.wPeriodMin);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wPeriodMax = "+caps1.wPeriodMax);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println ("joyGetDevCapsW() Demo");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println ("---------------------\n");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WinMM.JOYCAPSW caps2 = new WinMM.JOYCAPSW ();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt; numDev; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (lib.joyGetDevCapsW (i, caps2, WinMM.JOYCAPSW_SIZE) == 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pname = new String (caps2.szPname);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pname = pname.substring (0, pname.indexOf ('\0'));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("Device #"+i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wMid = "+caps2.wMid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wPid = "+caps2.wPid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;szPname = "+pname);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wXmin = "+caps2.wXmin);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wXmax = "+caps2.wXmax);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wYmin = "+caps2.wYmin);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wYmax = "+caps2.wYmax);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wZmin = "+caps2.wZmin);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wZmax = "+caps2.wZmax);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wNumButtons = "+caps2.wNumButtons);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wPeriodMin = "+caps2.wPeriodMin);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ("&nbsp;&nbsp;wPeriodMax = "+caps2.wPeriodMax);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println ();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; }<br />
}</pre>
<br />
尽管和LocalTime这个示例类似，JoystickInfo执行WinMM lib = (WinMM) Native.loadLibrary ("winmm", WinMM.class);这句话来获取一个WinMM的实例，并且载入winmm.dll。它还执行WinMM.JOYCAPSA caps1 = new WinMM.JOYCAPSA (); 和 WinMM.JOYCAPSW caps2 = new WinMM.JOYCAPSW ();初始化必需的结构体实例。<br />
<br />
<strong><span style="font-size: 14px"><span style="color: blue">编译和运行这个程序（Compile and run the application）</span></span></strong><br />
<br />
假如jna.jar，WinMM.java和JoystickInfo.java在同一个文件夹中，调用 javac -cp jna.jar;. JoystickInfo.java 来编译这个应用的源代码。<br />
在windows平台下，调用java -cp jna.jar;. JoystickInfo就可以运行这个应用程序了。如果没有操纵杆设备，你应该得到Listing 8中的输出。<br />
<br />
<strong><span style="font-size: 12px"><span style="color: green">将C语言中的string类型转换为Java语言的String类型</span></span></strong><br />
<br />
pname = pname.substring (0, pname.indexOf ('\0')); 这段代码将一个C string 转换成了Java string. 如果不使用这个转换，C语言的string结束符&#8217;\0&#8217;和string后面的无用字符都会成为Java语言中String实例对象的内容。 <br />
<br />
<strong><span style="font-size: 12px"><span style="color: green">Listing 8. 输出操纵杆信息（Output of JoystickInfo）</span></span></strong><br />
<br />
<pre class="overflow">joyGetDevCapsA() Demo<br />
---------------------<br />
<br />
joyGetDevCapsW() Demo<br />
---------------------</pre>
<br />
<br />
上面的输出是因为每次调用joyGetDevCap()返回的是一个非空值，这表示没有操纵杆/游戏控制器设备或者是出现错误。为了获取更多有意思的输出，将一个设备连接到你的平台上并且再次运行JoystickInfo。如下，将一个微软SideWinder即插即用游戏触摸板设备联上之后我获取了如下的输出：<br />
<br />
<strong><span style="font-size: 12px"><span style="color: green">Listing 9. 操纵杆连接上之后的运行结果（Output after running JoystickInfo with a joystick attached）</span></span></strong><br />
<br />
<pre class="overflow">joyGetDevCapsA() Demo<br />
---------------------<br />
<br />
Device #0<br />
&nbsp;&nbsp;wMid = 1118<br />
&nbsp;&nbsp;wPid = 39<br />
&nbsp;&nbsp;szPname = Microsoft PC-joystick driver<br />
&nbsp;&nbsp;wXmin = 0<br />
&nbsp;&nbsp;wXmax = 65535<br />
&nbsp;&nbsp;wYmin = 0<br />
&nbsp;&nbsp;wYmax = 65535<br />
&nbsp;&nbsp;wZmin = 0<br />
&nbsp;&nbsp;wZmax = 65535<br />
&nbsp;&nbsp;wNumButtons = 6<br />
&nbsp;&nbsp;wPeriodMin = 10<br />
&nbsp;&nbsp;wPeriodMax = 1000<br />
<br />
joyGetDevCapsW() Demo<br />
---------------------<br />
<br />
Device #0<br />
&nbsp;&nbsp;wMid = 1118<br />
&nbsp;&nbsp;wPid = 39<br />
&nbsp;&nbsp;szPname = Microsoft PC-joystick driver<br />
&nbsp;&nbsp;wXmin = 0<br />
&nbsp;&nbsp;wXmax = 65535<br />
&nbsp;&nbsp;wYmin = 0<br />
&nbsp;&nbsp;wYmax = 65535<br />
&nbsp;&nbsp;wZmin = 0<br />
&nbsp;&nbsp;wZmax = 65535<br />
&nbsp;&nbsp;wNumButtons = 6<br />
&nbsp;&nbsp;wPeriodMin = 10<br />
&nbsp;&nbsp;wPeriodMax = 1000</pre>
<br />
<br />
<strong><span style="font-size: 14px"><span style="color: blue">窗口透明度（Transparent windows）</span></span></strong><br />
<br />
在这系列文章中上篇文章是关于Bernhard Pauler's 气泡提示（balloontip）工程的。我构建了一个叫做VerifyAge的、包含有一个气泡提示的GUI应用。Figure 1中显示了这个GUI应用的一个小问题：这个气泡提示的没有经过修饰的对话框部分遮住了应用窗口的一部分边框,导致了无法点击这个边框的最小化和最大化按钮，并且使整个GUI很难看.<br />
<img style="display: inline" onclick="javascript:imgClick(this);" border="0" alt="image" src="http://www.matrix.org.cn/resource/upload/forum/2008_10_29_143042_CzQuHmvIGF.jpg" onload="javascript:imgLoad(this);" resized="0" /><br />
尽管未修饰部分的对话框不能显示气泡提示的透明度，java语言不支持窗口透明度。幸运的是，我们可以通过使用com.sun.jna.examples.WindowUtils类调用JNA的examples.jar文件来解决这个问题。 <br />
WindowUtils提供在Unix，Linux，Mac OS X和Windows平台上使用JNA&#8217;s来实现窗口透明的工具方法。例如， public static void setWindowMask(final Window w, Icon mask) 让你根据像素而不是通过预定的掩罩（mask）参数来选取某部分的窗口。这个功能将在Listing 10中展示：<br />
<br />
<strong><span style="font-size: 12px"><span style="color: green">Listing 10. Using JNA to render a window transparent</span></span></strong><br />
<br />
<pre class="overflow"><br />
// Create a mask for this dialog. This mask has the same shape as the<br />
// dialog's rounded balloon tip and ensures that only the balloon tip<br />
// part of the dialog will be visible. All other dialog pixels will<br />
// disappear because they correspond to transparent mask pixels.<br />
<br />
// Note: The drawing code is based on the drawing code in<br />
// RoundedBalloonBorder.<br />
<br />
Rectangle bounds = getBounds ();<br />
BufferedImage bi = new BufferedImage (bounds.width, bounds.height,<br />
&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;BufferedImage.TYPE_INT_ARGB);<br />
Graphics g = bi.createGraphics ();<br />
g.fillRoundRect (0, 0, bounds.width, bounds.height-VERT_OFFSET,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARC_WIDTH*2, ARC_HEIGHT*2);<br />
g.drawRoundRect (0, 0, bounds.width-1, bounds.height-VERT_OFFSET-1,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARC_WIDTH*2, ARC_HEIGHT*2);<br />
int [] xPoints = { HORZ_OFFSET, HORZ_OFFSET+VERT_OFFSET, HORZ_OFFSET };<br />
int [] yPoints = { bounds.height-VERT_OFFSET-1, bounds.height-VERT_OFFSET<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -1, bounds.height-1 };<br />
g.fillPolygon (xPoints, yPoints, 3);<br />
g.drawLine (xPoints [0], yPoints [0], xPoints [2], yPoints [2]);<br />
g.drawLine (xPoints [1], yPoints [1], xPoints [2], yPoints [2]);<br />
g.dispose ();<br />
WindowUtils.setWindowMask (this, new ImageIcon (bi));<br />
</pre>
<br />
<br />
在Listing 10中的代码段是从本文代码文档（<a href="http://www.javaworld.com/javaworld/jw-02-2008/jw-02-opensourcejava-jna.html?page=5#resources" target="_new">code archive</a>）里的加强版的VerifyAge2 应用中的TipFrame的构造函数结尾部分摘录的。这个构造函数定义了围绕提示气泡的掩罩（mask）的形状，在这个形状范围里描绘不透明的像素。<br />
假如你当前文件夹中有examples.jar, jna.jar, 和 VerifyAge2.java,调用 javac -cp examples.jar;balloontip.jar VerifyAge2.java 来编译源文件.然后调用java -Dsun.java2d.noddraw=true -cp examples.jar;balloontip.jar;. VerifyAge2运行这个应用. Figure 2 展示了透明示例.<br />
<img style="display: inline" onclick="javascript:imgClick(this);" border="0" alt="image" src="http://www.matrix.org.cn/resource/upload/forum/2008_10_29_142725_MXPGpCuWAY.jpg" onload="javascript:imgLoad(this);" resized="0" /> <br />
<br />
<strong><span style="font-size: 14px"><span style="color: blue">总结（In conclusion）</span></span></strong><br />
<br />
JNA项目有很长的历史了（追溯到1999年），但是它第一次发布是在2006年11月。从此以后它慢慢的被需要将本地C代码整合到Java工程中的开发者注意到了。因为JNA能够用来解决JuRuby中常见一个问题：缺乏对POSIX调用的支持（<a href="http://www.javaworld.com/javaworld/jw-02-2008/jw-02-opensourcejava-jna.html?page=5#resources" target="_new">lack of support for POSIX calls</a>），它也在JRuby程序员中掀起些波浪。JNA也同样被作为实现用低级C代码继承Ruby的一种解决方案（<a href="http://www.javaworld.com/javaworld/jw-02-2008/jw-02-opensourcejava-jna.html?page=5#resources" target="_new">extending Ruby with low-level C code</a>）。<br />
我喜欢使用JNA来工作，相信你也会发现它比使用JNI来访问本地代码更简单、更安全。无需多言，JNA还有更多的特性在本文中没有体现出来。查阅它的资源部分：获取这个开源java项目更多的信息（<a href="http://www.javaworld.com/javaworld/jw-02-2008/jw-02-opensourcejava-jna.html?page=5#resources" target="_new">learn more about this open source Java project</a>）。用它做demo，而且在论坛（<a href="http://www.javaworld.com/javaforums/postlist.php?Cat=0&amp;Board=OPENSOURCEJAVA" target="_new">discussion forum</a> ）上共享你的经验。 下一个月我会带着另一个开源项目回来的，这个开源项目会给你每天的java开发带来益处。<br />
<br />
<strong><span style="font-size: 14px"><span style="color: blue">附录：WindowUtils.setWindowMask()的替代品</span></span></strong><br />
<br />
在刚刚写完这篇文章后，我发现java语言支持在6u10版本中支持窗口的透明和形状定制。读完Kirill Grouchnikov的博客后，我用WindowUtils.setWindowMask()的替代品修改了VerifyAge2，如下：<br />
<pre class="overflow">// Create and install a balloon tip shape to ensure that only this part<br />
// of the dialog will be visible.<br />
<br />
Rectangle bounds = getBounds ();<br />
GeneralPath gp;<br />
gp = new GeneralPath (new RoundRectangle2D.Double (bounds.x, bounds.y,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bounds.width,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bounds.height-<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; VERT_OFFSET,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARC_WIDTH*2-1,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ARC_HEIGHT*2-1));<br />
gp.moveTo (HORZ_OFFSET, bounds.height-VERT_OFFSET);<br />
gp.lineTo (HORZ_OFFSET, bounds.height);<br />
gp.lineTo (HORZ_OFFSET+VERT_OFFSET+1, bounds.height-VERT_OFFSET);<br />
AWTUtilities.setWindowShape (this, gp);</pre>
<br />
<br />
这段代码使用新类AWTUtilities（在com.sun.awt包中），而且public void setWindowShape(Window w, Shape s)函数将TipFrame和JDialog窗口设置气泡形状。<br />
<img src ="http://www.blogjava.net/lanxin1020/aggbug/269365.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2009-05-07 11:08 <a href="http://www.blogjava.net/lanxin1020/archive/2009/05/07/269365.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jnidemo(转)</title><link>http://www.blogjava.net/lanxin1020/archive/2009/05/07/269363.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Thu, 07 May 2009 03:04:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2009/05/07/269363.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/269363.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2009/05/07/269363.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/269363.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/269363.html</trackback:ping><description><![CDATA[<div class="bar">
<div class="tools">Java代码 </div>
</div>
<ol class="dp-j">
    <li><span><span>简单介绍及应用如下：&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>　　一、JAVA中所需要做的工作&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>　　在JAVA程序中，首先需要在类中声明所调用的库名称，如下：&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">static</span><span>&nbsp;{&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>System.loadLibrary(&#8220;goodluck&#8221;);&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　在这里，库的扩展名字可以不用写出来，究竟是DLL还是SO，由系统自己判断。&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　还需对将要调用的方法做本地声明，关键字为</span><span class="keyword">native</span><span>。且只需要声明，而不需要具体实现。如下：&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">native</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;set(</span><span class="keyword">int</span><span>&nbsp;i);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">native</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">int</span><span>&nbsp;get(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　然后编译该JAVA程序文件，生成CLASS，再用JAVAH命令，<span class="hilite1">JNI</span>就会生成C/C++的头文件。&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　例如程序testdll.java，内容为：&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;testdll&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="keyword">static</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>System.loadLibrary(</span><span class="string">"goodluck"</span><span>);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">native</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">int</span><span>&nbsp;get();&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">native</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;set(</span><span class="keyword">int</span><span>&nbsp;i);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>testdll&nbsp;test&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;testdll();&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>test.set(</span><span class="number">10</span><span>);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>System.out.println(test.get());&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　用javac&nbsp;testdll.java编译它，会生成testdll.</span><span class="keyword">class</span><span>。&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>　　再用javah&nbsp;testdll，则会在当前目录下生成testdll.h文件，这个文件需要被C/C++程序调用来生成所需的库文件。&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　二、C/C++中所需要做的工作&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>　　对于已生成的.h头文件，C/C++所需要做的，就是把它的各个方法具体的实现。然后编译连接成库文件即可。再把库文件拷贝到JAVA程序的路径下面，就可以用JAVA调用C/C++所实现的功能了。&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>　　接上例子。我们先看一下testdll.h文件的内容：&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="comment">/*&nbsp;DO&nbsp;NOT&nbsp;EDIT&nbsp;THIS&nbsp;FILE&nbsp;-&nbsp;it&nbsp;is&nbsp;machine&nbsp;generated&nbsp;*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#include&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="comment">/*&nbsp;Header&nbsp;for&nbsp;class&nbsp;testdll&nbsp;*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#ifndef&nbsp;_Included_testdll&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>#define&nbsp;_Included_testdll&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>#ifdef&nbsp;__cplusplus&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>extern&nbsp;</span><span class="string">"C"</span><span>&nbsp;{&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#endif&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="comment">/*&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;Class:&nbsp;testdll&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;Method:&nbsp;get&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;Signature:&nbsp;()I&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>JNIEXPORT&nbsp;jint&nbsp;JNICALL&nbsp;Java_testdll_get&nbsp;(JNIEnv&nbsp;*,&nbsp;jclass);&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="comment">/*&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;Class:&nbsp;testdll&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;Method:&nbsp;set&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;Signature:&nbsp;(I)V&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>JNIEXPORT&nbsp;</span><span class="keyword">void</span><span>&nbsp;JNICALL&nbsp;Java_testdll_set&nbsp;(JNIEnv&nbsp;*,&nbsp;jclass,&nbsp;jint);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#ifdef&nbsp;__cplusplus&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>#endif&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>#endif &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　在具体实现的时候，我们只关心两个函数原型&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>　　JNIEXPORT&nbsp;jint&nbsp;JNICALL&nbsp;Java_testdll_get&nbsp;(JNIEnv&nbsp;*,&nbsp;jclass);&nbsp;和&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>　　JNIEXPORT&nbsp;</span><span class="keyword">void</span><span>&nbsp;JNICALL&nbsp;Java_testdll_set&nbsp;(JNIEnv&nbsp;*,&nbsp;jclass,&nbsp;jint); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　这里JNIEXPORT和JNICALL都是<span class="hilite1">JNI</span>的关键字，表示此函数是要被<span class="hilite1">JNI</span>调用的。而jint是以<span class="hilite1">JNI</span>为中介使JAVA的</span><span class="keyword">int</span><span>类型与本&nbsp;地的</span><span class="keyword">int</span><span>沟通的一种类型，我们可以视而不见，就当做</span><span class="keyword">int</span><span>使用。函数的名称是JAVA_再加上java程序的</span><span class="keyword">package</span><span>路径再加函数名组成的。参数&nbsp;中，我们也只需要关心在JAVA程序中存在的参数，至于JNIEnv*和jclass我们一般没有必要去碰它。&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　好，下面我们用testdll.cpp文件具体实现这两个函数：&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>#include&nbsp;</span><span class="string">"testdll.h"</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">int</span><span>&nbsp;i&nbsp;=&nbsp;</span><span class="number">0</span><span>;&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>JNIEXPORT&nbsp;jint&nbsp;JNICALL&nbsp;Java_testdll_get&nbsp;(JNIEnv&nbsp;*,&nbsp;jclass)&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>{&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="keyword">return</span><span>&nbsp;i;&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>JNIEXPORT&nbsp;</span><span class="keyword">void</span><span>&nbsp;JNICALL&nbsp;Java_testdll_set&nbsp;(JNIEnv&nbsp;*,&nbsp;jclass,&nbsp;jint&nbsp;j)&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>i&nbsp;=&nbsp;j;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　编译连接成库文件，本例是在WINDOWS下做的，生成的是DLL文件。并且名称要与JAVA中需要调用的一致，这里就是goodluck.dll&nbsp;。把goodluck.dll拷贝到testdll.</span><span class="keyword">class</span><span>的目录下，java&nbsp;testdll运行它，就可以观察到结果了。&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>　　我的项目比较复杂，需要调用动态链接库，这样在<span class="hilite1">JNI</span>传送参数到C程序时，需要对参数进行处理转换。才可以被C程序识别。 &nbsp;&nbsp;</span></li>
    <li><span>　　大体程序如下： &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;SendSMS&nbsp;{&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">static</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>System.out.println(System.getProperty(</span><span class="string">"java.library.path"</span><span>));&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>System.loadLibrary(</span><span class="string">"sms"</span><span>);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">native</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">int</span><span>&nbsp;SmsInit();&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">native</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">int</span><span>&nbsp;SmsSend(</span><span class="keyword">byte</span><span>[]&nbsp;mobileNo,&nbsp;</span><span class="keyword">byte</span><span>[]&nbsp;smContent);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　在这里要注意的是，path里一定要包含类库的路径，否则在程序运行时会抛出异常： &nbsp;&nbsp;</span></li>
    <li><span>　　java.lang.UnsatisfiedLinkError:&nbsp;no&nbsp;sms&nbsp;in&nbsp;java.library.path &nbsp;&nbsp;</span></li>
    <li><span>　　at&nbsp;java.lang.ClassLoader.loadLibrary(ClassLoader.java:</span><span class="number">1491</span><span>) &nbsp;&nbsp;</span></span></li>
    <li><span>　　at&nbsp;java.lang.Runtime.loadLibrary0(Runtime.java:</span><span class="number">788</span><span>) &nbsp;&nbsp;</span></span></li>
    <li><span>　　at&nbsp;java.lang.System.loadLibrary(System.java:</span><span class="number">834</span><span>) &nbsp;&nbsp;</span></span></li>
    <li><span>　　at&nbsp;com.mobilesoft.sms.mobilesoftinfo.SendSMS.(SendSMS.java:</span><span class="number">14</span><span>) &nbsp;&nbsp;</span></span></li>
    <li><span>　　at&nbsp;com.mobilesoft.sms.mobilesoftinfo.test.main(test.java:</span><span class="number">18</span><span>) &nbsp;&nbsp;</span></span></li>
    <li><span>　　Exception&nbsp;in&nbsp;thread&nbsp;</span><span class="string">"main"</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　指引的路径应该到.dll文件的上一级，如果指到.dll，则会报： &nbsp;&nbsp;</span></li>
    <li><span>　　java.lang.UnsatisfiedLinkError:&nbsp;C:\sms.dll:&nbsp;Can't&nbsp;find&nbsp;dependent&nbsp;libraries &nbsp;&nbsp;</span></li>
    <li><span>　　at&nbsp;java.lang.ClassLoader$NativeLibrary.load(Native&nbsp;Method) &nbsp;&nbsp;</span></li>
    <li><span>　　at&nbsp;java.lang.ClassLoader.loadLibrary0(ClassLoader.java:</span><span class="number">1560</span><span>) &nbsp;&nbsp;</span></span></li>
    <li><span>　　at&nbsp;java.lang.ClassLoader.loadLibrary(ClassLoader.java:</span><span class="number">1485</span><span>) &nbsp;&nbsp;</span></span></li>
    <li><span>　　at&nbsp;java.lang.Runtime.loadLibrary0(Runtime.java:</span><span class="number">788</span><span>) &nbsp;&nbsp;</span></span></li>
    <li><span>　　at&nbsp;java.lang.System.loadLibrary(System.java:</span><span class="number">834</span><span>) &nbsp;&nbsp;</span></span></li>
    <li><span>　　at&nbsp;com.mobilesoft.sms.mobilesoftinfo.test.main(test.java:</span><span class="number">18</span><span>) &nbsp;&nbsp;</span></span></li>
    <li><span>　　Exception&nbsp;in&nbsp;thread&nbsp;</span><span class="string">"main"</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　通过编译，生成com_mobilesoft_sms_mobilesoftinfo_SendSMS.h头文件。（建议使用Jbuilder进行编&nbsp;译，操作比较简单！）这个头文件就是Java和C之间的纽带。要特别注意的是方法中传递的参数jbyteArray，这在接下来的过程中会重点介绍。 &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="comment">/*&nbsp;DO&nbsp;NOT&nbsp;EDIT&nbsp;THIS&nbsp;FILE&nbsp;-&nbsp;it&nbsp;is&nbsp;machine&nbsp;generated&nbsp;*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#include&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="comment">/*&nbsp;Header&nbsp;for&nbsp;class&nbsp;com_mobilesoft_sms_mobilesoftinfo_SendSMS&nbsp;*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#ifndef&nbsp;_Included_com_mobilesoft_sms_mobilesoftinfo_SendSMS&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>#define&nbsp;_Included_com_mobilesoft_sms_mobilesoftinfo_SendSMS&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>#ifdef&nbsp;__cplusplus&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>extern&nbsp;</span><span class="string">"C"</span><span>&nbsp;{&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#endif&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="comment">/*&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;Class:&nbsp;com_mobilesoft_sms_mobilesoftinfo_SendSMS&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;Method:&nbsp;SmsInit&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;Signature:&nbsp;()I&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>JNIEXPORT&nbsp;jint&nbsp;JNICALL&nbsp;Java_com_mobilesoft_sms_mobilesoftinfo_SendSMS_SmsInit&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>(JNIEnv&nbsp;*,&nbsp;jclass);&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="comment">/*&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;Class:&nbsp;com_mobilesoft_sms_mobilesoftinfo_SendSMS&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;Method:&nbsp;SmsSend&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;Signature:&nbsp;([B[B)I&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>JNIEXPORT&nbsp;jint&nbsp;JNICALL&nbsp;Java_com_mobilesoft_sms_mobilesoftinfo_SendSMS_SmsSend&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>(JNIEnv&nbsp;*,&nbsp;jclass,&nbsp;jbyteArray,&nbsp;jbyteArray);&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>#ifdef&nbsp;__cplusplus&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>#endif&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>#endif &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　对于我要调用的C程序的动态链接库，C程序也要提供一个头文件，sms.h。这个文件将要调用的方法罗列了出来。 &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="comment">/*&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;SMS&nbsp;API&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;Author:&nbsp;yippit&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;Date:&nbsp;2004.6.8&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#ifndef&nbsp;MCS_SMS_H&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>#define&nbsp;MCS_SMS_H&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>#define&nbsp;DLLEXPORT&nbsp;__declspec(dllexport)&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="comment">/*sms&nbsp;storage*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#define&nbsp;SMS_SIM&nbsp;</span><span class="number">0</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#define&nbsp;SMS_MT&nbsp;</span><span class="number">1</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="comment">/*sms&nbsp;states*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#define&nbsp;SMS_UNREAD&nbsp;</span><span class="number">0</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#define&nbsp;SMS_READ&nbsp;</span><span class="number">1</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="comment">/*sms&nbsp;type*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#define&nbsp;SMS_NOPARSE&nbsp;-</span><span class="number">1</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#define&nbsp;SMS_NORMAL&nbsp;</span><span class="number">0</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#define&nbsp;SMS_FLASH&nbsp;</span><span class="number">1</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#define&nbsp;SMS_MMSNOTI&nbsp;</span><span class="number">2</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>typedef&nbsp;struct&nbsp;tagSmsEntry&nbsp;{&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="keyword">int</span><span>&nbsp;index;&nbsp;</span><span class="comment">/*index,&nbsp;start&nbsp;from&nbsp;1*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">int</span><span>&nbsp;status;&nbsp;</span><span class="comment">/*read,&nbsp;unread*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">int</span><span>&nbsp;type;&nbsp;</span><span class="comment">/*-1-can't&nbsp;parser&nbsp;0-normal,&nbsp;1-flash,&nbsp;2-mms*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">int</span><span>&nbsp;storage;&nbsp;</span><span class="comment">/*SMS_SIM,&nbsp;SMS_MT*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">char</span><span>&nbsp;date[</span><span class="number">24</span><span>];&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">char</span><span>&nbsp;number[</span><span class="number">32</span><span>];&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">char</span><span>&nbsp;text[</span><span class="number">144</span><span>];&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;SmsEntry;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>DLLEXPORT&nbsp;</span><span class="keyword">int</span><span>&nbsp;SmsInit(</span><span class="keyword">void</span><span>);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>DLLEXPORT&nbsp;</span><span class="keyword">int</span><span>&nbsp;SmsSend(</span><span class="keyword">char</span><span>&nbsp;*phonenum,&nbsp;</span><span class="keyword">char</span><span>&nbsp;*content);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>DLLEXPORT&nbsp;</span><span class="keyword">int</span><span>&nbsp;SmsSetSCA(</span><span class="keyword">char</span><span>&nbsp;*sca);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>DLLEXPORT&nbsp;</span><span class="keyword">int</span><span>&nbsp;SmsGetSCA(</span><span class="keyword">char</span><span>&nbsp;*sca);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>DLLEXPORT&nbsp;</span><span class="keyword">int</span><span>&nbsp;SmsSetInd(</span><span class="keyword">int</span><span>&nbsp;ind);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>DLLEXPORT&nbsp;</span><span class="keyword">int</span><span>&nbsp;SmsGetInd(</span><span class="keyword">void</span><span>);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>DLLEXPORT&nbsp;</span><span class="keyword">int</span><span>&nbsp;SmsGetInfo(</span><span class="keyword">int</span><span>&nbsp;storage,&nbsp;</span><span class="keyword">int</span><span>&nbsp;*max,&nbsp;</span><span class="keyword">int</span><span>&nbsp;*used);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>DLLEXPORT&nbsp;</span><span class="keyword">int</span><span>&nbsp;SmsSaveFlash(</span><span class="keyword">int</span><span>&nbsp;flag);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>DLLEXPORT&nbsp;</span><span class="keyword">int</span><span>&nbsp;SmsRead(SmsEntry&nbsp;*entry,&nbsp;</span><span class="keyword">int</span><span>&nbsp;storage,&nbsp;</span><span class="keyword">int</span><span>&nbsp;index);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>DLLEXPORT&nbsp;</span><span class="keyword">int</span><span>&nbsp;SmsDelete(</span><span class="keyword">int</span><span>&nbsp;storage,&nbsp;</span><span class="keyword">int</span><span>&nbsp;index);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>DLLEXPORT&nbsp;</span><span class="keyword">int</span><span>&nbsp;SmsModifyStatus(</span><span class="keyword">int</span><span>&nbsp;storage,&nbsp;</span><span class="keyword">int</span><span>&nbsp;index);&nbsp;</span><span class="comment">/*unread&nbsp;-&gt;&nbsp;read*/</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#endif &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　在有了这两个头文件之后，就可以进行C程序的编写了。也就是实现对<span class="hilite1">JNI</span>调用的两个方法。在网上的资料中，由于调用的方法实现的都比较简单，（大多是打印字符串等）所以避开了<span class="hilite1">JNI</span>中最麻烦的部分，也是最关键的部分，参数的传递。&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>由于Java和C的编码是不同的，所以传递的参数是要进行再处理，否则C程序是会对参数在编译过程中提出警告，例如；warning&nbsp;C4024:&nbsp;</span><span class="string">'SmsSend'</span><span>&nbsp;:&nbsp;different&nbsp;types&nbsp;</span><span class="keyword">for</span><span>&nbsp;formal&nbsp;and&nbsp;actual&nbsp;parameter&nbsp;</span><span class="number">2</span><span>等。 &nbsp;&nbsp;</span></span></li>
    <li><span>　　Sms.c的程序如下： &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>#include&nbsp;</span><span class="string">"sms.h"</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>#include&nbsp;</span><span class="string">"com_mobilesoft_sms_mobilesoftinfo_SendSMS.h"</span><span>&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>JNIEXPORT&nbsp;jint&nbsp;JNICALL&nbsp;Java_com_mobilesoft_sms_mobilesoftinfo_SendSMS_SmsInit(JNIEnv&nbsp;*&nbsp;env,&nbsp;jclass&nbsp;jobject)&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>{&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="keyword">return</span><span>&nbsp;SmsInit();&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>JNIEXPORT&nbsp;jint&nbsp;JNICALL&nbsp;Java_com_mobilesoft_sms_mobilesoftinfo_SendSMS_SmsSend(JNIEnv&nbsp;*&nbsp;env,&nbsp;jclass&nbsp;jobject,&nbsp;jbyteArray&nbsp;mobileno,&nbsp;jbyteArray&nbsp;smscontent)&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>{&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="keyword">char</span><span>&nbsp;*&nbsp;pSmscontent&nbsp;;&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="comment">//jsize&nbsp;theArrayLengthJ&nbsp;=&nbsp;(*env)-&gt;GetArrayLength(env,mobileno);&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>jbyte&nbsp;*&nbsp;arrayBody&nbsp;=&nbsp;(*env)-&gt;GetByteArrayElements(env,mobileno,</span><span class="number">0</span><span>);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">char</span><span>&nbsp;*&nbsp;pMobileNo&nbsp;=&nbsp;(</span><span class="keyword">char</span><span>&nbsp;*)arrayBody;&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>printf(</span><span class="string">"[%s]\n&nbsp;"</span><span>,&nbsp;pMobileNo);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="comment">//jsize&nbsp;size&nbsp;=&nbsp;(*env)-&gt;GetArrayLength(env,smscontent);&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>arrayBody&nbsp;=&nbsp;(*env)-&gt;GetByteArrayElements(env,smscontent,</span><span class="number">0</span><span>);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>pSmscontent&nbsp;=&nbsp;(</span><span class="keyword">char</span><span>&nbsp;*)arrayBody;&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>printf(</span><span class="string">"&lt;%s&gt;\n"</span><span>,&nbsp;pSmscontent);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">return</span><span>&nbsp;SmsSend(pMobileNo,pSmscontent);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　对于C或C++，在程序上是会有稍微的不同，这可以由读者对其进行适当的修改。这里要注意的是GetArrayLength，GetByteArrayElements等这些<span class="hilite1">JNI</span>中已经包含的方法，这些方法是专门对转换参数类型而提供的。具体的方法有很多，在下一篇中会做专门的介绍。 &nbsp;&nbsp;</span></li>
    <li><span>　　在完成了上述的文件后，可以对sms.c进行编译，生成.dll文件（建议在release中编译，这样动态链接库的容积会比较小！） &nbsp;&nbsp;</span></li>
    <li><span>　　完成.dll文件的编译后，就可以在Java中调用C程序中的方法了。例如文件test.java &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;test&nbsp;{&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">public</span><span>&nbsp;test()&nbsp;{&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;{&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">byte</span><span>[]&nbsp;mobileno&nbsp;=&nbsp;{&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="number">0x31</span><span>,&nbsp;</span><span class="number">0x33</span><span>,&nbsp;</span><span class="number">0x36</span><span>,&nbsp;</span><span class="number">0x36</span><span>,&nbsp;</span><span class="number">0x31</span><span>,&nbsp;</span><span class="number">0x36</span><span>,&nbsp;</span><span class="number">0x33</span><span>,&nbsp;</span><span class="number">0x30</span><span>,&nbsp;</span><span class="number">0x36</span><span>,&nbsp;</span><span class="number">0x36</span><span>,&nbsp;</span><span class="number">0x37</span><span>,&nbsp;</span><span class="number">0x00</span><span>};&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>String&nbsp;smscontentemp&nbsp;=&nbsp;</span><span class="string">"早上好"</span><span>;&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">byte</span><span>[]&nbsp;temp&nbsp;=&nbsp;{</span><span class="number">0</span><span>};&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">try</span><span>&nbsp;{&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">byte</span><span>[]&nbsp;smscontentdb&nbsp;=&nbsp;smscontentemp.getBytes(</span><span class="string">"gbk"</span><span>);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">byte</span><span>[]&nbsp;smscontent&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;</span><span class="keyword">byte</span><span>[smscontentdb.length&nbsp;+&nbsp;temp.length];&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>System.arraycopy(smscontentdb,&nbsp;</span><span class="number">0</span><span>,&nbsp;smscontent,&nbsp;</span><span class="number">0</span><span>,&nbsp;smscontentdb.length);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>System.arraycopy(temp,&nbsp;</span><span class="number">0</span><span>,&nbsp;smscontent,&nbsp;smscontentdb.length,&nbsp;temp.length);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>SendSMS&nbsp;sendSMS&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;SendSMS();&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>sendSMS.SmsInit();&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="keyword">if</span><span>&nbsp;(sendSMS.SmsSend(mobileno,&nbsp;smscontent)&nbsp;&gt;=&nbsp;</span><span class="number">0</span><span>)&nbsp;{&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>System.out.println(</span><span class="string">"chenggong&nbsp;!"</span><span>);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp; &nbsp;&nbsp;</span></li>
    <li><span class="keyword">else</span><span>&nbsp;{&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>System.out.println(</span><span class="string">"shibai&nbsp;!"</span><span>);&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>}</span><span class="keyword">catch</span><span>&nbsp;(Exception&nbsp;ex)&nbsp;{}&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　在这个文件中要注意的有一点，就是在传递字节数组到C程序中时，最后的结尾一定要以</span><span class="number">0</span><span>结束。这是一个偷懒的做法，不过是个有效的做法。因为大多数情况&nbsp;下，接口是由第三方提供的。所以我们一般是不知道在C的方法里，具体是怎么处理参数的。而C又是要求数组是有长度。所以，在Java中，如果你不想写程序&nbsp;传数组的长度，那么在数组中以</span><span class="number">0</span><span>结尾就是最方便的方法了。当然，如果有更好的方法也希望大家提出。 &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span>　　到这里，一个完整的Java通过<span class="hilite1">JNI</span>调用动态链接库的程序就完成了。实际上也不是很复杂。只要多注意一下细节，是很容易得出来的。&nbsp;&nbsp;</span></li>
</ol>
<img src ="http://www.blogjava.net/lanxin1020/aggbug/269363.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2009-05-07 11:04 <a href="http://www.blogjava.net/lanxin1020/archive/2009/05/07/269363.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java.util.properties(转)</title><link>http://www.blogjava.net/lanxin1020/archive/2009/05/06/269307.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Wed, 06 May 2009 14:52:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2009/05/06/269307.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/269307.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2009/05/06/269307.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/269307.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/269307.html</trackback:ping><description><![CDATA[Properties 基本知识 <br />
如果不熟悉 <span class="hilite2">java</span>.<span class="hilite3">util</span>.Properties 类，那么现在告诉您它是用来在一个文件中存储键-值对的，其中键和值是用等号分隔的，如清单 1 所示。 <br />
<br />
<span style="color: red">清单 1.</span> 一组属性示例 <br />
foo=bar <br />
fu=baz <br />
<br />
将清单 1 装载到 Properties 对象中后，您就可以找到两个键（ foo 和 fu ）和两个值（ foo 的 bar 和 fu 的 baz ）了。这个类支持带 \u 的嵌入 Unicode 字符串，但是这里重要的是每一项内容都当作 String 。 <br />
<br />
清单 2 显示了如何装载属性文件并列出它当前的一组键和值。只需传递这个文件的 InputStream 给 load() 方法，就会将每一个键-值对添加到 Properties 实例中。然后用 list() 列出所有属性或者用 getProperty() 获取单独的属性。 <br />
<span style="color: red">清单 2.</span> 装载属性 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools"><span class="hilite2">Java</span>代码 </div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">import</span><span>&nbsp;<span class="hilite2">java</span>.<span class="hilite3">util</span>.*; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;<span class="hilite2">java</span>.io.*; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;LoadSample&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String&nbsp;args[])&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Properties&nbsp;prop&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Properties(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileInputStream&nbsp;fis&nbsp;=&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">new</span><span>&nbsp;FileInputStream(</span><span class="string">"sample.properties"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prop.load(fis); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prop.list(System.out); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"\nThe&nbsp;foo&nbsp;property:&nbsp;"</span><span>&nbsp;+ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prop.getProperty(</span><span class="string">"foo"</span><span>)); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">import <span class="hilite2">java</span>.<span class="hilite3">util</span>.*;
import <span class="hilite2">java</span>.io.*;
public class LoadSample {
public static void main(String args[]) throws Exception {
Properties prop = new Properties();
FileInputStream fis =
new FileInputStream("sample.properties");
prop.load(fis);
prop.list(System.out);
System.out.println("\nThe foo property: " +
prop.getProperty("foo"));
}
}
</pre>
<br />
运行 LoadSample 程序生成如清单 3 所示的输出。注意 list() 方法的输出中键-值对的顺序与它们在输入文件中的顺序不一样。 Properties 类在一个散列表（hashtable，事实上是一个 Hashtable 子类）中储存一组键-值对，所以不能保证顺序。 <br />
<br />
<span style="color: red">清单 3.</span> LoadSample 的输出 <br />
<br />
-- listing properties -- <br />
fu=baz <br />
foo=bar <br />
<br />
The foo property: bar <br />
<br />
XML 属性文件 <br />
这里没有什么新内容。 Properties 类总是这样工作的。不过，新的地方是从一个 XML 文件中装载一组属性。它的 DTD 如清单 4 所示。 <br />
<br />
<span style="color: red">清单 4.</span> 属性 DTD <br />
<br />
dtd 写道 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools"><span class="hilite2">Java</span>代码 </div>
</div>
<ol class="dp-j">
    <li><span><span>&lt;?xml&nbsp;version=</span><span class="string">"1.0"</span><span>&nbsp;encoding=</span><span class="string">"UTF-8"</span><span>?&gt;&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>&lt;!--&nbsp;DTD&nbsp;</span><span class="keyword">for</span><span>&nbsp;properties&nbsp;--&gt;&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>&lt;!ELEMENT&nbsp;properties&nbsp;(&nbsp;comment?,&nbsp;entry*&nbsp;)&nbsp;&gt;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&lt;!ATTLIST&nbsp;properties&nbsp;version&nbsp;CDATA&nbsp;#FIXED&nbsp;</span><span class="string">"1.0"</span><span>&gt;&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>&lt;!ELEMENT&nbsp;comment&nbsp;(#PCDATA)&nbsp;&gt;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&lt;!ELEMENT&nbsp;entry&nbsp;(#PCDATA)&nbsp;&gt;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&lt;!ATTLIST&nbsp;entry&nbsp;key&nbsp;CDATA&nbsp;#REQUIRED&gt;&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!-- DTD for properties --&gt;
&lt;!ELEMENT properties ( comment?, entry* ) &gt;
&lt;!ATTLIST properties version CDATA #FIXED "1.0"&gt;
&lt;!ELEMENT comment (#PCDATA) &gt;
&lt;!ELEMENT entry (#PCDATA) &gt;
&lt;!ATTLIST entry key CDATA #REQUIRED&gt;</pre>
<br />
<br />
<br />
如果不想细读 XML DTD，那么可以告诉您它其实就是说在外围 &lt;properties&gt; 标签中包装的是一个 &lt;comment&gt; 标签，后面是任意数量的 &lt;entry&gt; 标签。对每一个 &lt;entry&gt; 标签，有一个键属性，输入的内容就是它的值。清单 5 显示了 清单 1中的属性文件的 XML 版本是什么样子的。 <br />
<br />
<span style="color: red">清单 5.</span> XML 版本的属性文件 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools"><span class="hilite2">Java</span>代码 </div>
</div>
<ol class="dp-j">
    <li><span><span>&lt;?xml&nbsp;version=</span><span class="string">"1.0"</span><span>&nbsp;encoding=</span><span class="string">"UTF-8"</span><span>?&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&lt;!DOCTYPE&nbsp;properties&nbsp;SYSTEM&nbsp;</span><span class="string">"http://<span class="hilite2">java</span>.sun.com/dtd/properties.dtd"</span><span>&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&lt;properties&gt; &nbsp;&nbsp;</span></li>
    <li><span>&lt;comment&gt;Hi&lt;/comment&gt; &nbsp;&nbsp;</span></li>
    <li><span>&lt;entry&nbsp;key=</span><span class="string">"foo"</span><span>&gt;bar&lt;/entry&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&lt;entry&nbsp;key=</span><span class="string">"fu"</span><span>&gt;baz&lt;/entry&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&lt;/properties&gt;&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE properties SYSTEM "http://<span class="hilite2">java</span>.sun.com/dtd/properties.dtd"&gt;
&lt;properties&gt;
&lt;comment&gt;Hi&lt;/comment&gt;
&lt;entry key="foo"&gt;bar&lt;/entry&gt;
&lt;entry key="fu"&gt;baz&lt;/entry&gt;
&lt;/properties&gt;
</pre>
<br />
如果清单 6 所示，读取 XML 版本的 Properties 文件与读取老格式的文件没什么不同。 <br />
<span style="color: red">清单 6.</span> 读取 XML Properties 文件 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools"><span class="hilite2">Java</span>代码 </div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">import</span><span>&nbsp;<span class="hilite2">java</span>.<span class="hilite3">util</span>.*; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;<span class="hilite2">java</span>.io.*; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;LoadSampleXML&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String&nbsp;args[])&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Properties&nbsp;prop&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Properties(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileInputStream&nbsp;fis&nbsp;= &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">new</span><span>&nbsp;FileInputStream(</span><span class="string">"sampleprops.xml"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prop.loadFromXML(fis); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prop.list(System.out); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"\nThe&nbsp;foo&nbsp;property:&nbsp;"</span><span>&nbsp;+ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prop.getProperty(</span><span class="string">"foo"</span><span>)); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">import <span class="hilite2">java</span>.<span class="hilite3">util</span>.*;
import <span class="hilite2">java</span>.io.*;
public class LoadSampleXML {
public static void main(String args[]) throws Exception {
Properties prop = new Properties();
FileInputStream fis =
new FileInputStream("sampleprops.xml");
prop.loadFromXML(fis);
prop.list(System.out);
System.out.println("\nThe foo property: " +
prop.getProperty("foo"));
}
}</pre>
<br />
关于资源绑定的说明 <br />
虽然 <span class="hilite2">java</span>.<span class="hilite3">util</span>.Properties 类现在除了支持键-值对，还支持属性文件作为 XML 文件，不幸的是，没有内置的选项可以将 ResourceBundle 作为一个 XML 文件处理。是的， PropertyResourceBundle 不使用 Properties 对象来装载绑定，不过装载方法的使用是硬编码到类中的，而不使用较新的 loadFromXML() 方法。 <br />
<br />
运行清单 6 中的程序产生与原来的程序相同的输出，如 清单 2所示。 <br />
<br />
保存 XML 属性 <br />
新的 Properties 还有一个功能是将属性存储到 XML 格式的文件中。虽然 store() 方法仍然会创建一个类似 清单 1 所示的文件，但是现在可以用新的 storeToXML() 方法创建如 清单 5 所示的文件。只要传递一个 OutputStream 和一个用于注释的 String 就可以了。清单 7 展示了新的 storeToXML() 方法。 <br />
<br />
<span style="color: red">清单 7.</span> 将 Properties 存储为 XML 文件 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools"><span class="hilite2">Java</span>代码 </div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">import</span><span>&nbsp;<span class="hilite2">java</span>.<span class="hilite3">util</span>.*; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;<span class="hilite2">java</span>.io.*; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;StoreXML&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String&nbsp;args[])&nbsp;</span><span class="keyword">throws</span><span>&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Properties&nbsp;prop&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Properties(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prop.setProperty(</span><span class="string">"one-two"</span><span>,&nbsp;</span><span class="string">"buckle&nbsp;my&nbsp;shoe"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prop.setProperty(</span><span class="string">"three-four"</span><span>,&nbsp;</span><span class="string">"shut&nbsp;the&nbsp;door"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prop.setProperty(</span><span class="string">"five-six"</span><span>,&nbsp;</span><span class="string">"pick&nbsp;up&nbsp;sticks"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prop.setProperty(</span><span class="string">"seven-eight"</span><span>,&nbsp;</span><span class="string">"lay&nbsp;them&nbsp;straight"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prop.setProperty(</span><span class="string">"nine-ten"</span><span>,&nbsp;</span><span class="string">"a&nbsp;big,&nbsp;fat&nbsp;hen"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileOutputStream&nbsp;fos&nbsp;= &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">new</span><span>&nbsp;FileOutputStream(</span><span class="string">"rhyme.xml"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prop.storeToXML(fos,&nbsp;</span><span class="string">"Rhyme"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fos.close(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">import <span class="hilite2">java</span>.<span class="hilite3">util</span>.*;
import <span class="hilite2">java</span>.io.*;
public class StoreXML {
public static void main(String args[]) throws Exception {
Properties prop = new Properties();
prop.setProperty("one-two", "buckle my shoe");
prop.setProperty("three-four", "shut the door");
prop.setProperty("five-six", "pick up sticks");
prop.setProperty("seven-eight", "lay them straight");
prop.setProperty("nine-ten", "a big, fat hen");
FileOutputStream fos =
new FileOutputStream("rhyme.xml");
prop.storeToXML(fos, "Rhyme");
fos.close();
}
}</pre>
<br />
运行清单 7 中的程序产生的输出如清单 8 所示。 <br />
<br />
<span style="color: red">清单 8.</span> 存储的 XML 文件 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools"><span class="hilite2">Java</span>代码 </div>
</div>
<ol class="dp-j">
    <li><span><span>&lt;?xml&nbsp;version=</span><span class="string">"1.0"</span><span>&nbsp;encoding=</span><span class="string">"UTF-8"</span><span>?&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&lt;!DOCTYPE&nbsp;properties&nbsp;SYSTEM&nbsp;</span><span class="string">"http://<span class="hilite2">java</span>.sun.com/dtd/properties.dtd"</span><span>&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&lt;properties&gt; &nbsp;&nbsp;</span></li>
    <li><span>&lt;comment&gt;Rhyme&lt;/comment&gt; &nbsp;&nbsp;</span></li>
    <li><span>&lt;entry&nbsp;key=</span><span class="string">"seven-eight"</span><span>&gt;lay&nbsp;them&nbsp;straight&lt;/entry&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&lt;entry&nbsp;key=</span><span class="string">"five-six"</span><span>&gt;pick&nbsp;up&nbsp;sticks&lt;/entry&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&lt;entry&nbsp;key=</span><span class="string">"nine-ten"</span><span>&gt;a&nbsp;big,&nbsp;fat&nbsp;hen&lt;/entry&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&lt;entry&nbsp;key=</span><span class="string">"three-four"</span><span>&gt;shut&nbsp;the&nbsp;door&lt;/entry&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&lt;entry&nbsp;key=</span><span class="string">"one-two"</span><span>&gt;buckle&nbsp;my&nbsp;shoe&lt;/entry&gt; &nbsp;&nbsp;</span></span></li>
    <li><span>&lt;/properties&gt;&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE properties SYSTEM "http://<span class="hilite2">java</span>.sun.com/dtd/properties.dtd"&gt;
&lt;properties&gt;
&lt;comment&gt;Rhyme&lt;/comment&gt;
&lt;entry key="seven-eight"&gt;lay them straight&lt;/entry&gt;
&lt;entry key="five-six"&gt;pick up sticks&lt;/entry&gt;
&lt;entry key="nine-ten"&gt;a big, fat hen&lt;/entry&gt;
&lt;entry key="three-four"&gt;shut the door&lt;/entry&gt;
&lt;entry key="one-two"&gt;buckle my shoe&lt;/entry&gt;
&lt;/properties&gt;</pre>
<br />
结束语 <br />
使用 XML 文件还是使用老式的 a=b 类型的文件完全取决于您自己。老式文件从内存的角度看肯定是轻量级的。不过，由于 XML 的普遍使用，人们会期望 XML 格式流行起来，因为它已经被广泛使用了，只不过没有用到 Properties 对象。选择完全在您。分析软件包 private XMLUtils 类的源代码以获得关于所使用的 XML 解析的更多信息。 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools"><span class="hilite2">Java</span>代码 </div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">import</span><span>&nbsp;<span class="hilite2">java</span>.io.FileInputStream; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;<span class="hilite2">java</span>.io.IOException; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;<span class="hilite2">java</span>.io.InputStream; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">import</span><span>&nbsp;<span class="hilite2">java</span>.<span class="hilite3">util</span>.Properties; &nbsp;&nbsp;</span></span></li>
    <li><span class="comment">/** </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;实现properties文件的读取 </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;@author&nbsp;bbflyerwww </span>&nbsp;</span></li>
    <li><span><span class="comment">*&nbsp;@date&nbsp;2006-08-02 </span>&nbsp;</span></li>
    <li><span><span class="comment">*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;PTest&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">long</span><span>&nbsp;start&nbsp;=&nbsp;System.currentTimeMillis(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InputStream&nbsp;is&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;FileInputStream(</span><span class="string">"conf.properties"</span><span>); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Properties&nbsp;p&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Properties(); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p.load(is); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;is.close(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"SIZE&nbsp;:&nbsp;"</span><span>&nbsp;+&nbsp;p.size()); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"homepage&nbsp;:&nbsp;"</span><span>&nbsp;+&nbsp;p.getProperty(</span><span class="string">"homepage"</span><span>)); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"author&nbsp;:&nbsp;"</span><span>&nbsp;+&nbsp;p.getProperty(</span><span class="string">"author"</span><span>)); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"school&nbsp;:&nbsp;"</span><span>&nbsp;+&nbsp;p.getProperty(</span><span class="string">"school"</span><span>)); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"date&nbsp;:&nbsp;"</span><span>&nbsp;+&nbsp;p.getProperty(</span><span class="string">"date"</span><span>)); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">long</span><span>&nbsp;end&nbsp;=&nbsp;System.currentTimeMillis();&nbsp; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span class="string">"Cost&nbsp;:&nbsp;"</span><span>&nbsp;+&nbsp;(end&nbsp;-&nbsp;start)); &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(IOException&nbsp;ioe)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ioe.printStackTrace(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code">import <span class="hilite2">java</span>.io.FileInputStream;
import <span class="hilite2">java</span>.io.IOException;
import <span class="hilite2">java</span>.io.InputStream;
import <span class="hilite2">java</span>.<span class="hilite3">util</span>.Properties;
/**
* 实现properties文件的读取
* @author bbflyerwww
* @date 2006-08-02
*/
public class PTest {
public static void main(String[] args) {
try {
long start = System.currentTimeMillis();
InputStream is = new FileInputStream("conf.properties");
Properties p = new Properties();
p.load(is);
is.close();
System.out.println("SIZE : " + p.size());
System.out.println("homepage : " + p.getProperty("homepage"));
System.out.println("author : " + p.getProperty("author"));
System.out.println("school : " + p.getProperty("school"));
System.out.println("date : " + p.getProperty("date"));
long end = System.currentTimeMillis();
System.out.println("Cost : " + (end - start));
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}</pre>
<br />
conf.properties <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools"><span class="hilite2">Java</span>代码 </div>
</div>
<ol class="dp-j">
    <li><span><span>#&nbsp;Configuration&nbsp;fileauthor&nbsp;=&nbsp;bbflyerwww &nbsp;&nbsp;</span></span></li>
    <li><span>school&nbsp;=&nbsp;WuHan&nbsp;University &nbsp;&nbsp;</span></li>
    <li><span>date&nbsp;=&nbsp;</span><span class="number">2006</span><span>-</span><span class="number">08</span><span>-</span><span class="number">02</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<pre style="display: none" class="java" name="code"># Configuration fileauthor = bbflyerwww
school = WuHan University
date = 2006-08-02</pre>
<br />
<br />
Result <br />
<br />
SIZE:4 <br />
author : bbflyerwww <br />
school : WuHan University <br />
date : 2006-08-02 <br />
Cost : 0 <br />
<img src ="http://www.blogjava.net/lanxin1020/aggbug/269307.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2009-05-06 22:52 <a href="http://www.blogjava.net/lanxin1020/archive/2009/05/06/269307.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>HashMap 与 TreeMap的区别</title><link>http://www.blogjava.net/lanxin1020/archive/2009/04/18/266268.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Sat, 18 Apr 2009 01:42:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2009/04/18/266268.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/266268.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2009/04/18/266268.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/266268.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/266268.html</trackback:ping><description><![CDATA[<h3 title=""><a href="/blog/154295">HashMap 与 <span class="hilite1">TreeMap</span>的区别</a><br />
</h3>
<div class="blog_content">
<p>HashMap通过hashcode对其内容进行快速查找，而<span class="hilite1">TreeMap</span>中所有的元素都保持着某种固定的顺序，如果你需要得到一个有序的结果你就应该使用<span class="hilite1">TreeMap</span>（HashMap中元素的排列顺序是不固定的）。<img border="0" alt="" align="bottom" src="http://frontfree.net/articles/pages/0000000695/container.gif" /></p>
<p><font size="2">集合框架&#8221;提供两种常规的<span lang="EN-US">Map</span>实现：<span lang="EN-US">HashMap</span>和<span lang="EN-US"><span class="hilite1">TreeMap</span> (<span class="hilite1">TreeMap</span></span>实现<span lang="EN-US">SortedMap</span>接口<span lang="EN-US">)</span>。在<span lang="EN-US">Map </span>中插入、删除和定位元素，<span lang="EN-US">HashMap </span>是最好的选择。但如果您要按自然顺序或自定义顺序遍历键，那么<span lang="EN-US"><span class="hilite1">TreeMap</span></span>会更好。使用<span lang="EN-US">HashMap</span>要求添加的键类明确定义了<span lang="EN-US">hashCode()</span>和<span lang="EN-US">equals()</span>的实现。</font><span lang="EN-US"><font size="2">　　这个<span lang="EN-US"><span class="hilite1">TreeMap</span></span>没有调优选项，因为该树总处于平衡状态。</font></p>
<p>2、两个对象值相同(x.equals(y) == true)，但却可有不同的hash code，这句话对不对?hash code是什么意思</p>
<p>&nbsp;hashcode是给一系列hash算法用的，比如hashtable。不同的对象应该有不同的hashcode，同一个对象应该有同样的hashcode </p>
<p>更正，不是同一个对象，而是相等的对象，应该有相同的hashcode </p>
<p>hash算法是什么啊，作用？ hash算法基本就是为了将一个对象和一个整数对应起来，不同的对象对应不同的整数。 <br />
(x.equals(y) == true)那这个的话就是去比较它们所对应的整数？ <br />
不是。有一个equals()函数，和一个hashcode()函数 </p>
<p>3、String a="abc";String b=new String("abc");String c="abc";</p>
<p>System.out.println(a==b);f<br />
System.out.println(a==c);t<br />
System.out.println(b==c);f<br />
System.out.println(a.equals(b));<br />
输出结果是什么？<br />
为什么？</p>
<p>4、a=0;b=0;<br />
if((a=3)&gt;0|(b=3)&gt;0){}<br />
if((a=3)&gt;0||(b=3)&gt;0){}分别说出a,b的值</p>
</span></div>
<img src ="http://www.blogjava.net/lanxin1020/aggbug/266268.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2009-04-18 09:42 <a href="http://www.blogjava.net/lanxin1020/archive/2009/04/18/266268.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>TREEMAP的排序机制 (转)</title><link>http://www.blogjava.net/lanxin1020/archive/2009/04/18/266266.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Sat, 18 Apr 2009 01:36:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2009/04/18/266266.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/266266.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2009/04/18/266266.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/266266.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/266266.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: TREEMAP的排序机制 &nbsp;1package&nbsp;com.sf;&nbsp;2&nbsp;3import&nbsp;java.text.CollationKey;&nbsp;4import&nbsp;java.text.Collator;&nbsp;5import&nbsp;java.util.Comparator;&nbsp;6import&nbsp;...&nbsp;&nbsp;<a href='http://www.blogjava.net/lanxin1020/archive/2009/04/18/266266.html'>阅读全文</a><img src ="http://www.blogjava.net/lanxin1020/aggbug/266266.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2009-04-18 09:36 <a href="http://www.blogjava.net/lanxin1020/archive/2009/04/18/266266.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>内部类(转)</title><link>http://www.blogjava.net/lanxin1020/archive/2009/04/16/265964.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Thu, 16 Apr 2009 06:06:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2009/04/16/265964.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/265964.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2009/04/16/265964.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/265964.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/265964.html</trackback:ping><description><![CDATA[<p>内部类：定义在其他类里面的类。<br />
使用内部类的理由：<br />
1.内部类方法能够访问外部类的任何数据成员包括私有成员。<br />
2.对同一个包的其他类，内部类是不可见的。<br />
3.匿名内部类能够方便的定义回调而不用写太多方法。</p>
<p>非静态内部类没有默认的构造函数，非静态内部类的构造函数都有一个外围类对象的引用。<br />
内部类的特殊语法规则：<br />
1.相对内部类，引用其外部类隐式对象的形式：OuterClass.this<br />
2.调用内部类的构造函数：outerObject.new InnerClass(construction parameters);<br />
3.外部类外面引用内部类：OuterClass.InnerClass</p>
<p>内部类是一种编译器现象与虚拟机无关。编译器将内部类翻译为用$分隔外部类名和内部类名的常规类文件，虚拟机对此并无所知。<br />
使用javap -private OuterClass$InnerClass。javap这个工具确实挺不错的，对分析字节码和源码都有很大的帮助。<br />
可以看出详细的内部类源码清单，其中包括了编译器自动添加的部分：<br />
public class Outer<br />
{<br />
&nbsp;public class Inner<br />
&nbsp;{<br />
&nbsp;}<br />
}<br />
当内部类是非静态内部类时相应的内部类的详细源码如下：<br />
Compiled from "Outer.java"<br />
public class Outer$Inner extends java.lang.Object{<br />
&nbsp;&nbsp;&nbsp; final Outer this$0;&nbsp; //编译器自动在内部类里面添加了指向外部类对象的引用<br />
&nbsp;&nbsp;&nbsp; public Outer$Inner(Outer);&nbsp; //内部类的构造函数默认有一个外部类对象作为参数。<br />
}</p>
<p>当内部类是静态内部类时：<br />
Compiled from "Outer.java"<br />
public class Outer$Inner extends java.lang.Object{<br />
&nbsp;&nbsp;&nbsp; public Outer$Inner(); //没有了对外部类对象的引用<br />
}</p>
<p><br />
如下代码模拟了上面内部类的情形唯一不同的是这里的Inner没有访问Outer私有数据的权限：<br />
class Outer{<br />
&nbsp;&nbsp; Inner in = new Inner(this);<br />
}</p>
<p>class Inner{<br />
&nbsp;&nbsp; public Inner(Outer outer){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.outer = outer;<br />
&nbsp;&nbsp; }<br />
&nbsp;&nbsp; <br />
&nbsp;&nbsp; private Outer outer;<br />
}</p>
<p>&nbsp;</p>
<p>//那么权限是如何控制的呢？当内部类中的方法访问到外部类的私有数据时(注意如果内部类没有方法去访问外部类的私有数据不会生成该静态方法static int access$000(Outer);)<br />
public class Outer<br />
{<br />
&nbsp;private int i;<br />
&nbsp;public void methodOne()<br />
&nbsp;{<br />
&nbsp;}</p>
<p>&nbsp;class Inner<br />
&nbsp;{<br />
&nbsp;&nbsp;public void print(){<br />
&nbsp;&nbsp;&nbsp;System.out.println(Outer.this.i);<br />
&nbsp;&nbsp;}<br />
&nbsp;}<br />
}</p>
<p>相应的外部类详细源码如下：<br />
public class Outer<br />
{<br />
&nbsp;&nbsp; public Outer();</p>
<p>&nbsp;&nbsp; public void methodOne();<br />
&nbsp;&nbsp; static int access$000(Outer); //由编译器合成的用于内部类对外部类进行特殊访问权限的控制：这也是<br />
&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; //为什么内部类能够访问外部类中的私有数据的原因。<br />
&nbsp;&nbsp; private int i;<br />
}</p>
<p>内部类访问外部类的private数据的这种方式很可能导致危险，虽然access$000不是一个合法的Java方法名，但是熟悉class文件结构的黑客可以使用十六进制编辑器轻松创建一个用虚拟机指令调用那个方法的类文件。由于隐秘的访问方法需要拥有包可见性，所以攻击代码需要与被攻击类放在同一个包中。总之，如果内部类访问了外部类的私有数据域，就有可能通过附加在外部类所在包中的其他类访问私有数据。</p>
<p>局部内部类：定义在方法之中，因此局部类没有public和private修饰符。对外界是完全隐藏的。<br />
局部类不仅能够访问外部类，还能访问方法中的局部变量(或方法的参数)。不过那些局部变量要声明为final的。</p>
<p><br />
匿名内部类：用外部类+$+数字的形式表示。一个外部类中有多个匿名内部类时，其生成的class文件对应有Outer$(1、2、3)的形式表示。注意到该匿名内部类是final的。<br />
final class Outer$1<br />
{<br />
&nbsp;&nbsp; Outer$1(Outer);</p>
<p>&nbsp;&nbsp; public void method();</p>
<p>&nbsp;&nbsp; final Outer this$0;<br />
}</p>
<p>嵌套类：当内部类不需要访问外部类的数据成员时应该使用嵌套类。注意只有内部类可以声明为static的其他不行。<br />
在接口中声明的内部类自动转换为public static的，在接口中定义的成员自动都是public static的。</p>
<p>内部类构造函数的可见性与其类的可见性相同。</p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/lanxin1020/aggbug/265964.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2009-04-16 14:06 <a href="http://www.blogjava.net/lanxin1020/archive/2009/04/16/265964.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>单例模式(转)</title><link>http://www.blogjava.net/lanxin1020/archive/2009/04/06/264133.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Mon, 06 Apr 2009 10:35:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2009/04/06/264133.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/264133.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2009/04/06/264133.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/264133.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/264133.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 单例模式是最简单的设计模式之一，但是对于Java的开发者来说，它却有很多缺陷。在本月的专栏中，David Geary探讨了单例模式以及在面对多线程（multithreading)、类装载器（classloaders）和序列化(serialization)时如何处理这些缺陷。 单例模式适合于一个类只有一个实例的情况，比如窗口管理器，打印缓冲池和文件系统，它们都是原型的例子。典型的情况是，那些...&nbsp;&nbsp;<a href='http://www.blogjava.net/lanxin1020/archive/2009/04/06/264133.html'>阅读全文</a><img src ="http://www.blogjava.net/lanxin1020/aggbug/264133.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2009-04-06 18:35 <a href="http://www.blogjava.net/lanxin1020/archive/2009/04/06/264133.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计模式-抽象工厂模式</title><link>http://www.blogjava.net/lanxin1020/archive/2009/04/06/264058.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Mon, 06 Apr 2009 02:02:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2009/04/06/264058.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/264058.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2009/04/06/264058.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/264058.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/264058.html</trackback:ping><description><![CDATA[<p>工厂模式是最重要的模式，因为大多数模式都需要用到工厂模式。如果不能正确的运用工厂模式，那么可以说无法成为合格的架构师。 <br />
多数设计模式的内容讲解的都是如何设计接口。 <br />
接口如何产生呢？如果在客户代码（类库的使用者称之为客户）中直接使用具体类，那么就失去了接口的意义。因为接口的使用目的，就是要降低客户对具体类的依赖程度。如果在客户代码中直接使用接口，那么就造成了客户对具体类名称的依赖。（客户最终需要以某种方式指明所需要的具体类，如配置文件或代码，但是只需要指出一次，所以说降低对具体类的依赖程度）。要使客户代码不依赖具体类，唯一的方法，就是让客户代码不依赖具体类的部分不知道具体类的名称。知道具体类名称的部分，仅仅是配置部分。（配置文件或者配置代码）。 <br />
依赖不可能完全消除，除非二者毫无联系。但是可以将这种依赖的程度降到最低。 <br />
既然不能直接创建具体类，那么就需要通过一个创建者类来创建接口的实现类。这样就产生了工厂类。 <br />
<strong>那么现在已经知道工厂类存在的理由，抽象创建接口的过程。</strong><br />
这样，就可以使用简单工厂。 <br />
简单工厂，一般是两级结构。工厂类创建接口。 <br />
随着接口创建复杂性的增强，可能在接口创建的过程中，一个创建者类，无法承担创建所有的接口类的职责。 <br />
可能会有这样的情况，我们定义了一个接口，有6个实现类分别是123456号。但是，这六个实现类不可能用一个工厂创建出来，因为123号是 windows下的实现，而456号是linux上的实现。（假设我们使用的语言不是广大人民群众热爱的java语言），那么这个时候，我还需要客户方用相同的方式来创建这个借口，而不是在代码中到处写 <br />
</p>
<div class="code_title">代码</div>
<div style="border-bottom: rgb(204,204,204) 1px solid; border-left: rgb(204,204,204) 1px solid; padding-bottom: 4px; background-color: rgb(238,238,238); padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; border-top: rgb(204,204,204) 1px solid; border-right: rgb(204,204,204) 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="color: rgb(0,0,255)">if</span> <span style="color: rgb(0,0,0)">&nbsp;(操作系统</span> <span style="color: rgb(0,0,0)">==</span> <span style="color: rgb(0,0,0)">"</span> <span style="color: rgb(0,0,0)">windows</span> <span style="color: rgb(0,0,0)">"</span> <span style="color: rgb(0,0,0)">){&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/images/dot.gif"  alt="" />&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> <span style="color: rgb(0,0,255)">else</span> <span style="color: rgb(0,0,0)">{&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/images/dot.gif"  alt="" />&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span> </div>
<script><![cdata[ender_code();]]&gt;</script><br />
那样就太麻烦了。设计模式就是为了减少麻烦，而不是什么别的废话，比如什么太极八卦、天人合一、面向xx之类的。因为怕麻烦，<strong>所以搞出设计模式这个咚咚减少麻烦。如果你发现用了设计模式更麻烦了，那么肯定是你用错了。 </strong><br />
这个时候为了省事，我就把工厂也抽象成一个接口（因为我有两个相似的工厂，如果只有一个，我还废话什么呢），这样就成了工厂方法。 <br />
当然，既然工厂方法成了一个接口，那么当然也需要用一个工厂来创建它。这个时候，创建是三级结构，简单工厂（此时是工厂的工厂）创建工厂接口（本来是个类，现在因为进一步的抽象，成为接口了），工厂接口创建产品。 <br />
过了一段时间，随着我们的工厂业务不断发展，我们有了很多产品。 <br />
比如，我们有锤子和钉子两种产品。这两种产品都有windows品牌和linux品牌的。我们给锤子和钉子各自定义了一个创建的接口。 <br />
<div class="code_title">代码</div>
<div style="border-bottom: rgb(204,204,204) 1px solid; border-left: rgb(204,204,204) 1px solid; padding-bottom: 4px; background-color: rgb(238,238,238); padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; border-top: rgb(204,204,204) 1px solid; border-right: rgb(204,204,204) 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">interface</span><span style="color: rgb(0,0,0)">&nbsp;锤子工厂{&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;造锤子（）；&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">interface</span><span style="color: rgb(0,0,0)">&nbsp;钉子工厂{&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;造钉子();&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></div>
<script><![cdata[ender_code();]]&gt;</script><br />
可是，我们发现某些用户，用windows的锤子去敲linux的钉子，从而把程序敲出了bug。这当然是我们的错误，因为我们违反了一条金科玉律： <br />
<strong>要想使你的程序稳定运行，你假设用户是猪。</strong><br />
所以，我们把锤子和钉子的工厂合并，让一个工厂只能造出配套的锤子和钉子，这样猪就没有犯错误的机会了。 <br />
于是我们搞出一个抽象工厂： <br />
<div style="border-bottom: rgb(204,204,204) 1px solid; border-left: rgb(204,204,204) 1px solid; padding-bottom: 4px; background-color: rgb(238,238,238); padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; border-top: rgb(204,204,204) 1px solid; border-right: rgb(204,204,204) 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0,0,255)">interface</span><span style="color: rgb(0,0,0)">&nbsp;铁匠铺{<br />
造锤子（）；<br />
造钉子();<br />
}&nbsp;</span></div>
<br />
当然，这个铁匠铺是个接口，所以同样需要用一个工厂来创建它。所以，这个时候，工厂还是三级结构。 <br />
我们的工厂，业务很多，而且产品一般都是配套使用的（这样可以多骗点钱），所以，我们大多数情况下，都是使用抽象工厂和简单工厂。简单工厂用来创建工厂，抽象工厂创建产品。 <br />
<strong>工厂的作用，就是创建接口。</strong><br />
其实我们不知道什么是设计模式，我们只是怕麻烦。什么是麻烦呢？ <br />
我们觉得把同样的代码写两遍就非常麻烦。所以，我们宁可多写几句，也要解决麻烦。猪不怕麻烦，可以日复一日的重复相同的事情，可是我们不是猪。<br />
<br />
<br />
<br />
<br />
<br />
例子:<br />
<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">interface</span><span>&nbsp;Plant&nbsp;{&nbsp;}</span><span class="comment">//标志接口&nbsp;&nbsp; </span><span>&nbsp;&nbsp;</span>
<li><span class="comment">//具体产品PlantA，PlantB&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
<li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;PlantA&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Plant&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>　</span><span class="keyword">public</span><span>&nbsp;PlantA&nbsp;()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　　System.out.println(</span><span class="string">"create&nbsp;PlantA&nbsp;!"</span><span>);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>　</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;doSomething()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　　System.out.println(</span><span class="string">"&nbsp;PlantA&nbsp;do&nbsp;something&nbsp;..."</span><span>);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;PlantB&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Plant&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　</span><span class="keyword">public</span><span>&nbsp;PlantB&nbsp;()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　　System.out.println(</span><span class="string">"create&nbsp;PlantB&nbsp;!"</span><span>);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>　</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;doSomething()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　　System.out.println(</span><span class="string">"&nbsp;PlantB&nbsp;do&nbsp;something&nbsp;..."</span><span>);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span class="comment">//&nbsp;产品&nbsp;Fruit接口&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
<li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">interface</span><span>&nbsp;Fruit&nbsp;{&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span class="comment">//具体产品FruitA，FruitB&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
<li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;FruitA&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Fruit&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　</span><span class="keyword">public</span><span>&nbsp;FruitA()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　　System.out.println(</span><span class="string">"create&nbsp;FruitA&nbsp;!"</span><span>);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>　</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;doSomething()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　　System.out.println(</span><span class="string">"&nbsp;FruitA&nbsp;do&nbsp;something&nbsp;..."</span><span>);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;FruitB&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Fruit&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　</span><span class="keyword">public</span><span>&nbsp;FruitB()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　　System.out.println(</span><span class="string">"create&nbsp;FruitB&nbsp;!"</span><span>);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>　</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;doSomething()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　　System.out.println(</span><span class="string">"&nbsp;FruitB&nbsp;do&nbsp;something&nbsp;..."</span><span>);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span class="comment">//&nbsp;抽象工厂方法&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
<li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">interface</span><span>&nbsp;AbstractFactory&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　</span><span class="keyword">public</span><span>&nbsp;Plant&nbsp;createPlant();&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　</span><span class="keyword">public</span><span>&nbsp;Fruit&nbsp;createFruit();&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span class="comment">//具体工厂方法&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;</span></span></li>
<li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;FactoryA&nbsp;</span><span class="keyword">implements</span><span>&nbsp;AbstractFactory&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　</span><span class="keyword">public</span><span>&nbsp;Plant&nbsp;createPlant()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　　</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">new</span><span>&nbsp;PlantA();&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>　</span><span class="keyword">public</span><span>&nbsp;Fruit&nbsp;createFruit()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　　</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">new</span><span>&nbsp;FruitA();&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;FactoryB&nbsp;</span><span class="keyword">implements</span><span>&nbsp;AbstractFactory&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　</span><span class="keyword">public</span><span>&nbsp;Plant&nbsp;createPlant()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　　</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">new</span><span>&nbsp;PlantB();&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>　</span><span class="keyword">public</span><span>&nbsp;Fruit&nbsp;createFruit()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　　</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">new</span><span>&nbsp;FruitB();&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>　}&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
<p>&nbsp;</p>
<p><br />
<br />
<span class="keyword">public</span><span>&nbsp;Client&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </p>
<li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">public</span><span>&nbsp;method1()&nbsp;{&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AbstractFactory&nbsp;instance&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;FactoryA();&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></span></li>
<li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance.createPlant();&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
<li><span>}&nbsp;&nbsp;</span></li>
<p><br />
&nbsp;</p>
 <img src ="http://www.blogjava.net/lanxin1020/aggbug/264058.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2009-04-06 10:02 <a href="http://www.blogjava.net/lanxin1020/archive/2009/04/06/264058.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>事件监听机制(转)</title><link>http://www.blogjava.net/lanxin1020/archive/2009/04/05/263960.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Sun, 05 Apr 2009 00:39:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2009/04/05/263960.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/263960.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2009/04/05/263960.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/263960.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/263960.html</trackback:ping><description><![CDATA[<h3>一个事件监听机制（Event Listener）的例程 </h3>
<table class="blog-content">
    <tbody>
        <tr>
            <td>
            <p>事件监听机制在java编程中有很重要的应用，一般我们在处理GUI编程时，只是重写一下监听接口的perform函数即可。但事件监听在底层是如何运行的？通过下面的例子我们可以有个清楚地了解。<br />
            1． &nbsp; &nbsp; &nbsp;首先写一个事件类<br />
            public class NewEvent {<br />
            &nbsp; &nbsp; &nbsp;private int eventType=-1;<br />
            &nbsp; &nbsp; &nbsp;public &nbsp; &nbsp; &nbsp;NewEvent(int type){<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;eventType=type;<br />
            &nbsp; &nbsp; &nbsp;}<br />
            &nbsp; &nbsp; &nbsp;public int getEventType(){<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return eventType;<br />
            &nbsp; &nbsp; &nbsp;}<br />
            <br />
            }<br />
            2． &nbsp; &nbsp; &nbsp;写一个事件监听器<br />
            <br />
            public interface INewEventListener {<br />
            &nbsp; &nbsp; &nbsp; public void doProcessEvent(NewEvent event);<br />
            <br />
            }<br />
            3． &nbsp; &nbsp; &nbsp;写一个测试程序<br />
            import java.util.ArrayList;<br />
            import java.util.Iterator;<br />
            import java.util.List;<br />
            <br />
            <br />
            public class Source {<br />
            &nbsp; &nbsp; &nbsp;private List listeners = new ArrayList();<br />
            &nbsp; &nbsp; &nbsp;<br />
            &nbsp; &nbsp; &nbsp;public void addNewEventListener(INewEventListener listener){//增加一个监听器<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(!listeners.contains(listener)){<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;listeners.add(listener);<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br />
            &nbsp; &nbsp; &nbsp;}<br />
            &nbsp; &nbsp; &nbsp;<br />
            &nbsp; &nbsp; &nbsp;public void fireEvent(NewEvent event){//触发事件<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for (Iterator i=listeners.iterator(); i.hasNext();) {<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;INewEventListener listener = (INewEventListener)i.next();<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;listener.doProcessEvent(event);<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br />
            &nbsp; &nbsp; &nbsp;}<br />
            &nbsp; &nbsp; &nbsp;<br />
            &nbsp; &nbsp; &nbsp;public void GenerateEvent(int eventType){//生成一个指定类型的事件<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fireEvent(new NewEvent(eventType));<br />
            &nbsp; &nbsp; &nbsp;}<br />
            &nbsp; &nbsp; &nbsp;<br />
            &nbsp; &nbsp; &nbsp;//for test<br />
            &nbsp; &nbsp; &nbsp;public static void main (String [] args){<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Source source = new Source ();<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;source.addNewEventListener(new INewEventListener(){//增加一个监听器，并实现这个监听器接口的方法<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void doProcessEvent(NewEvent event){<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int eventType = event.getEventType();<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("EventType "+eventType+ " was triggered");<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;});<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;source.GenerateEvent(3);//生成一个eventType为3的事件<br />
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
            &nbsp; &nbsp; &nbsp;}<br />
            &nbsp; &nbsp; &nbsp;<br />
            }<br />
            </p>
            </td>
        </tr>
    </tbody>
</table>
 <img src ="http://www.blogjava.net/lanxin1020/aggbug/263960.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2009-04-05 08:39 <a href="http://www.blogjava.net/lanxin1020/archive/2009/04/05/263960.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>getOutputStream() has already been called for this response(转)</title><link>http://www.blogjava.net/lanxin1020/archive/2009/03/26/262007.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Thu, 26 Mar 2009 01:15:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2009/03/26/262007.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/262007.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2009/03/26/262007.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/262007.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/262007.html</trackback:ping><description><![CDATA[<div class="blog_content">
<p>tomcat5下jsp出现<span class="undefined">getOutputStream</span>() <span class="hilite2">has</span> <span class="hilite3">already</span> <span class="hilite4">been</span> <span class="hilite5">called</span> <span class="hilite6">for</span> <span class="hilite7">this</span> <span class="hilite8">response</span>异常的原因和解决方法</p>
<p>在tomcat5下jsp中出现此错误一般都是在jsp中使用了输出流（如输出图片验证码，文件下载等），<br />
没有妥善处理好的原因。<br />
具体的原因就是<br />
在tomcat中jsp编译成servlet之后在函数_jspService(HttpServletRequest request, HttpServletResponse <span class="hilite8">response</span>)的最后<br />
有一段这样的代码<br />
finally {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);<br />
&nbsp;&nbsp;&nbsp; }<br />
这里是在释放在jsp中使用的对象，会调用<span class="hilite8">response</span>.getWriter(),因为这个方法是和<br />
<span class="hilite8">response</span>.<span class="undefined">getOutputStream</span>()相冲突的！所以会出现以上这个异常。</p>
<p>然后当然是要提出解决的办法，其实挺简单的（并不是和某些朋友说的那样--<br />
将jsp内的所有空格和回车符号所有都删除掉），</p>
<p>在使用完输出流以后调用以下两行代码即可：<br />
out.clear();<br />
out = pageContext.pushBody();</p>
<p>最后这里是一个输出彩色验证码例子（这样的例子几乎随处可见）<br />
imag.jsp</p>
<p>&lt;%@ page&nbsp; import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %&gt;<br />
&lt;%@ page import="java.io.OutputStream" %&gt;<br />
&lt;%!<br />
Color getRandColor(int fc,int bc){<br />
Random random = new Random();<br />
if(fc&gt;255) fc=255;<br />
if(bc&gt;255) bc=255;<br />
int r=fc+random.nextInt(bc-fc);<br />
int g=fc+random.nextInt(bc-fc);<br />
int b=fc+random.nextInt(bc-fc);<br />
return new Color(r,g,b);<br />
}<br />
%&gt;<br />
&lt;%<br />
try{<br />
<span class="hilite8">response</span>.setHeader("Pragma","No-cache");<br />
<span class="hilite8">response</span>.setHeader("Cache-Control","no-cache");<br />
<span class="hilite8">response</span>.setDateHeader("Expires", 0);<br />
int width=60, height=20;<br />
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);<br />
OutputStream os=<span class="hilite8">response</span>.<span class="undefined">getOutputStream</span>();<br />
Graphics g = image.getGraphics();<br />
Random random = new Random();<br />
g.setColor(getRandColor(200,250));<br />
g.fillRect(0, 0, width, height);</p>
<p>g.setFont(new Font("Times New Roman",Font.PLAIN,18));<br />
g.setColor(getRandColor(160,200));<br />
<span class="hilite6">for</span> (int i=0;i&lt;155;i++)<br />
{<br />
int x = random.nextInt(width);<br />
int y = random.nextInt(height);<br />
int xl = random.nextInt(12);<br />
int yl = random.nextInt(12);<br />
g.drawLine(x,y,x+xl,y+yl);<br />
}<br />
String sRand="";<br />
<span class="hilite6">for</span> (int i=0;i&lt;4;i++){<br />
String rand=String.valueOf(random.nextInt(10));<br />
sRand+=rand;<br />
g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));<br />
g.drawString(rand,13*i+6,16);<br />
}<br />
session.setAttribute("rand",sRand);<br />
g.dispose();</p>
<p>ImageIO.write(image, "JPEG",os);<br />
os.flush();<br />
os.close();<br />
os=null;<br />
<span class="hilite8">response</span>.flushBuffer();<br />
out.clear();<br />
out = pageContext.pushBody();<br />
}<br />
catch(IllegalStateException e)<br />
{<br />
System.out.println(e.getMessage());<br />
e.printStackTrace();<br />
}%&gt;</p>
</div>
 <img src ="http://www.blogjava.net/lanxin1020/aggbug/262007.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2009-03-26 09:15 <a href="http://www.blogjava.net/lanxin1020/archive/2009/03/26/262007.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解决在命令行下编译和执行带包java文件的问题(修改)</title><link>http://www.blogjava.net/lanxin1020/archive/2009/01/31/252779.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Sat, 31 Jan 2009 02:59:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2009/01/31/252779.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/252779.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2009/01/31/252779.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/252779.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/252779.html</trackback:ping><description><![CDATA[<p>1&nbsp; 如果用到j2ee包则现将servlet-api包拷贝到javaHome/jre\lib\ext下<br />
2&nbsp; 在命令行方式下定位到要编译的文件所在的目录<br />
3&nbsp; javac -d . 文件名</p>
 <img src ="http://www.blogjava.net/lanxin1020/aggbug/252779.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2009-01-31 10:59 <a href="http://www.blogjava.net/lanxin1020/archive/2009/01/31/252779.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA通过接口来实现CALLBACK </title><link>http://www.blogjava.net/lanxin1020/archive/2009/01/20/251989.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Tue, 20 Jan 2009 00:51:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2009/01/20/251989.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/251989.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2009/01/20/251989.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/251989.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/251989.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<p>所谓回调，就是客户程序C调用服务程序S中的某个函数A，然后S又在某个时候反过来调用C中的某个函数B，对于C来说，这个B便叫做回调函数。</p>
<p>例：&nbsp;&nbsp; <br />
&nbsp; 1.class&nbsp;&nbsp; A,class&nbsp;&nbsp; B&nbsp;&nbsp; <br />
&nbsp; 2.class&nbsp;&nbsp; A实现接口operate&nbsp;&nbsp; <br />
&nbsp; 3.class&nbsp;&nbsp; B拥有一个参数为operate接口类型的函数test(operate&nbsp;&nbsp; o)&nbsp;&nbsp; <br />
&nbsp; 4.class&nbsp;&nbsp; A运行时调用class&nbsp;&nbsp; B中test函数,以自身传入参数&nbsp;&nbsp; <br />
&nbsp; 5.class&nbsp;&nbsp; B已取得A，就可以随时回调A所实现的operate接口中的方法 </p>
举个例子来说:<br />
<br />
<p>public interface InterestingEvent<br />
{</p>
<p>&nbsp;&nbsp;&nbsp; // This is just a regular method so it can return something or</p>
<p>&nbsp;&nbsp;&nbsp; // take arguments if you like.</p>
<p>&nbsp;&nbsp;&nbsp; public void interestingEvent ();</p>
<p>}</p>
<br />
<br />
<br />
<br />
<br />
<p>public class EventNotifier<br />
{</p>
<p>&nbsp;&nbsp;&nbsp; private InterestingEvent ie;</p>
<p>&nbsp;&nbsp;&nbsp; private boolean somethingHappened; </p>
<p>&nbsp;&nbsp;&nbsp; public EventNotifier (InterestingEvent event)<br />
&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Save the event object for later use.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ie = event; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Nothing to report yet.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; somethingHappened = false;</p>
<p>&nbsp;&nbsp;&nbsp; } </p>
<p>&nbsp;&nbsp;&nbsp; //&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp; public void doWork ()<br />
&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Check the predicate, which is set elsewhere.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (somethingHappened)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Signal the even by invoking the interface's method.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ie.interestingEvent ();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<br />
&nbsp;&nbsp;&nbsp; } </p>
<p>&nbsp;&nbsp;&nbsp; // </p>
<p>}</p>
<br />
<br />
<p>public class CallMe implements InterestingEvent<br />
{</p>
<p>&nbsp;&nbsp;&nbsp; private EventNotifier en; </p>
<p>&nbsp;&nbsp;&nbsp; public CallMe ()<br />
&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Create the event notifier and pass ourself to it.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; en = new EventNotifier (this);</p>
<p>&nbsp;&nbsp;&nbsp; } </p>
<p>&nbsp;&nbsp;&nbsp; // Define the actual handler for the event.</p>
<p>&nbsp;&nbsp;&nbsp; public void interestingEvent ()<br />
&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Wow!&nbsp; Something really interesting must have occurred!</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Do something</p>
<p>&nbsp;&nbsp;&nbsp; } </p>
<p>&nbsp;&nbsp;&nbsp; //</p>
<p>}</p>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
 <img src ="http://www.blogjava.net/lanxin1020/aggbug/251989.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2009-01-20 08:51 <a href="http://www.blogjava.net/lanxin1020/archive/2009/01/20/251989.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>图像显示笔记</title><link>http://www.blogjava.net/lanxin1020/archive/2008/08/10/221172.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Sun, 10 Aug 2008 13:37:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2008/08/10/221172.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/221172.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2008/08/10/221172.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/221172.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/221172.html</trackback:ping><description><![CDATA[<p>图像显示</p>
<p>1 使用Graphics.drawImage(Image img, int x, int y, ImageObserver observer)<br />
方法显示图像。</p>
<p><br />
2 使用Component.getToolkit.getImage(String path)语句获得Image实例对象。</p>
<p>例：<br />
package drawimage;</p>
<p>import java.awt.Frame;<br />
import java.awt.Graphics;<br />
import java.awt.Image;<br />
import java.awt.event.WindowAdapter;<br />
import java.awt.event.WindowEvent;</p>
<p>public class DrawImage extends Frame <br />
{<br />
&nbsp;&nbsp;&nbsp; private static final long serialVersionUID = 1L;<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; public DrawImage()<br />
&nbsp;{<br />
&nbsp;&nbsp; this.addWindowListener(new WindowAdapter() <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void windowClosing(WindowEvent e) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dispose();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.exit(0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });<br />
&nbsp;}<br />
&nbsp;public static void main(String[] args) <br />
&nbsp;{<br />
&nbsp;&nbsp;System.out.println("Starting DrawImage.");<br />
&nbsp;&nbsp;DrawImage mainFrame = new DrawImage();<br />
&nbsp;&nbsp;Image img = mainFrame.getToolkit().getImage("love.jpg");<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;mainFrame.setSize(400,400);<br />
&nbsp;&nbsp;mainFrame.setTitle("DrawImage");<br />
&nbsp;&nbsp;mainFrame.setVisible(true);<br />
&nbsp;&nbsp;Graphics g = mainFrame.getGraphics();<br />
&nbsp;&nbsp;while(!g.drawImage(img,150,150,mainFrame));<br />
&nbsp;&nbsp;<br />
&nbsp;</p>
<p>&nbsp;}</p>
<p>}</p>
<p>&nbsp;</p>
<p>图像重画</p>
<p><br />
package drawimage;</p>
<p>import java.awt.Frame;<br />
import java.awt.Graphics;<br />
import java.awt.Image;<br />
import java.awt.event.WindowAdapter;<br />
import java.awt.event.WindowEvent;</p>
<p>public class DrawImage extends Frame <br />
{<br />
&nbsp;Image img = getToolkit().getImage("love.jpg");<br />
&nbsp;&nbsp;&nbsp; private static final long serialVersionUID = 1L;<br />
&nbsp;public void paint(Graphics g)<br />
&nbsp;{<br />
&nbsp;&nbsp;g.drawImage(img,0,0,this);<br />
&nbsp;}<br />
&nbsp;&nbsp;&nbsp; public DrawImage()<br />
&nbsp;{<br />
&nbsp;&nbsp; this.addWindowListener(new WindowAdapter() <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void windowClosing(WindowEvent e) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dispose();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.exit(0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });<br />
&nbsp;}<br />
&nbsp;public static void main(String[] args) <br />
&nbsp;{<br />
&nbsp;&nbsp;System.out.println("Starting DrawImage.");<br />
&nbsp;&nbsp;DrawImage mainFrame = new DrawImage();<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;mainFrame.setSize(400,400);<br />
&nbsp;&nbsp;mainFrame.setTitle("DrawImage");<br />
&nbsp;&nbsp;mainFrame.setVisible(true);<br />
&nbsp;&nbsp;/*Graphics g = mainFrame.getGraphics();<br />
&nbsp;&nbsp;while(!g.drawImage(img,150,150,mainFrame));<br />
&nbsp;&nbsp;*/<br />
&nbsp;</p>
<p>&nbsp;}</p>
<p>}</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><br />
双缓冲技术：</p>
<p>1&nbsp; Component.createImage方法创建内存Image对象<br />
2&nbsp; 在Image对象上进行绘制的结果就成了一幅图像<br />
3&nbsp; 在Image对象上执行与组件表面同样的绘制，Image<br />
&nbsp;&nbsp;&nbsp;&nbsp; 对象中的图像就是组件表面内容的复制，当组件重画&nbsp;&nbsp;&nbsp; 时，只需要将内存中的Image对象在组件上画出；</p>
<p>package drawline;</p>
<p>import java.awt.Color;<br />
import java.awt.Dimension;<br />
import java.awt.Font;<br />
import java.awt.Frame;<br />
import java.awt.Graphics;<br />
import java.awt.Image;<br />
import java.awt.event.MouseAdapter;<br />
import java.awt.event.MouseEvent;<br />
import java.awt.event.WindowAdapter;<br />
import java.awt.event.WindowEvent;<br />
//import java.util.Enumeration;<br />
import java.util.Vector;</p>
<p><br />
public class DrawLine1 extends Frame <br />
{<br />
&nbsp;int orgX;<br />
&nbsp;int orgY;<br />
&nbsp;int endX;<br />
&nbsp;int endY;<br />
&nbsp;Image oimg = null;<br />
&nbsp;Graphics og = null;<br />
&nbsp;Vector&lt;MyLine&gt; vLines = new Vector&lt;MyLine&gt;();<br />
&nbsp;<br />
&nbsp;public void paint(Graphics g)<br />
&nbsp;{<br />
&nbsp;&nbsp;if(oimg != null)<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp; g.drawImage(oimg,0,0,this);<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;/*g.setColor(Color.RED);<br />
&nbsp;&nbsp;g.setFont(new Font(null,Font.ITALIC|Font.BOLD,30));<br />
&nbsp;&nbsp;Enumeration&lt;MyLine&gt; e = vLines.elements();<br />
&nbsp;&nbsp;while(e.hasMoreElements())<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;MyLine line = (MyLine)e.nextElement();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line.drawMe(g);<br />
&nbsp;&nbsp;}*/<br />
&nbsp;&nbsp;//g.drawLine(orgX, orgY, endX, endY);<br />
&nbsp;}<br />
&nbsp;private static final long serialVersionUID = 9004940250333651314L;</p>
<p>&nbsp;public DrawLine1() <br />
&nbsp;{<br />
&nbsp;&nbsp;setSize(400,400);<br />
&nbsp;&nbsp;setTitle("Drawline");<br />
&nbsp;&nbsp;setVisible(true);<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;Dimension d = getSize();<br />
&nbsp;&nbsp;oimg = createImage(d.width,d.height);<br />
&nbsp;&nbsp;og = oimg.getGraphics();<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; addWindowListener(new WindowAdapter() <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void windowClosing(WindowEvent e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dispose();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.exit(0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;this.addMouseListener(new MouseAdapter()<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void mousePressed(MouseEvent e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;orgX = e.getX();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;orgY = e.getY();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void mouseReleased(MouseEvent e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;endX = e.getX();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;endY = e.getY();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Graphics g = getGraphics();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.setColor(Color.RED);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.setFont(new Font(null,Font.ITALIC|Font.BOLD,30));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawString(orgX + "," + orgY,orgX,orgY);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawString(e.getX() + "," + e.getY(), e.getX(),e.getY());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawLine(orgX, orgY, e.getX(),e.getY());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;og.setColor(Color.RED);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;og.setFont(new Font(null,Font.ITALIC|Font.BOLD,30));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;og.drawString(orgX + "," + orgY,orgX,orgY);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;og.drawString(e.getX() + "," + e.getY(), e.getX(),e.getY());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;og.drawLine(orgX, orgY, e.getX(),e.getY());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*vLines.add(new MyLine(orgX,orgY,endX,endY));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;repaint();*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}//为什么用getGraphics().setColor(Color.RED)是不用导java.awt.Graphics包<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//Enumeration&lt;MyLine&gt;???????????????????????????<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />
&nbsp;}</p>
<p>&nbsp;public static void main( String[] args) {<br />
&nbsp;&nbsp;System.out.println("String DrawLine");<br />
&nbsp;&nbsp; new DrawLine1();<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;<br />
&nbsp;}<br />
}</p>
<p>//构建主框架对象时是先调用paint（）还是构造函数</p>
<p>&nbsp;</p>
 <img src ="http://www.blogjava.net/lanxin1020/aggbug/221172.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2008-08-10 21:37 <a href="http://www.blogjava.net/lanxin1020/archive/2008/08/10/221172.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Graphics类与图形绘制笔记</title><link>http://www.blogjava.net/lanxin1020/archive/2008/08/10/221093.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Sat, 09 Aug 2008 23:51:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2008/08/10/221093.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/221093.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2008/08/10/221093.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/221093.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/221093.html</trackback:ping><description><![CDATA[<p>&nbsp;Graphics类与图形绘制<br />
Componentp.getGraphics方法与Grahpics类</p>
<p>Graphics.drawLine(int x1,int y1,int x2, int y2)方法；<br />
Graphics.drawStringString str，int x，int y）方法；<br />
Graphics.drawSting方法的坐标参数是以坐下方为参考点的；</p>
<p><br />
例：</p>
<p>package drawline;</p>
<p>import java.awt.Color;<br />
import java.awt.Font;<br />
import java.awt.Frame;<br />
import java.awt.Graphics;<br />
import java.awt.event.MouseAdapter;<br />
import java.awt.event.MouseEvent;<br />
import java.awt.event.WindowAdapter;<br />
import java.awt.event.WindowEvent;</p>
<p><br />
public class DrawLine extends Frame {</p>
<p>&nbsp;private static final long serialVersionUID = 9004940250333651314L;</p>
<p>&nbsp;public DrawLine() <br />
&nbsp;{<br />
&nbsp;&nbsp;this.addWindowListener(new WindowAdapter() <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void windowClosing(WindowEvent e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dispose();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.exit(0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;this.addMouseListener(new MouseAdapter()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int orgX;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int orgY;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void mousePressed(MouseEvent e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;orgX = e.getX();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;orgY = e.getY();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void mouseReleased(MouseEvent e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Graphics g = getGraphics();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.setColor(Color.RED);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.setFont(new Font(null,Font.ITALIC|Font.BOLD,30));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawString(orgX + "," + orgY,orgX,orgY);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawString(e.getX() + "," + e.getY(), e.getX(),e.getY());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawLine(orgX, orgY, e.getX(),e.getY());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}//为什么用getGraphics().setColor(Color.RED)是不用导java.awt.Graphics包<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />
&nbsp;}</p>
<p>&nbsp;public static void main( String[] args) {<br />
&nbsp;&nbsp;System.out.println("String DrawLine");<br />
&nbsp;&nbsp;DrawLine mainFrame = new DrawLine();<br />
&nbsp;&nbsp;mainFrame.setSize(400,400);<br />
&nbsp;&nbsp;mainFrame.setTitle("Drawline");<br />
&nbsp;&nbsp;mainFrame.setVisible(true);<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;<br />
&nbsp;}<br />
}</p>
<p>组件重建的处理：</p>
<p>1 组件重绘的原理&nbsp; 曝光<br />
2 paint(Graphics g)的作用</p>
<p>AWT组件重绘路线：<br />
AWT Thread -&gt;paint() -&gt;AWT Thread<br />
repaint()+AWT Thread -&gt;update(清除组件表面内容调用paint()方法）-&gt;paint();</p>
<p>例：<br />
package drawline;</p>
<p>import java.awt.Color;<br />
import java.awt.Font;<br />
import java.awt.Frame;<br />
import java.awt.Graphics;<br />
import java.awt.event.MouseAdapter;<br />
import java.awt.event.MouseEvent;<br />
import java.awt.event.WindowAdapter;<br />
import java.awt.event.WindowEvent;<br />
import java.util.Enumeration;<br />
import java.util.Vector;</p>
<p><br />
public class DrawLine extends Frame <br />
{<br />
&nbsp;int orgX;<br />
&nbsp;int orgY;<br />
&nbsp;int endX;<br />
&nbsp;int endY;<br />
&nbsp;Vector&lt;MyLine&gt; vLines = new Vector&lt;MyLine&gt;();<br />
&nbsp;<br />
&nbsp;public void paint(Graphics g)<br />
&nbsp;{<br />
&nbsp;&nbsp;g.setColor(Color.RED);<br />
&nbsp;&nbsp;g.setFont(new Font(null,Font.ITALIC|Font.BOLD,30));<br />
&nbsp;&nbsp;Enumeration&lt;MyLine&gt; e = vLines.elements();<br />
&nbsp;&nbsp;while(e.hasMoreElements())<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;MyLine line = (MyLine)e.nextElement();<br />
&nbsp;&nbsp;line.drawMe(g);<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;//g.drawLine(orgX, orgY, endX, endY);<br />
&nbsp;}<br />
&nbsp;private static final long serialVersionUID = 9004940250333651314L;</p>
<p>&nbsp;public DrawLine() <br />
&nbsp;{<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;this.addWindowListener(new WindowAdapter() <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void windowClosing(WindowEvent e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dispose();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.exit(0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;this.addMouseListener(new MouseAdapter()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void mousePressed(MouseEvent e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;orgX = e.getX();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;orgY = e.getY();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void mouseReleased(MouseEvent e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;endX = e.getX();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;endY = e.getY();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*Graphics g = getGraphics();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.setColor(Color.RED);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.setFont(new Font(null,Font.ITALIC|Font.BOLD,30));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawString(orgX + "," + orgY,orgX,orgY);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawString(e.getX() + "," + e.getY(), e.getX(),e.getY());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g.drawLine(orgX, orgY, e.getX(),e.getY());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vLines.add(new MyLine(orgX,orgY,endX,endY));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;repaint();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}//为什么用getGraphics().setColor(Color.RED)是不用导java.awt.Graphics包<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//Enumeration&lt;MyLine&gt;???????????????????????????<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />
&nbsp;}</p>
<p>&nbsp;public static void main( String[] args) {<br />
&nbsp;&nbsp;System.out.println("String DrawLine");<br />
&nbsp;&nbsp;DrawLine mainFrame = new DrawLine();<br />
&nbsp;&nbsp;mainFrame.setSize(400,400);<br />
&nbsp;&nbsp;mainFrame.setTitle("Drawline");<br />
&nbsp;&nbsp;mainFrame.setVisible(true);<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp;<br />
&nbsp;}<br />
}</p>
<p><br />
package drawline;</p>
<p>import java.awt.Graphics;</p>
<p><br />
public class MyLine <br />
{<br />
&nbsp;private int orgX;<br />
&nbsp;private int orgY;<br />
&nbsp;private int endX;<br />
&nbsp;private int endY;<br />
&nbsp;public MyLine(int orgX, int orgY, int endX, int endY)<br />
&nbsp;{<br />
&nbsp;&nbsp;this.orgX = orgX;<br />
&nbsp;&nbsp;this.orgY = orgY;<br />
&nbsp;&nbsp;this.endX = endX;<br />
&nbsp;&nbsp;this.endY = endY;<br />
&nbsp;}<br />
&nbsp;<br />
&nbsp;<br />
&nbsp;public void drawMe(Graphics g)<br />
&nbsp;{<br />
&nbsp;&nbsp;System.out.println(orgX + "," + orgY + " "+endX + "," + endY);<br />
&nbsp;&nbsp;g.drawString(orgX + "," + orgY,orgX,orgY);<br />
&nbsp;&nbsp;g.drawString(endX + "," + endY,endX,endY);<br />
&nbsp;&nbsp;g.drawLine(orgX, orgY, endX, endY);<br />
&nbsp;}<br />
&nbsp;<br />
&nbsp;</p>
<p>}<br />
</p>
   <img src ="http://www.blogjava.net/lanxin1020/aggbug/221093.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2008-08-10 07:51 <a href="http://www.blogjava.net/lanxin1020/archive/2008/08/10/221093.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>初学警示</title><link>http://www.blogjava.net/lanxin1020/archive/2008/08/07/220694.html</link><dc:creator>lanxin1020</dc:creator><author>lanxin1020</author><pubDate>Thu, 07 Aug 2008 07:53:00 GMT</pubDate><guid>http://www.blogjava.net/lanxin1020/archive/2008/08/07/220694.html</guid><wfw:comment>http://www.blogjava.net/lanxin1020/comments/220694.html</wfw:comment><comments>http://www.blogjava.net/lanxin1020/archive/2008/08/07/220694.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lanxin1020/comments/commentRss/220694.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lanxin1020/services/trackbacks/220694.html</trackback:ping><description><![CDATA[初学警示：<br />
<br />
<br />
面向对象编程思想：<br />
编程人员脑海里面想的问题应该是：程序运行时的各个时刻的各个对象的内存布局和变化状态，以及每行代码执行后对这些对象产生的影响。而非顶住程序中静止不变的代码，孤立的琢磨每条语句的语法是否正确。
 <img src ="http://www.blogjava.net/lanxin1020/aggbug/220694.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lanxin1020/" target="_blank">lanxin1020</a> 2008-08-07 15:53 <a href="http://www.blogjava.net/lanxin1020/archive/2008/08/07/220694.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>