??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲av无码乱码国产精品,国产亚洲美女精品久久久久狼 ,亚洲中文字幕无码久久http://m.tkk7.com/ashutc/category/42979.html沈阳求职Qjava3q以上经验)Qashutc@126.comzh-cnWed, 20 Apr 2011 11:15:22 GMTWed, 20 Apr 2011 11:15:22 GMT60再谈 Qtry中的return语句Q在finally前执行还是在finally后执行(|上也大多是之前执行是错误的Q附试数据Q?/title><link>http://m.tkk7.com/ashutc/archive/2011/04/19/348559.html</link><dc:creator>西瓜</dc:creator><author>西瓜</author><pubDate>Tue, 19 Apr 2011 03:30:00 GMT</pubDate><guid>http://m.tkk7.com/ashutc/archive/2011/04/19/348559.html</guid><wfw:comment>http://m.tkk7.com/ashutc/comments/348559.html</wfw:comment><comments>http://m.tkk7.com/ashutc/archive/2011/04/19/348559.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/ashutc/comments/commentRss/348559.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/ashutc/services/trackbacks/348559.html</trackback:ping><description><![CDATA[首先说明下:|上大多说法Qfinally块会执行Qƈ都会在return之前执行Q都是错误的? <div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">package</span><span style="color: #000000; "> cn.yu.test001;<br /> </span><span style="color: #008000; ">/**</span><span style="color: #008000; "><br />  * <br />  * Created by myeclipse8.5.<br />  * User: </span><span style="color: #808080; ">@author</span><span style="color: #008000; "> yu<br />  * Time: 2011-4-19 <br />  * Company: 天极传媒集团<br />  * Descripion: 试<br />  </span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br /> </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> testReturn {<br /> <br />     </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">static</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> test() {<br />         </span><span style="color: #0000FF; ">try</span><span style="color: #000000; "> {<br />             </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> fun1();<br />         } </span><span style="color: #0000FF; ">catch</span><span style="color: #000000; "> (Exception e) {<br />         } </span><span style="color: #0000FF; ">finally</span><span style="color: #000000; "> {<br />             </span><span style="color: #0000FF; ">return</span><span style="color: #000000;"> fun2();<br />         }<br />     }<br /> <br />     </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">static</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> fun1() {<br />         System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">fun1被执行了</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />         System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">fun1的确被执行了,q回么?</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />         </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> </span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />     }<br /> <br />     </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">static</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> fun2() {<br />         System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">fun2被执行了</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />         System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">fun2的确被执行了,q回么?</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />         </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> </span><span style="color: #000000; ">2</span><span style="color: #000000; ">;<br />     }<br /> <br />     </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">static</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> main(String[] args) {<br />         System.out.println(testReturn.test());<br />     }<br /> }</span></div> <br /> <br /> <br /> <br /> <br /> l果Qfun1被执行了<br />       fun1的确被执行了,q回么?<br />       fun2被执行了<br />       fun2的确被执行了,q回么?<br />       2<br /> <br /> 证明什么?finallyq没有在之前执行Q第一个执行的q是try里面的内容但是没有立刻返?{待执行finallyQ当finallyq回l果后执行完毕?br /> q不是网上大多数的说?br /> <br /> q有要说明下 如果finally里面没有q回|则返回try里面的返回倹{?br /> <br /> <br /> <img src ="http://m.tkk7.com/ashutc/aggbug/348559.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/ashutc/" target="_blank">西瓜</a> 2011-04-19 11:30 <a href="http://m.tkk7.com/ashutc/archive/2011/04/19/348559.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>分析农夫ȝ问题Q网上好多错的,其是csdn上各U说法都有)http://m.tkk7.com/ashutc/archive/2011/04/18/348503.html西瓜西瓜Mon, 18 Apr 2011 08:21:00 GMThttp://m.tkk7.com/ashutc/archive/2011/04/18/348503.htmlhttp://m.tkk7.com/ashutc/comments/348503.htmlhttp://m.tkk7.com/ashutc/archive/2011/04/18/348503.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/348503.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/348503.html q有可以感觉到的是:农夫把未满月的牛抱回家试M

package cn.yu.test;

/**
 * 一个农夫养了一头牛Q三q后Q这头牛每年会生?头牛Q生出来的牛三年后,又可以每q生Z头牛……问农?0q后有多头?nq呢Q(用JAVA实现Q?nbsp;
 * Created by myeclipse8.5.
 * User: 
@author yu
 * Time: 2011-4-18 
 * Company: 天极传媒集团
 * Descripion:
 
*/
public class Cow {
    
public static int cowcount = 0;

    
public static void CowCount(int startYear, int endYear) {
        cowcount
++;
        
for (int i = 3 + startYear; i <= endYear; i++) {
            CowCount(i, endYear);
        }
    }
    
public static void main(String[] args) {
        
int startYear=1;//开始年份,W一q开?/span>
        int endYear=10;//l止q䆾Q第十年l止
        CowCount(startYear, endYear);
        System.out.println(
"ȝ敎ͼ"+cowcount);
    }
}

l果 ȝ敎ͼ19

分析Q?nbsp; q䆾  牛名?nbsp;                                   牛年?nbsp;                      L
        1q?nbsp;  a                                         0?Q刚生下来)              1?br />         2q?nbsp;  a                                         1?nbsp;                          1?br />         3q?nbsp;  a                                         2?nbsp;                          1?br />         4q?nbsp;  a,b1                                      3?/span>,0?Q增加一_          2?nbsp;
Q这里理解吧Q成q牛4岁才可以生小牛,牛刚生下来?岁而不?岁)
        5q?nbsp;  a,b1,b2                                   4?/span>Q??0?                 3?br />         6q?nbsp;  a,b1,b2,b3                                5?/span>Q??1?0?             4?br />         7q?nbsp;  a,b1,b2,b3,b4                             6岁,3?/span> 2?1?0?0?             6?br />         8q?nbsp;  a,b1,b2,b3,b4,b5,c1                       7岁,4?3?/span> 2?1?1?0?         9?br />         9q?nbsp;  a,b1,b2,b3,b4,b5,b6,c1,c2,d1              8岁,5?4?/span> 3?/span> 2?2?1?#8230;…      13?br />         10q?nbsp; a,b1,b2,b3,b4,b5,b6,b7,c1,c2,c3,d1,d2     9岁,6?5?4?/span> 3?3?/span> 2?#8230;…      19?br />
如果是第三年生小牛呢Q也是说牛2岁就可以生小牛)
那就是网上大多数的答?

package cn.yu.test;

/**
 * 一个农夫养了一头牛Q三q后Q这头牛每年会生?头牛Q生出来的牛三年后,又可以每q生Z头牛……问农?0q后有多头?nq呢Q(用JAVA实现Q?nbsp;
 * Created by myeclipse8.5.
 * User: 
@author yu
 * Time: 2011-4-18 
 * Company: 天极传媒集团
 * Descripion:
 
*/
public class Cow {
    
public static int cowcount = 0;

    
public static void CowCount(int startYear, int endYear) {
        cowcount
++;
        
for (int i = 2 + startYear; i <= endYear; i++) {
            CowCount(i, endYear);
        }
    }
    
public static void main(String[] args) {
        
int startYear=1;//开始年份,W一q开?/span>
        int endYear=10;//l止q䆾Q第十年l止
        CowCount(startYear, endYear);
        System.out.println(
"ȝ敎ͼ"+cowcount);
    }
}

l果 ȝ敎ͼ55










西瓜 2011-04-18 16:21 发表评论
]]>
java23U设计模式(代码版{Q?/title><link>http://m.tkk7.com/ashutc/archive/2010/12/14/340667.html</link><dc:creator>西瓜</dc:creator><author>西瓜</author><pubDate>Tue, 14 Dec 2010 09:03:00 GMT</pubDate><guid>http://m.tkk7.com/ashutc/archive/2010/12/14/340667.html</guid><wfw:comment>http://m.tkk7.com/ashutc/comments/340667.html</wfw:comment><comments>http://m.tkk7.com/ashutc/archive/2010/12/14/340667.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/ashutc/comments/commentRss/340667.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/ashutc/services/trackbacks/340667.html</trackback:ping><description><![CDATA[     摘要: Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->  package   lq.test;         impor...  <a href='http://m.tkk7.com/ashutc/archive/2010/12/14/340667.html'>阅读全文</a><img src ="http://m.tkk7.com/ashutc/aggbug/340667.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/ashutc/" target="_blank">西瓜</a> 2010-12-14 17:03 <a href="http://m.tkk7.com/ashutc/archive/2010/12/14/340667.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>StringUtilshttp://m.tkk7.com/ashutc/archive/2010/11/01/336672.html西瓜西瓜Mon, 01 Nov 2010 06:24:00 GMThttp://m.tkk7.com/ashutc/archive/2010/11/01/336672.htmlhttp://m.tkk7.com/ashutc/comments/336672.htmlhttp://m.tkk7.com/ashutc/archive/2010/11/01/336672.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/336672.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/336672.htmlStringUtils Ҏ(gu)的操作对象是 java.lang.String cd的对象,?nbsp;JDK 提供?nbsp;String ...  阅读全文

西瓜 2010-11-01 14:24 发表评论
]]>
使用JSON的方?/title><link>http://m.tkk7.com/ashutc/archive/2010/10/13/335022.html</link><dc:creator>西瓜</dc:creator><author>西瓜</author><pubDate>Wed, 13 Oct 2010 05:42:00 GMT</pubDate><guid>http://m.tkk7.com/ashutc/archive/2010/10/13/335022.html</guid><wfw:comment>http://m.tkk7.com/ashutc/comments/335022.html</wfw:comment><comments>http://m.tkk7.com/ashutc/archive/2010/10/13/335022.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/ashutc/comments/commentRss/335022.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/ashutc/services/trackbacks/335022.html</trackback:ping><description><![CDATA[     摘要: SON ?nbsp;JavaScript Object NatationQ它是一U轻量的数据交换格式,非常适合于服务器?nbsp;JavaScript 的交互。本文将快速讲?nbsp;JSON 格式Qƈ通过代码CZ演示如何分别在客L(fng)和服务器端进?nbsp;JSON 格式数据的处理?   Json必需的包 ...  <a href='http://m.tkk7.com/ashutc/archive/2010/10/13/335022.html'>阅读全文</a><img src ="http://m.tkk7.com/ashutc/aggbug/335022.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/ashutc/" target="_blank">西瓜</a> 2010-10-13 13:42 <a href="http://m.tkk7.com/ashutc/archive/2010/10/13/335022.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用 org.apache.commons.io.FileUtils快速读写文?/title><link>http://m.tkk7.com/ashutc/archive/2010/07/13/325933.html</link><dc:creator>西瓜</dc:creator><author>西瓜</author><pubDate>Tue, 13 Jul 2010 02:45:00 GMT</pubDate><guid>http://m.tkk7.com/ashutc/archive/2010/07/13/325933.html</guid><wfw:comment>http://m.tkk7.com/ashutc/comments/325933.html</wfw:comment><comments>http://m.tkk7.com/ashutc/archive/2010/07/13/325933.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/ashutc/comments/commentRss/325933.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/ashutc/services/trackbacks/325933.html</trackback:ping><description><![CDATA[     摘要: 利用 org.apache.commons.io.FileUtils快速读写文?http://php.11519.net/5jblog/?p=475   String fileName = "C://11.txt";   File file = new File(fileName);   String fileContent = "...  <a href='http://m.tkk7.com/ashutc/archive/2010/07/13/325933.html'>阅读全文</a><img src ="http://m.tkk7.com/ashutc/aggbug/325933.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/ashutc/" target="_blank">西瓜</a> 2010-07-13 10:45 <a href="http://m.tkk7.com/ashutc/archive/2010/07/13/325933.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>法的时间复杂度的具体步?/title><link>http://m.tkk7.com/ashutc/archive/2009/07/24/288211.html</link><dc:creator>西瓜</dc:creator><author>西瓜</author><pubDate>Fri, 24 Jul 2009 07:03:00 GMT</pubDate><guid>http://m.tkk7.com/ashutc/archive/2009/07/24/288211.html</guid><wfw:comment>http://m.tkk7.com/ashutc/comments/288211.html</wfw:comment><comments>http://m.tkk7.com/ashutc/archive/2009/07/24/288211.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/ashutc/comments/commentRss/288211.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/ashutc/services/trackbacks/288211.html</trackback:ping><description><![CDATA[<p>  ?扑և法中的基本语句Q?/p> <p>  法中执行次数最多的那条语句是基本语句Q通常是最内层循环的@环体?/p> <p>  ?计算基本语句的执行次数的数量U;</p> <p>  只需计算基本语句执行ơ数的数量Q这意味着只要保证基本语句执行ơ数的函C的最高次q正即可,可以忽略所有低ơ幂和最高次q的pL。这栯够简化算法分析,q且使注意力集中在最重要的一点上Q增长率?/p> <p>  ?用大Ο记号表示法的时间性能?/p> <p>  基本语句执行次数的数量U放入大Ο记号中?/p> <p>  如果法中包含嵌套的循环Q则基本语句通常是最内层的@环体Q如果算法中包含q列的@环,则将q列循环的时间复杂度相加。例如:</p> <p>  for (i=1; i<=n; i++)<br /> x++;</p> <p>  for (i=1; i<=n; i++)<br /> for (j=1; j<=n; j++)<br /> x++;</p> <p>  W一个for循环的时间复杂度?#927;(n)Q第二个for循环的时间复杂度?#927;(n2)Q则整个法的时间复杂度?#927;(n+n2)=Ο(n2)?/p> <p>  常见的算法时间复杂度由小到大依次为:</p> <p>  Ο(1)Q?#927;(log2n)Q?#927;(n)Q?#927;(nlog2n)Q?#927;(n2)Q?#927;(n3)Q?#8230;Q?#927;(2n)Q?#927;(n!)</p> <p>  Ο(1)表示基本语句的执行次数是一个常敎ͼ一般来_只要法中不存在循环语句Q其旉复杂度就?#927;(1)?#927;(log2n)?#927;(n)?#927;(nlog2n)?#927;(n2)?#927;(n3)UCؓ(f)多项式时_?#927;(2n)?#927;(n!)UCؓ(f)指数旉。计机U学家普遍认为前者是有效法Q把q类问题UCؓ(f)Pc问题,而把后者称为NP问题?/p> <p><span style="color: red;" twffan="done">O(1)</span><br /> <br /> Temp=i;i=j;j=temp;                     <br /> <br /> 以上三条单个语句的频度均?Q该E序D늚执行旉是一个与问题规模n无关的常数。算法的旉复杂度ؓ(f)常数ӞCT(n)=O(1)。如果算法的执行?间不随着问题规模n的增加而增长,即ɽ法中有上千条语句,其执行时间也不过是一个较大的常数。此cȝ法的旉复杂度是O(1)?<br /> <br /> <span style="color: red;" twffan="done">O(n^2)<br /> </span><br /> 2.1. 交换i和j的内?br />      sum=0Q?nbsp;                Q一ơ)<br />      for(i=1;i<=n;i++)       Qn?Q?br />         for(j=1;j<=n;j++) Qn^2?Q?br />          sum++Q?nbsp;      Qn^2?Q?br /> 解:T(n)=2n^2+n+1 =O(n^2)<br /> <br /> 2.2.   <br />     for (i=1;i<n;i++)<br />     { <br />         y=y+1;         ?nbsp;  <br />         for (j=0;j<=(2*n);j++)    <br />            x++;        ?nbsp;     <br />     }          <br /> 解: 语句1的频度是n-1<br />           语句2的频度是(n-1)*(2n+1)=2n^2-n-1<br />           f(n)=2n^2-n-1+(n-1)=2n^2-2<br />           该程序的旉复杂度T(n)=O(n^2).         <br /> <br /> <span style="color: red;" twffan="done">O(n)</span>      <br />                                                        <br /> 2.3. <br />     a=0;<br />     b=1;                      ?br />     for (i=1;i<=n;i++) ?br />     {  <br />        s=a+b;    ?br />        b=a;     ?nbsp; <br />        a=s;     ?br />     }<br /> 解: 语句1的频度:2,        <br />            语句2的频度: n,        <br />           语句3的频度: n-1,        <br />           语句4的频度:n-1,    <br />           语句5的频度:n-1,                                  <br />           T(n)=2+n+3(n-1)=4n-1=O(n).<br />                                                                                                   <br /> <span style="color: red;" twffan="done">O(logn )<br /> </span><br /> 2.4. <br />      i=1;       ?br />     while (i<=n)<br />        i=i*2; ?br /> 解: 语句1的频度是1,  <br />           设语?的频度是f(n),   则:2^f(n)<=n;f(n)<=logn    <br />           取最大值f(n)= logn,<br />           T(n)=O(logn )<br /> <br /> <span style="color: red;" twffan="done">O(n^3)</span><br /> <br /> 2.5. <br />     for(i=0;i<n;i++)<br />     {  <br />        for(j=0;j<i;j++)  <br />        {<br />           for(k=0;k<j;k++)<br />              x=x+2;  <br />        }<br />     }<br /> 解:当i=m, j=k的时?内层循环的次Cؓ(f)k当i=m? j 可以?0,1,...,m-1 , 所以这里最内@环共q行?+1+...+m-1=(m-1)m/2ơ所?i?取到n, 则@环共q行? 0+(1-1)*1/2+...+(n-1)n/2=n(n+1)(n-1)/6所以时间复杂度为O(n^3).</p> <img src ="http://m.tkk7.com/ashutc/aggbug/288211.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/ashutc/" target="_blank">西瓜</a> 2009-07-24 15:03 <a href="http://m.tkk7.com/ashutc/archive/2009/07/24/288211.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>判断单链表是否存在环Q判断两个链表是否相交问题详?转蝲)http://m.tkk7.com/ashutc/archive/2009/07/24/288205.html西瓜西瓜Fri, 24 Jul 2009 06:35:00 GMThttp://m.tkk7.com/ashutc/archive/2009/07/24/288205.htmlhttp://m.tkk7.com/ashutc/comments/288205.htmlhttp://m.tkk7.com/ashutc/archive/2009/07/24/288205.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/288205.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/288205.html有一个单链表Q其中可能有一个环Q也是某个节点的next指向的是链表中在它之前的节点Q这样在链表的尾部Ş成一环?、如何判断一个链表是不是q类链表Q?、如果链表ؓ(f)存在环,如果扑ֈ环的入口点?扩展Q判断两个单链表是否怺Q如果相交,l出怺的第一个点?br /> 有一个单链表Q其中可能有一个环Q也是某个节点的next指向的是链表中在它之前的节点Q这样在链表的尾部Ş成一环?/p>

问题Q?/p>

1、如何判断一个链表是不是q类链表Q?br /> 2、如果链表ؓ(f)存在环,如果扑ֈ环的入口点?

解答Q?/p>

一、判断链表是否存在环Q办法ؓ(f)Q?/p>

讄两个指针(fast, slow)Q初始值都指向_slow每次前进一步,fast每次前进二步Q如果链表存在环Q则fast必定先进入环Q而slow后进入环Q两个指针必定相遇?当然Qfast先行头到N为NULLQ则为无环链?E序如下Q?/p>

bool IsExitsLoop(slist * head)
{
    slist * slow = head ,  * fast = head;

    while  ( fast  &&  fast -> next )
    {
        slow  =  slow -> next;
        fast  =  fast -> next -> next;
        if  ( slow  ==  fast )  break ;
    }

    return   ! (fast  ==  NULL  ||  fast -> next  ==  NULL);
}
二、找到环的入口点

当fast若与slow盔RӞslow肯定没有走遍历完链表Q而fast已经在环内@环了n?1<=n)。假设slowCs步,则fastC2s步(fast步数q等于s 加上在环上多转的n圈)Q设环长为rQ则Q?/p>

2s = s + nr
s= nr

设整个链表长LQ入口环与相遇点距离为xQv点到环入口点的距Mؓ(f)a?br /> a + x = nr
a + x = (n – 1)r +r = (n-1)r + L - a
a = (n-1)r + (L – a – x)

(L – a – x)为相遇点到环入口点的距离Q由此可知,从链表头到环入口点等?n-1)循环内环+盔R点到环入口点Q于是我们从链表头、与盔R点分别设一个指针,每次各走一步,两个指针必定盔RQ且盔RW一点ؓ(f)环入口点?/p>

E序描述如下Q?/p>

slist *  FindLoopPort(slist * head)
{
    slist * slow  =  head,  * fast  =  head;

    while  ( fast  &&  fast -> next )
    {
        slow  =  slow -> next;
        fast  =  fast -> next -> next;
        if  ( slow  ==  fast )  break ;
    }

    if  (fast  ==  NULL  ||  fast -> next  ==  NULL)
        return  NULL;

    slow  =  head;
    while  (slow  !=  fast)
    {
         slow  =  slow -> next;
         fast  =  fast -> next;
    }

    return  slow;
}

附一U易于理解的解释Q?/p>

一UOQnQ的办法是Q搞两个指针Q一个每ơ递增一步,一个每ơ递增两步Q如果有环的话两者必焉合,反之亦然Q:
关于q个解法最形象的比d是在操场当中跑步Q速度快的会把速度慢的扣圈

可以证明Qp2q赶上p1的时候,p1一定还没有走完一遍环路,p2也不会跨p1多圈才追?/p>

我们可以从p2和p1的位|差距来证明Qp2一定会赶上p1但是不会跌p1?/p>

因ؓ(f)p2每次?步,而p1C步,所以他们之间的差距是一步一步的~小Q?Q?Q?Q?Q? ?的时候就重合?/p>

Ҏ(gu)q个方式Q可以证明,p2每次C步以上,q不总能加快的速度Q反而有可能判别不出有环

既然能够判断出是否是有环路,那改如何扑ֈq个环\的入口呢Q?

解法如下Q?当p2按照每次2步,p1每次一步的方式赎ͼ发现p2和p1重合Q确定了单向链表有环路了

接下来,让p2回到链表的头部,重新赎ͼ每次步长不是?了,而是?Q那么当p1和p2再次盔R的时候,是环\的入口了?/p>

q点可以证明的:

在p2和p1W一ơ相遇的时候,假定p1Cn步骤Q环路的入口是在p步的时候经q的Q那么有

p1走的路径Q?p+c Q?nQ?nbsp;        c为p1和p2怺点,距离环\入口的距?/p>

p2走的路径Q?p+c+k*L = 2*nQ?nbsp;  L为环路的周长Qk是整?/p>

昄Q如果从p+c点开始,p1再走n步骤的话Q还可以回到p+cq个?/p>

同时p2从头开始走的话Q经qn步,也会辑ֈp+cq点

昄在这个步骤当中p1和p2只有前p步骤走的路径不同Q所以当p1和p2再次重合的时候,必然是在链表的环路入口点上?/p>

扩展问题Q?/p>

判断两个单链表是否相交,如果怺Q给出相交的W一个点Q两个链表都不存在环Q?/p>

比较好的Ҏ(gu)有两个:

一、将其中一个链表首q,另外一个链表是否存在环Q如果存在,则两个链表相交,而检出来的依赖环入口即为相交的W一个点?/p>

二、如果两个链表相交,那个两个链表从相交点到链表结束都是相同的节点Q我们可以先遍历一个链表,直到NQ再遍历另外一个链表,如果也可以走到同L(fng)l尾点,则两个链表相交?/p>

q时我们C两个链表lengthQ再遍历一ơ,镉K表节点先出发前进(lengthMax-lengthMin)步,之后两个链表同时前进Q每ơ一步,盔R的第一点即Z个链表相交的W一个点?/p>


本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/ssfp8762/archive/2009/07/08/4331419.aspx



西瓜 2009-07-24 14:35 发表评论
]]>
JDK1.5新特性介l?/title><link>http://m.tkk7.com/ashutc/archive/2009/06/10/281343.html</link><dc:creator>西瓜</dc:creator><author>西瓜</author><pubDate>Wed, 10 Jun 2009 14:44:00 GMT</pubDate><guid>http://m.tkk7.com/ashutc/archive/2009/06/10/281343.html</guid><wfw:comment>http://m.tkk7.com/ashutc/comments/281343.html</wfw:comment><comments>http://m.tkk7.com/ashutc/archive/2009/06/10/281343.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/ashutc/comments/commentRss/281343.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/ashutc/services/trackbacks/281343.html</trackback:ping><description><![CDATA[<h1 id="artibodyTitle"> </h1> <div class="gi8wug8" id="conauthor"><span>2004-09-11 00:05</span><span>作者:xBird</span><span>出处QJava研究l织</span><span>责Q~辑Q方?/span></div> <div id="kq8ukmw" class="topadbg"></div> <p align="justify"><!--正文开?-></p> <div class="c8u4a4e" id="conneirong"> <div class="8444ky4" id="artibody"><!-- Error --> <div id="aw44mk4" class="clear1"></div> <div id="ssqy4im" class="guanggao"></div> “JDK1.5”Q开发代L(fng)虎)的一个重要主题就是通过新增一些特性来化开发,q些Ҏ(gu)包括泛型,for-else 循环Q自动装?拆包Q枚举,可变参数, 静态导入 。用这些特性有助于我们~写更加清晰Q精(zhn),安全的代码?br /> <br /> 下面我们单介l一下这些新Ҏ(gu)?br /> <br /> <strong>1.泛型(Generic)</strong><br /> <br /> C++通过模板技术可以指定集合的元素cdQ而Java?.5之前一直没有相对应的功能。一个集合可以放Mcd的对象,相应C集合里面拿对象的时候我们也不得不对他们q行强制得类型{换。猛虎引入了泛型Q它允许指定集合里元素的cdQ这样你可以得到强类型在~译时刻q行cd查的好处?br /> <br /> <table align="center" bgcolor="#e6e4dd" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td>Collection<String> c = new ArrayList();<br /> c.add(new Date());</td> </tr> </tbody> </table> <br /> ~译器会l出一个错误:<br /> <br /> <table align="center" bgcolor="#e6e4dd" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td>add(java.lang.String) in java.util.Collection<java.lang.String> cannot be applied to (java.util.Date)</td> </tr> </tbody> </table> <br /> <strong>2.For-Each循环</strong><br /> <br /> For-Each循环得加入简化了集合的遍历。假设我们要遍历一个集合对其中的元素进行一些处理。典型的代码为:<br /> <br /> <table align="center" bgcolor="#e6e4dd" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td>void processAll(Collection c){<br /> for(Iterator i=c.iterator(); i.hasNext();){<br /> MyClass myObject = (MyClass)i.next();<br /> myObject.process();<br /> }<br /> }</td> </tr> </tbody> </table> <br /> 使用For-Each循环Q我们可以把代码改写成:<br /> <br /> <table align="center" bgcolor="#e6e4dd" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td>void processAll(Collection<MyClass> c){<br /> for (MyClass  myObject :c)<br /> myObject.process();<br /> }</td> </tr> </tbody> </table> <br /> q段代码要比上面清晰许多Qƈ且避免了强制cd转换?br /> <br /> <strong>3.自动装包/拆包(Autoboxing/unboxing)</strong><br /> <br /> 自动装包/拆包大大方便了基本类型数据和它们包装cd使用?br /> <br /> 自动装包Q基本类型自动{为包装类.(int >> Integer)<br /> <br /> 自动拆包Q包装类自动转ؓ(f)基本cd.(Integer >> int)<br /> <br /> 在JDK1.5之前Q我们L寚w合不能存攑֟本类型而耿耿于怀Q现在自动{换机制解决了我们的问题?br /> <br /> <table align="center" bgcolor="#e6e4dd" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td>int a = 3;<br /> Collection c = new ArrayList();<br /> c.add(a);//自动转换成Integer.<br /> <br /> Integer b = new Integer(2);<br /> c.add(b + 2);</td> </tr> </tbody> </table> <br /> q里Integer先自动{换ؓ(f)intq行加法q算Q然后int再次转换为Integer.<br /> <br /> <strong>4.枚D(Enums)</strong><br /> <br /> JDK1.5加入了一个全新类型的“c?#8221;Q枚丄型。ؓ(f)此JDK1.5引入了一个新关键字enmu. 我们可以q样来定义一个枚丄型?br /> <br /> <table align="center" bgcolor="#e6e4dd" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td>public enum Color<br /> {<br /> Red,<br /> White,<br /> Blue<br /> }</td> </tr> </tbody> </table> <br /> 然后可以q样来用Color myColor = Color.Red.<br /> <br /> 枚Dcdq提供了两个有用的静态方法values()和valueOf(). 我们可以很方便地使用它们Q例?br /> <br /> <table align="center" bgcolor="#e6e4dd" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td>for (Color c : Color.values())<br /> System.out.println(c);</td> </tr> </tbody> </table> <br /> <strong>5.可变参数(Varargs)</strong><br /> <br /> 可变参数使程序员可以声明一个接受可变数目参数的Ҏ(gu)。注意,可变参数必须是函数声明中的最后一个参数。假设我们要写一个简单的Ҏ(gu)打印一些对象,<br /> <br /> <table align="center" bgcolor="#e6e4dd" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td>util.write(obj1);<br /> util.write(obj1,obj2);<br /> util.write(obj1,obj2,obj3);<br /> …</td> </tr> </tbody> </table> <br /> 在JDK1.5之前Q我们可以用重蝲来实玎ͼ但是q样需要写很多的重载函敎ͼ昑־不是很有效。如果用可变参数的话我们只需要一个函数就行了<br /> <br /> <table align="center" bgcolor="#e6e4dd" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td>public void write(Object... objs) {<br /> for (Object obj: objs)<br /> System.out.println(obj);<br /> }</td> </tr> </tbody> </table> <br /> 在引入可变参C后,Java的反包也更加方便用了。对于c.getMethod("test", new Object[0]).invoke(c.newInstance(), new Object[0]))Q现在我们可以这样写了c.getMethod("test").invoke(c.newInstance())Q这L(fng)代码比原来清楚了很多。 <br /> <br /> <strong>6.静态导?Static Imports)</strong><br /> <br /> 要用用静态成员(Ҏ(gu)和变量)我们必须l出提供q个Ҏ(gu)的类。用静态导入可以被导入类的所有静态变量和静态方法在当前cȝ接可见,使用q些静态成员无需再给Z们的cd?br /> <br /> <table align="center" bgcolor="#e6e4dd" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td>import static java.lang.Math.*;<br /> …….<br /> r = sin(PI * 2); //无需再写r = Math.sin(Math.PI);</td> </tr> </tbody> </table> <br /> 不过Q过度用这个特性也会一定程度上降低代码地可L?br /> </div> </div> <img src ="http://m.tkk7.com/ashutc/aggbug/281343.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/ashutc/" target="_blank">西瓜</a> 2009-06-10 22:44 <a href="http://m.tkk7.com/ashutc/archive/2009/06/10/281343.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java ClassLoader机制http://m.tkk7.com/ashutc/archive/2009/05/29/278944.html西瓜西瓜Fri, 29 May 2009 12:45:00 GMThttp://m.tkk7.com/ashutc/archive/2009/05/29/278944.htmlhttp://m.tkk7.com/ashutc/comments/278944.htmlhttp://m.tkk7.com/ashutc/archive/2009/05/29/278944.html#Feedback0http://m.tkk7.com/ashutc/comments/commentRss/278944.htmlhttp://m.tkk7.com/ashutc/services/trackbacks/278944.htmlJava虚拟机)启动Ӟ会Ş成由三个cd载器l成的初始类加蝲器层ơ结构:

       bootstrap classloader
                |
       extension classloader
                |
       system classloader

bootstrap classloader Q引|也称为原始)cd载器Q它负责加蝲Java的核心类。在Sun的JVM中,在执行java的命令中使用-Xbootclasspath选项或? D选项指定sun.boot.class.pathpȝ属性值可以指定附加的cR这个加载器的是非常Ҏ(gu)的,它实际上不是 java.lang.ClassLoader的子c,而是由JVM自n实现的。大家可以通过执行以下代码来获得bootstrap classloader加蝲了那些核心类库:
   URL[] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs();
   for (int i = 0; i < urls.length; i++) {
     System.out.println(urls.toExternalform());
   }
在我的计机上的l果为:
文g:/C:/j2sdk1.4.1_01/jre/lib/endorsed/dom.jar
文g:/C:/j2sdk1.4.1_01/jre/lib/endorsed/sax.jar
文g:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xalan-2.3.1.jar
文g:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xercesImpl-2.0.0.jar
文g:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xml-apis.jar
文g:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xsltc.jar
文g:/C:/j2sdk1.4.1_01/jre/lib/rt.jar
文g:/C:/j2sdk1.4.1_01/jre/lib/i18n.jar
文g:/C:/j2sdk1.4.1_01/jre/lib/sunrsasign.jar
文g:/C:/j2sdk1.4.1_01/jre/lib/jsse.jar
文g:/C:/j2sdk1.4.1_01/jre/lib/jce.jar
文g:/C:/j2sdk1.4.1_01/jre/lib/charsets.jar
文g:/C:/j2sdk1.4.1_01/jre/classes
q时大家知道了ؓ(f)什么我们不需要在pȝ属性CLASSPATH中指定这些类库了吧,因ؓ(f)JVM在启动的时候就自动加蝲它们了?br />
extension classloader Q扩展类加蝲器,它负责加载JRE的扩展目录(JAVA_HOME/jre/lib/ext或者由java.ext.dirspȝ属性指定的Q中JAR的类包。这为引入除Java核心cM外的新功能提供了一个标准机制。因为默认的扩展目录Ҏ(gu)有从同一个JRE中启动的JVM都是通用的,所以放入这个目录的 JARcdҎ(gu)有的JVM和system classloader都是可见的。在q个实例上调用方法getParent()Lq回I值nullQ因为引导加载器bootstrap classloader不是一个真正的ClassLoader实例。所以当大家执行以下代码Ӟ
   System.out.println(System.getProperty("java.ext.dirs"));
   ClassLoader extensionClassloader=ClassLoader.getSystemClassLoader().getParent();
   System.out.println("the parent of extension classloader : "+extensionClassloader.getParent());
l果为:
C:\j2sdk1.4.1_01\jre\lib\ext
the parent of extension classloader : null
extension classloader是system classloader的parentQ而bootstrap classloader是extension classloader的parentQ但它不是一个实际的classloaderQ所以ؓ(f)null?br />
system classloader Q系l(也称为应用)cd载器Q它负责在JVM被启动时Q加载来自在命ojava中的-classpath或者java.class.pathpȝ属性或?CLASSPATH*作系l属性所指定的JARcd和类路径。总能通过静态方法ClassLoader.getSystemClassLoader()扑ֈ该类加蝲器。如果没有特别指定,则用戯定义的Q何类加蝲器都该cd载器作ؓ(f)它的父加载器。执行以下代码即可获得:
   System.out.println(System.getProperty("java.class.path"));
输出l果则ؓ(f)用户在系l属性里面设|的CLASSPATH?br /> classloader 加蝲cȝ的是全盘负责委托机制。所谓全盘负责,x当一个classloader加蝲一个Class的时候,q个Class所依赖的和引用的所?Class也由q个classloader负责载入Q除非是昑ּ的用另外一个classloader载入Q委托机制则是先让parentQ父Q类加蝲?(而不是superQ它与parent classloadercM是承关p?LQ只有在parent找不到的时候才从自qc\径中d找。此外类加蝲q采用了cache机制Q也是如果 cache中保存了q个Classq接返回它Q如果没有才从文件中d和{换成ClassQƈ存入cacheQ这是Z么我们修改了Class但是必须重新启动JVM才能生效的原因?br />

每个ClassLoader加蝲Class的过E是Q?br /> 1.此Class是否载入q(卛_cache中是否有此ClassQ,如果有到8,如果没有?
2.如果parent classloader不存在(没有parentQ那parent一定是bootstrap classloader了)Q到4
3.hparent classloader载入Q如果成功到8Q不成功?
4.hjvm从bootstrap classloader中蝲入,如果成功?
5.LClass文gQ从与此classloader相关的类路径中寻找)。如果找不到则到7.
6.从文件中载入ClassQ到8.
7.抛出ClassNotFoundException.
8.q回Class.

其中5.6步我们可以通过覆盖ClassLoader的findClassҎ(gu)来实现自q载入{略。甚臌盖loadClassҎ(gu)来实现自q载入q程?br />
cd载器的顺序是Q?br /> 先是bootstrap classloaderQ然后是extension classloaderQ最后才是system classloader。大家会发现加蝲的Class是重要的越在靠前面。这样做的原因是Z安全性的考虑Q试惛_果system classloader“亲自”加蝲了一个具有破坏性的“java.lang.System”cȝ后果吧。这U委托机制保证了用户即h一个这L(fng)c,也把它加入到了类路径中,但是它永q不会被载入Q因个类L由bootstrap classloader来加载的。大家可以执行一下以下的代码Q?br />    System.out.println(System.class.getClassLoader());
会看到l果是nullQ这p明java.lang.System是由bootstrap classloader加蝲的,因ؓ(f)bootstrap classloader不是一个真正的ClassLoader实例Q而是由JVM实现的,正如前面已经说过的?br />
下面p我们来看看JVM是如何来为我们来建立cd载器的结构的Q?br /> sun.misc.LauncherQ顾名思义Q当你执行java命o的时候,JVM会先使用bootstrap classloader载入q初始化一个LauncherQ执行下来代码:
  System.out.println("the Launcher's classloader is "+sun.misc.Launcher.getLauncher().getClass().getClassLoader());
l果为:
  the Launcher's classloader is null (因ؓ(f)是用bootstrap classloader加蝲,所以class loader为null)
Launcher 会根据系l和命o讑֮初始化好class loaderl构QJVMq它来获得extension classloader和system classloader,q蝲入所有的需要蝲入的ClassQ最后执行java命o指定的带有静态的mainҎ(gu)的Class。extension classloader实际上是sun.misc.Launcher$ExtClassLoadercȝ一个实例,system classloader实际上是sun.misc.Launcher$AppClassLoadercȝ一个实例。ƈ且都?java.net.URLClassLoader的子cR?br />
让我们来看看Launcher初试化的q程的部分代码?br />
Launcher的部分代码:
public class Launcher  {
   public Launcher() {
       ExtClassLoader extclassloader;
       try {
           //初始化extension classloader
           extclassloader = ExtClassLoader.getExtClassLoader();
       } catch(IOException ioexception) {
           throw new InternalError("Could not create extension class loader");
       }
       try {
           //初始化system classloaderQparent是extension classloader
           loader = AppClassLoader.getAppClassLoader(extclassloader);
       } catch(IOException ioexception1) {
           throw new InternalError("Could not create application class loader");
       }
       //system classloader讄成当前线E的context classloaderQ将在后面加以介l)
       Thread.currentThread().setContextClassLoader(loader);
       ......
   }
   public ClassLoader getClassLoader() {
       //q回system classloader
       return loader;
   }
}

extension classloader的部分代码:
static class Launcher$ExtClassLoader extends URLClassLoader {

   public static Launcher$ExtClassLoader getExtClassLoader()
       throws IOException
   {
       File afile[] = getExtDirs();
       return (Launcher$ExtClassLoader)AccessController.doPrivileged(new Launcher$1(afile));
   }
  private static File[] getExtDirs() {
       //获得pȝ属?#8220;java.ext.dirs”
       String s = System.getProperty("java.ext.dirs");
       File afile[];
       if(s != null) {
           StringTokenizer stringtokenizer = new StringTokenizer(s, File.pathSeparator);
           int i = stringtokenizer.countTokens();
           afile = new File;
           for(int j = 0; j < i; j++)
               afile[j] = new File(stringtokenizer.nextToken());

       } else {
           afile = new File[0];
       }
       return afile;
   }
}

system classloader的部分代码:
static class Launcher$AppClassLoader extends URLClassLoader
{

   public static ClassLoader getAppClassLoader(ClassLoader classloader)
       throws IOException
   {
       //获得pȝ属?#8220;java.class.path”
       String s = System.getProperty("java.class.path");
       File afile[] = s != null ? Launcher.access$200(s) : new File[0];
       return (Launcher$AppClassLoader)AccessController.doPrivileged(new Launcher$2(s, afile, classloader));
   }
}

看了源代码大家就清楚了吧Qextension classloader是用系l属?#8220;java.ext.dirs”讄cL索\径的Qƈ且没有parent。system classloader是用系l属?#8220;java.class.path”讄cL索\径的Qƈ且有一个parent classloader。Launcher初始化extension classloaderQsystem classloaderQƈsystem classloader讄成ؓ(f)context classloaderQ但是仅仅返回system classloaderlJVM?br />
q里怎么又出来一个context classloader呢?它有什么用呢?我们在徏立一个线EThread的时候,可以个线E通过setContextClassLoaderҎ(gu)来指定一个合适的classloader作ؓ(f)q个U程的context classloaderQ当此线E运行的时候,我们可以通过getContextClassLoaderҎ(gu)来获得此context classloaderQ就可以用它来蝲入我们所需要的Class。默认的是system classloader。利用这个特性,我们可以“打破”classloader委托机制了,父classloader可以获得当前U程的context classloaderQ而这个context classloader可以是它的子classloader或?a onclick="javascript:tagshow(event, '%C6%E4%CB%FB');" href="javascript:;" target="_self">其他的classloaderQ那么父classloader可以从其获得所需?ClassQ这打破了只能向父classloaderh的限制了。这个机制可以满_我们的classpath是在q行时才定,q由定制?classloader加蝲的时?由system classloader(卛_jvm classpath?加蝲的class可以通过context classloader获得定制的classloaderq加载入特定的class(通常是抽象类和接?定制的classloader中是其实?,例如web应用中的servlet是用这U机制加载的.


好了Q现在我们了解了classloader的结构和工作原理Q那么我们如何实现在q行时的动态蝲入和更新呢?只要我们能够动态改变类搜烦路径和清除classloader的cache中已l蝲入的Classp了,有两个方案,一是我们承一个classloaderQ覆盖loadclassҎ(gu)Q动态的LClass文gq用defineClassҎ(gu)来;另一个则非常单实用,只要重新使用一个新的类搜烦路径来new一个classloaderp了,q样xCcL索\径以便来载入新的ClassQ也重新生成了一个空白的cache(当然,cL索\径不一定必L?。噢Q太好了Q我们几乎不用做什么工作,java.netURLClassLoader正是一个符合我们要求的classloaderQ我们可以直接用或者承它?yu)可以了Q?br />
q是j2se1.4 API的doc中URLClassLoader的两个构造器的描qͼ
URLClassLoader(URL[] urls)
         Constructs a new URLClassLoader for the specified URLs using the default delegation parent ClassLoader.
URLClassLoader(URL[] urls, ClassLoader parent)
         Constructs a new URLClassLoader for the given URLs.
其中URL[] urls是我们要设|的cL索\径,parent是q个classloader的parent classloaderQ默认的是system classloader?br />

好,现在我们能够动态的载入Class了,q样我们可以利用newInstanceҎ(gu)来获得一个Object。但我们如何此Object造型呢?可以此Object造型成它本n的Class吗?

首先让我们来分析一下java源文件的~译Q运行吧Qjavac命o是调?#8220;JAVA_HOME/lib/tools.jar”中的“com.sun.tools.javac.Main”的compileҎ(gu)来编译:

   public static int compile(String as[]);

   public static int compile(String as[], PrintWriter printwriter);

q回0表示~译成功Q字W串数组as则是我们用javac命o~译时的参数Q以I格划分。例如:
javac -classpath c:\foo\bar.jar;. -d c:\ c:\Some.java
则字W串数组as为{"-classpath","c:\\foo\\bar.jar;.","-d","c:\\","c:\\Some.java"}Q如果带有PrintWriter参数Q则会把~译信息出到q个指定的printWriter中。默认的输出是System.err?br />
其中 Main是由JVM使用Launcher初始化的system classloader载入的,Ҏ(gu)全盘负责原则Q编译器在解析这个java源文件时所发现的它所依赖和引用的所有Class也将由system classloader载入Q如果system classloader不能载入某个ClassӞ~译器将抛出一?#8220;cannot resolve symbol”错误?br />
所以首先编译就通不q,也就是编译器无法~译一个引用了不在CLASSPATH中的未知Class的java源文Ӟ而由于拼写错误或者没有把所需cd攑ֈCLASSPATH中,大家一定经常看到这?#8220;cannot resolve symbol”q个~译错误吧!

其次Q就是我们把q个Class攑ֈ~译路径中,成功的进行了~译Q然后在q行的时候不把它攑օ到CLASSPATH中而利用我们自q classloader来动态蝲入这个ClassQ这时候也会出?#8220;java.lang.NoClassDefFoundError”的违例,Z么呢Q?br />
我们再来分析一下,首先调用q个造型语句的可执行的Class一定是由JVM使用Launcher初始化的system classloader载入的,Ҏ(gu)全盘负责原则Q当我们q行造型的时候,JVM也会使用system classloader来尝试蝲入这个Class来对实例q行造型Q自然在system classloaderL不到q个Class时就会抛?#8220;java.lang.NoClassDefFoundError”的违例?br />
OKQ现在让我们来ȝ一下,java文g的编译和Class的蝲入执行,都是使用Launcher初始化的system classloader作ؓ(f)c蝲入器的,我们无法动态的改变system classloaderQ更无法让JVM使用我们自己的classloader来替换system classloaderQ根据全盘负责原则,限制了~译和运行时Q我们无法直接显式的使用一个system classloaderL不到的ClassQ即我们只能使用Java核心cdQ扩展类库和CLASSPATH中的cd中的Class?br />
q不dQ再试一下这U情况,我们把这个Class也放入到CLASSPATH中,让system classloader能够识别和蝲入。然后我们通过自己的classloader来从指定的class文g中蝲入这个ClassQ不能够委托 parent载入Q因样会被system classloader从CLASSPATH中将其蝲入)Q然后实例化一个ObjectQƈ造型成这个ClassQ这样JVM也识别这个ClassQ因?system classloader能够定位和蝲入这个Class从CLASSPATH中)Q蝲入的也不是CLASSPATH中的q个ClassQ而是?CLASSPATH外动态蝲入的Q这h行了吧Q十分不q的是,q时会出?#8220;java.lang.ClassCastException”q例?br />
Z么呢Q我们也来分析一下,不错Q我们虽然从CLASSPATH外用我们自qclassloader动态蝲入了q个ClassQ但它的实例造型的时候是JVM会用system classloader来再ơ蝲入这个ClassQƈ试用我们的自己的classloader载入的Class的一个实例造型为system classloader载入的这个ClassQ另外的一个)。大家发C么问题了吗?也就是我们尝试将从一个classloader载入的Class的一个实例造型为另外一个classloader载入的ClassQ虽然这两个Class的名字一P甚至是从同一个class文g中蝲入。但不幸的是JVM 却认个两个Class是不同的Q即JVM认ؓ(f)不同的classloader载入的相同的名字的ClassQ即使是从同一个class文g中蝲入的Q是不同的!q样做的原因我想大概也是主要Z安全性考虑Q这样就保证所有的核心Javac都是system classloader载入的,我们无法用自qclassloader载入的相同名字的Class的实例来替换它们的实例?br />
看到q里Q聪明的读者一定想C该如何动态蝲入我们的ClassQ实例化Q造型q调用了吧!

那就是利用面向对象的基本Ҏ(gu)之一的多形性。我们把我们动态蝲入的Class的实例造型成它的一个system classloader所能识别的父类p了!q是Z么呢Q我们还是要再来分析一ơ。当我们用我们自qclassloader来动态蝲入这我们只要把这个Class的时候,发现它有一个父cClassQ在载入它之前JVM先会载入q个父类ClassQ这个父cClass是system classloader所能识别的Q根据委托机Ӟ它将由system classloader载入Q然后我们的classloader再蝲入这个ClassQ创Z个实例,造型个父cClassQ注意了Q造型成这个父c?Class的时候(也就是上溯)是面向对象的java语言所允许的ƈ且JVM也支持的QJVM׃用system classloader再次载入q个父类ClassQ然后将此实例造型个父cClass。大家可以从q个q程发现q个父类Class都是?system classloader载入的,也就是同一个class loader载入的同一个ClassQ所以造型的时候不会出CQ何异常。而根据多形性,调用q个父类的方法时Q真正执行的是这个ClassQ非父类 ClassQ的覆盖了父cL法的Ҏ(gu)。这些方法中也可以引用system classloader不能识别的ClassQ因为根据全盘负责原则,只要载入q个Class的classloaderx们自己定义的 classloader能够定位和蝲入这些Classp了?br />
q样我们可以事先定义好一l接口或者基cdƈ攑օCLASSPATH中,然后在执行的时候动态的载入实现或者承了q些接口或基cȝ子类。还不明白吗Q让我们来想一想Servlet吧,web application server能够载入Ml承了Servlet的Classq正的执行它们Q不它实际的Class是什么,是都把它们实例化成Z个Servlet ClassQ然后执行Servlet的initQdoPostQdoGet和destroy{方法的,而不这个Servlet是从web- inf/lib和web-inf/classes下由system classloader的子classloader(卛_制的classloader)动态蝲入。说了这么多希望大家都明白了。在applet,ejb{容器中,都是采用了这U机?

对于以上各种情况Q希望大家实际编写一些example来实验一下?br />
最后我再说点别的, classloader虽然UCؓ(f)cd载器Q但q不意味着只能用来加蝲ClassQ我们还可以利用它也获得囄Q音频文件等资源的URLQ当Ӟq些资源必须在CLASSPATH中的jarcd中或目录下。我们来看API的doc中关于ClassLoader的两个寻找资源和Class的方法描q吧Q?br /> public URL getResource(String name)
用指定的名字来查找资源,一个资源是一些能够被class代码讉K的在某种E度上依赖于代码位置的数据(囄Q音频,文本{等Q?br />                一个资源的名字是以'/'号分隔确定资源的路径名的?br />                q个Ҏ(gu)先hparent classloader搜烦资源Q如果没有parentQ则会在内置在虚拟机中的classloaderQ即bootstrap classloaderQ的路径中搜索。如果失败,q个Ҏ(gu)调用findResource(String)来寻找资源?br /> public static URL getSystemResource(String name)
               从用来蝲入类的搜索\径中查找一个指定名字的资源。这个方法用system class loader来定位资源。即相当于ClassLoader.getSystemClassLoader().getResource(name)?br />
例如Q?br />    System.out.println(ClassLoader.getSystemResource("java/lang/String.class"));
的结果ؓ(f)Q?br />    jar:文g:/C:/j2sdk1.4.1_01/jre/lib/rt.jar!/java/lang/String.class
表明String.class文g在rt.jar的java/lang目录中?br /> 因此我们可以图片等资源随同Class一同打包到jarcd中(当然Q也可单独打包这些资源)q添加它们到class loader的搜索\径中Q我们就可以无需兛_q些资源的具体位|,让class loader来帮我们L了!

西瓜 2009-05-29 20:45 发表评论
]]>
վ֩ģ壺 ˬָ߳ëƬ| Ұһ| ˾þô߽| ŮƵվa| ڵƵ| ˬˬƬA| ޾ƷŮþþþ99| Ƶ| ҹþAAAAAëƬѿ| ޹Ѽһ| ҹվѰ߹ۿ| ˳ɻҳ߹ۿձ| 츾AV߹ۿ| ͵͵ͼƬ| һƷһAVһи | ޳˸վ| ձһ߹ۿ| ֱӽѿƵվ| þþƷ޾Ʒɫ| ޳AƬ| 91ƷѾþþþþ| һëƬѿa| AV뾫Ʒ| պƷһ| 쿴Ƭˬ_Ѳ| պƷþþþþ| jzzjzzѹۿƬ| avרԭ| ۺƵ| ߾ƷһӰȷ | ձƵ| jizzй| Ůžžվֻ| AVרAV| jlzzjlzzѲ| þþžѾƷ6| ɫѹۿ| va޵Ӱ| һ| ձ㽶Ƶ| AV |