??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲Av无码乱码在线znlu,亚洲AV无码国产精品麻豆天美,久久亚洲精品成人无码http://www.tkk7.com/yjjlovewjf/category/27837.htmlJavaStudy--我爱?芛_zh-cnThu, 03 Jan 2008 20:26:35 GMTThu, 03 Jan 2008 20:26:35 GMT60Java中的易؜问题攉 --?/title><link>http://www.tkk7.com/yjjlovewjf/archive/2008/01/03/172609.html</link><dc:creator>wǒ愛伱--咑֩ </dc:creator><author>wǒ愛伱--咑֩ </author><pubDate>Thu, 03 Jan 2008 15:40:00 GMT</pubDate><guid>http://www.tkk7.com/yjjlovewjf/archive/2008/01/03/172609.html</guid><wfw:comment>http://www.tkk7.com/yjjlovewjf/comments/172609.html</wfw:comment><comments>http://www.tkk7.com/yjjlovewjf/archive/2008/01/03/172609.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/yjjlovewjf/comments/commentRss/172609.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/yjjlovewjf/services/trackbacks/172609.html</trackback:ping><description><![CDATA[<br /> <font color="red">W一Qfinal, finally, finalize的区?</font><br /> <br /> final 修饰W(关键字)如果一个类被声明ؓfinalQ意味着它不能再z出新的子c,不能作ؓ父类被ѝ因此一个类不能既被声明?abstract的,又被声明为final的。将变量或方法声明ؓfinalQ?strong></strong>可以保证它们在用中不被改变。被声明为final的变量必d声明时给定初|而在以后的引用中只能dQ不可修攏V被声明为final的方法也同样只能使用Q不能重?<br /> <br /> finally 再异常处理时提供 finally 块来执行M清除操作。如果抛Z个异常,那么相匹配的 catch 子句׃执行Q然后控制就会进?finally 块(如果有的话)?<br /> finalize Ҏ名。Java 技术允怋?finalize() Ҏ在垃圾收集器对象从内存中清除出M前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对q个对象调用的。它是在 Object cM定义的,因此所有的c都l承了它。子c覆?finalize() Ҏ以整理系l资源或者执行其他清理工作。finalize() Ҏ是在垃圾攉器删除对象之前对q个对象调用的?<br /> <br /> <font color="red">W二QAnonymous Inner Class (匿名内部c? 是否可以extends(l承)其它c,是否可以implements(实现)interface(接口)? </font><br /> <br /> 匿名的内部类是没有名字的内部cR不能extends(l承) 其它c,但一个内部类可以作ؓ一个接口,由另一个内部类实现?<br /> <br /> <font color="red">W三QStatic Nested Class ?Inner Class的不同,说得多好</font><br /> Nested Class Q一般是C++的说法)QInner Class (一般是JAVA的说?。Java内部cMC++嵌套cL大的不同在于是否有指向外部的引用上。具体可见http: //www.frontfree.net/articles/services/view.asp?id=704&page=1 <br /> 注: 静态内部类QInner ClassQ意味着1创徏一个static内部cȝ对象Q不需要一个外部类对象Q?不能从一个static内部cȝ一个对象访问一个外部类对象 <br /> <br /> <font color="red">W四Q?amp;?amp;&的区别?/font><br /> <br /> &是位q算W?amp;&是布逻辑q算W?<br /> <br /> <font color="red">W五QHashMap和Hashtable的区别?/font><br /> <br /> 都属于Map接口的类Q实C惟一键映到特定的g?<br /> HashMap cL有分cL者排序。它允许一?null 键和多个 null 倹{?<br /> Hashtable cM?HashMapQ但是不允许 null 键和 null 倹{它也比 HashMap 慢,因ؓ它是同步的?<br /> <br /> <font color="red">W六QCollection ?Collections的区别?/font> <br /> Collections是个java.util下的c,它包含有各种有关集合操作的静态方法?<br /> Collection是个java.util下的接口Q它是各U集合结构的父接口?<br /> <br /> <font color="red">W七Q什么时候用assert?</font><br /> 断言是一个包含布表辑ּ的语句,在执行这个语句时假定该表辑ּ?true。如果表辑ּ计算?falseQ那么系l会报告一?Assertionerror。它用于调试目的Q?<br /> assert(a > 0); // throws an Assertionerror if a <= 0 <br /> 断言可以有两UŞ式: <br /> assert Expression1 ; <br /> assert Expression1 : Expression2 ; <br /> Expression1 应该L产生一个布倹{?<br /> Expression2 可以是得Z个值的L表达式。这个值用于生成显C更多调试信息的 String 消息?<br /> 断言在默认情况下是禁用的。要在编译时启用断言Q需要?source 1.4 标记Q?<br /> javac -source 1.4 Test.java <br /> 要在q行时启用断aQ可使用 -enableassertions 或?-ea 标记?<br /> 要在q行旉择用断言Q可使用 -da 或?-disableassertions 标记?<br /> 要系l类中启用断aQ可使用 -esa 或?-dsa 标记。还可以在包的基上启用或者禁用断a?<br /> 可以在预计正常情况下不会到达的Q何位|上攄断言。断a可以用于验证传递给U有Ҏ的参数。不q,断言不应该用于验证传递给公有Ҏ的参敎ͼ因ؓ不管是否启用了断aQ公有方法都必须查其参数。不q,既可以在公有Ҏ中,也可以在非公有方法中利用断言试后置条g。另外,断言不应该以M方式改变E序的状态?<br /> <br /> <font color="red">W八QGC是什? Z么要有GC? (基础)?/font><br /> <br /> GC是垃圾收集器。Java E序员不用担心内存管理,因ؓ垃圾攉器会自动q行理。要h垃圾攉Q可以调用下面的Ҏ之一Q?<br /> System.gc() <br /> Runtime.getRuntime().gc() <br /> <br /> <font color="red">W九QString s = new String("xyz");创徏了几个String Object? </font><br /> <br /> 两个对象Q一个是“xyx”,一个是指向“xyx”的引用对象s?<br /> <br /> <font color="red">W十QMath.round(11.5){於多少? Math.round(-11.5){於多少? </font><br /> <br /> Math.round(11.5)q回QlongQ?2QMath.round(-11.5)q回QlongQ?11; <br /> <br /> <font color="red">W十一Qshort s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错? </font><br /> <br /> short s1 = 1; s1 = s1 + 1;有错Qs1是short型,s1+1是int?不能昑ּ转化为short型。可修改为s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正确?<br /> <br /> <font color="red">W十二,sleep() ?wait() 有什么区? 搞线E的最?</font><br /> sleep()Ҏ是ɾU程停止一D|间的Ҏ。在sleep 旉间隔期满后,U程不一定立x复执行。这是因为在那个时刻Q其它线E可能正在运行而且没有被调度ؓ攑ּ执行Q除?a)“醒来”的线E具有更高的优先U?<br /> (b)正在q行的线E因为其它原因而阻塞?<br /> wait()是线E交互时Q如果线E对一个同步对象x 发出一个wait()调用Q该U程会暂停执行,被调对象q入{待状态,直到被唤醒或{待旉到?<br /> <br /> <font color="red">W十三,Java有没有goto? </font><br /> Goto java中的保留字,现在没有在java中用?<br /> <br /> <font color="red">W十四,数组有没有length()q个Ҏ? String有没有length()q个ҎQ?/font> <br /> <br /> 数组没有length()q个ҎQ有length的属性?<br /> String有有length()q个Ҏ?<br /> <br /> <font color="red">W十五,Overload和Override的区别。Overloaded的方法是否可以改变返回值的cd? </font><br /> <br /> Ҏ的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父cM子类之间多态性的一U表玎ͼ重蝲Overloading是一个类中多态性的一U表现。如果在子类中定义某Ҏ与其父类有相同的名称和参敎ͼ我们说该Ҏ被重?(Overriding)。子cȝ对象使用q个ҎӞ调用子cM的定义,对它而言Q父cM的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参C数或有不同的参数cdQ则UCؓҎ的重?Overloading)。Overloaded的方法是可以改变q回值的cd?<br /> <br /> <font color="red">W十六,Set里的元素是不能重复的Q那么用什么方法来区分重复与否? 是用==q是equals()? 它们有何区别? </font><br /> <br /> Set里的元素是不能重复的Q那么用iterator()Ҏ来区分重复与否。equals()是判M个Set是否相等?<br /> equals()?=Ҏ军_引用值是否指向同一对象equals()在类中被覆盖Qؓ的是当两个分ȝ对象的内容和cd盔R的话Q返回真倹{?<br /> <br /> <font color="red">W十七,l我一个你最常见到的runtime exception?/font> <br /> ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, <br /> ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFORMatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException  <a >190-802</a> <a >000-834</a> <a >000-861</a> <a >117-102</a> <a >117-301</a> <a >190-721</a><br /> <br /> <font color="red">W十八,error和exception有什么区? </font><br /> error 表示恢复不是不可能但很困隄情况下的一U严重问题。比如说内存溢出。不可能指望E序能处理这L情况?<br /> exception 表示一U设计或实现问题。也是_它表C如果程序运行正常,从不会发生的情况?<br /> <br /> <font color="red">W十九,List, Set, Map是否l承自Collection接口? </font><br /> ListQSet?<br /> <br /> Map不是 <br /> <br /> <font color="red">W二十,abstract class和interface有什么区? </font><br /> <br /> 声明Ҏ的存在而不d现它的类被叫做抽象类Qabstract classQ,它用于要创徏一个体现某些基本行为的c,qؓ该类声明ҎQ但不能在该cM实现该类的情c不能创建abstract cȝ实例。然而可以创Z个变量,其类型是一个抽象类Qƈ让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract cȝ子类为它们父cM的所有抽象方法提供实玎ͼ否则它们也是抽象cMؓ。取而代之,在子cM实现该方法。知道其行ؓ的其它类可以在类中实现这些方法?<br /> 接口QinterfaceQ是抽象cȝ变体。在接口中,所有方法都是抽象的。多l承性可通过实现q样的接口而获得。接口中的所有方法都是抽象的Q没有一个有E序体。接口只可以定义static final成员变量。接口的实现与子cȝ|除了该实现类不能从接口定义中l承行ؓ。当cd现特D接口时Q它定义Q即程序体l予Q所有这U接口的Ҏ。然后,它可以在实现了该接口的类的Q何对象上调用接口的方法。由于有抽象c,它允怋用接口名作ؓ引用变量的类型。通常的动态联~将生效。引用可以{换到接口cd或从接口cd转换Qinstanceof q算W可以用来决定某对象的类是否实现了接口?<br /> <br /> <font color="red">W二十一Qabstract的method是否可同时是static,是否可同时是nativeQ是否可同时是synchronized? </font><br /> <br /> 都不?<br /> <br /> <font color="red">W二十二Q接口是否可l承接口? 抽象cL否可实现(implements)接口? 抽象cL否可l承实体c?concrete class)? </font><br /> 接口可以l承接口。抽象类可以实现(implements)接口Q抽象类是否可承实体类Q但前提是实体类必须有明的构造函数?<br /> <br /> <font color="red">W二十三Q启动一个线E是用run()q是start()? </font><br /> 启动一个线E是调用start()ҎQɾU程所代表的虚拟处理机处于可运行状态,q意味着它可以由JVM调度q执行。这q不意味着U程׃立即q行。run()Ҏ可以产生必须退出的标志来停止一个线E?<br /> <br /> <font color="red">W二十四Q构造器Constructor是否可被override? </font>构造器Constructor不能被承,因此不能重写OverridingQ但可以被重载Overloading?<br /> <br /> <font color="red">W二十五Q是否可以承Stringc? </font><br /> StringcLfinalcL不可以ѝ?<br /> <br /> <font color="red">W二十六Q当一个线E进入一个对象的一个synchronizedҎ后,其它U程是否可进入此对象的其它方? </font><br /> 不能Q一个对象的一个synchronizedҎ只能׃个线E访问?<br /> <br /> <font color="red">W二十七Qtry {}里有一个return语句Q那么紧跟在q个try后的finally {}里的code会不会被执行Q什么时候被执行Q在return前还是后? </font><br /> <br /> 会执行,在return前执行?<br /> <br /> <font color="red">W二十八Q编E题: 用最有效率的Ҏ出2乘以8{於? </font><br /> <br /> 有C背景的程序员特别喜欢问这U问题?<br /> <br /> 2 << 3 <br /> <br /> <font color="red">W二十九Q两个对象值相?x.equals(y) == true)Q但却可有不同的hash codeQ这句话对不? </font><br /> 不对Q有相同的hash code?<br /> <br /> <font color="red">W三十,当一个对象被当作参数传递到一个方法后Q此Ҏ可改变这个对象的属性,q可q回变化后的l果Q那么这里到底是g递还是引用传? </font><br /> <br /> 是g递。Java ~程语言只由g递参数。当一个对象实例作Z个参数被传递到Ҏ中时Q参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变Q但对象的引用是永远不会改变的?<br /> <br /> <font color="red">W三十一Qswtich是否能作用在byte上,是否能作用在long上,是否能作用在String? </font><br /> <br /> switchQexpr1Q中Qexpr1是一个整数表辑ּ。因此传递给 switch ?case 语句的参数应该是 int?short?char 或?byte。long,string 都不能作用于swtich?<br /> <br /> <font color="red">W三十二Q编E题: 写一个Singleton出来?/font><br /> <br /> Singleton模式主要作用是保证在Java应用E序中,一个类Class只有一个实例存在?<br /> 一般Singleton模式通常有几U种形式: <br /> W一UŞ? 定义一个类Q它的构造函Cؓprivate的,它有一个static的private的该cd量,在类初始化时实例话,通过一个public的getInstanceҎ获取对它的引?l而调用其中的Ҏ?<br /> public class Singleton { <br />   private Singleton(){} <br />   //在自己内部定义自׃个实例,是不是很奇怪? <br />   //注意q是private 只供内部调用 <br />   private static Singleton instance = new Singleton(); <br />   //q里提供了一个供外部讉K本class的静态方法,可以直接讉K   <br />   public static Singleton getInstance() { <br />     return instance;    <br />    } <br /> } <br /> W二UŞ? <br /> public class Singleton { <br />   private static Singleton instance = null; <br />   public static synchronized Singleton getInstance() { <br />   //q个Ҏ比上面有所改进Q不用每ơ都q行生成对象Q只是第一ơ      <br />   //使用时生成实例,提高了效率! <br />   if (instance==null) <br />     instanceQnew Singleton(); <br /> return instance;   } <br /> } <br /> 其他形式: <br /> 定义一个类Q它的构造函Cؓprivate的,所有方法ؓstatic的?<br /> 一般认为第一UŞ式要更加安全?<br /> <br /> <font color="red">W三十三 Hashtable和HashMap </font><br /> Hashtablel承自Dictionaryc,而HashMap是Java1.2引进的Map interface的一个实?<br /> <br /> HashMap允许null作ؓ一个entry的key或者valueQ而Hashtable不允?<br /> <br /> q有是QHashMap把Hashtable的containsҎL了,Ҏcontainsvalue和containsKey。因为containsҎҎ让h引v?strong></strong>解?<br /> <br /> 最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是Q在 <br /> 多个U程讉KHashtableӞ不需要自׃ؓ它的Ҏ实现同步Q而HashMap <br /> 必Mؓ之提供外同步?<br /> <br /> Hashtable和HashMap采用的hash/rehash法都大概一P所以性能不会有很大的差异? <img src ="http://www.tkk7.com/yjjlovewjf/aggbug/172609.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/yjjlovewjf/" target="_blank">wǒ愛伱--咑֩ </a> 2008-01-03 23:40 <a href="http://www.tkk7.com/yjjlovewjf/archive/2008/01/03/172609.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于static变量对于内存分配的实际验?..http://www.tkk7.com/yjjlovewjf/archive/2007/12/20/169151.htmlwǒ愛伱--咑֩ wǒ愛伱--咑֩ Thu, 20 Dec 2007 13:07:00 GMThttp://www.tkk7.com/yjjlovewjf/archive/2007/12/20/169151.htmlhttp://www.tkk7.com/yjjlovewjf/comments/169151.htmlhttp://www.tkk7.com/yjjlovewjf/archive/2007/12/20/169151.html#Feedback3http://www.tkk7.com/yjjlovewjf/comments/commentRss/169151.htmlhttp://www.tkk7.com/yjjlovewjf/services/trackbacks/169151.htmlpublic class Num
{
    
static Integer i = new Integer(520);
};
public class Demo
{
        
public static void main(String[] args)
        {
            Num demo1 
= new Num();
            Num demo2 
= new Num();
            
if (demo1.i == demo2.i)
            {
                System.out.println(
"ture");
            }
            
else
            {
                System.out.println(
"false");
            }

        }
    
}

输出?true!表明demo1.i和demo2.i只有一分存储空?虽然new了两个对?但只有一份存储空?
public class Num
{
    Integer i 
= new Integer(520);
};

public class Demo
{
        
public static void main(String[] args)
        {
            Num demo1 
= new Num();
            Num demo2 
= new Num();
            
if (demo1.i == demo2.i)
            {
                System.out.println(
"ture");
            }
            
else
            {
                System.out.println(
"false");
            }

        }
    
}

输出为false
关于static变量或方?.只会创徏一份空?.无论是否有对象去引用..
下面是更深入的说?!!
public class Num
{
 
static Integer i = new Integer(520);
 Integer j 
= new Integer(520);
}

public class Demo
{
        
public static void main(String[] args)
        {
            Num demo1 
= new Num();
            Num demo2 
= new Num();
            
if (demo1.i == demo2.i)
            {
                System.out.println(
"ture");
            }
            
else
            {
                System.out.println(
"false");
            }
            
if (demo1.j == demo2.j)
            {
                System.out.println(
"ture");
            }
            
else
            {
                System.out.println(
"false");
            }
            System.out.println(Num.i);

        }
    
}

下面一个例?
public class F1
{
    
public static void main(String[] args)
    {
        Integer i 
= new Integer(10);
        Integer j 
= new Integer(10);
        
int k = 20;
        
int l = 20;
        System.out.println(k 
==l);
        System.out.println(i 
== j);
    }
};
上面的例 子表?对于通过new创徏的两个对象的引用i&j,他们所引用的值都相同?0.但是,两个10存储在不同的两个地方,两个引用不同?....
上面?子的l果?
ture
false


wǒ愛伱--咑֩ 2007-12-20 21:07 发表评论
]]>
Java初学者容易؜淆的几个问题详细解析 --?/title><link>http://www.tkk7.com/yjjlovewjf/archive/2007/12/09/166449.html</link><dc:creator>wǒ愛伱--咑֩ </dc:creator><author>wǒ愛伱--咑֩ </author><pubDate>Sun, 09 Dec 2007 07:16:00 GMT</pubDate><guid>http://www.tkk7.com/yjjlovewjf/archive/2007/12/09/166449.html</guid><wfw:comment>http://www.tkk7.com/yjjlovewjf/comments/166449.html</wfw:comment><comments>http://www.tkk7.com/yjjlovewjf/archive/2007/12/09/166449.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/yjjlovewjf/comments/commentRss/166449.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/yjjlovewjf/services/trackbacks/166449.html</trackback:ping><description><![CDATA[<div id="dbf7rtj" class="postText">Q?StringcdStringBufferc?<br /> <br /> <br /> 它们都是处理字符串的c?但是它们有一个最大的区别,那就?String对象是存储你不能改动的文本字W串,相反,如果你希望改?则应使用StringBuffercM为替? <br /> <br /> <br /> eg1: <br /> <br />    ...... <br /> <br />    //omit some code <br /> <br />    String s1="You are hired!"; <br /> <br />    System.out.println(s1.replace(h,f));//用f把字串中的h替换?<br /> <br />    System.out.println(s1); <br /> <br />    ...... <br /> <br />    //omit some code <br /> <br />    q行l果: <br /> <br />    You are fired! <br /> <br />    You are hired! <br />    l果分析: <br /> <br />    从结?明显可知,s1的值ƈ没有被改?而第一行结果只是屏q内容的替换. <br /> <br />    eg2: <br /> <br />    ...... <br /> <br />    //omit some code <br /> <br />    StringBuffer s2=new StringBuffer("Hello from Java!"); <br /> <br />    s2.replace(6,10,"to"); <br /> <br />    System.out.println(s2); <br /> <br />    ...... <br /> <br />    //omit some code<br /> <br /> <br />    <br /> <br /> q行l果: <br /> <br /> Hello to Java! <br /> <br /> l果分析: <br /> <br /> 昄,s2的值已改变. <br /> <br /> <br /> Q?位逻辑与条仉辑 <br /> <br /> <br /> 首先声明, Z与位逻辑更好区分开?我把通常所说的逻辑取了个别名叫做条仉辑. <br /> <br /> <br /> 它们都有各自的操作符,位逻辑操作W有:&(与运?,^(异或q算),|(或运?;条g逻辑操作W有:&&(q且),||(或?. <br /> <br /> 位逻辑q算通常是针对两个数而言,实行位操?而条仉辑q算是针对两个条件表辑ּ而言,实行条g操作.其实,位逻辑操作W一样可以实现条件操?但是此时有一个重要的区别:用位操作W时,不管操作W两边的 <br /> <br /> 条g表达式成不成?它都要通通进行运判?而条仉辑操作W不一样了,如果通过左侧的操作数可以进行它们需要的判断,那么它就不会再计右侧的操作C,q种情况叫短?废话说!且看下例. <br /> <br /> <br /> eg1: <br /> <br />    ...... <br /> <br />    //omit some code <br /> <br />    double value=0; <br /> <br />    if(value!=0 && 1/value<1000){ <br /> <br />    System.out.println("The value is not too small."); <br /> <br />    } <br /> <br />    else{ <br /> <br />    System.out.println("The value is too small."); <br /> <br />    } <br /> <br />    ...... <br /> <br />    //omit some code<br /> <br /> <br />    <br /> <br /> q行l果: <br /> <br /> The value is too small. <br /> <br /> l果分析: <br /> <br /> 照理说应会出现除Cؓ0的错?但是我刚才说?׃条g逻辑操作W是短\操作W?昄,value!=0不成?立即可作出判断应执行else后的语句,所以它׃再会q算判断1/value<1000?如果不懂请再看一? <br /> <br /> <br /> eg2: <br /> <br />    ...... <br /> <br />    //omit some code <br /> <br />    double int1=0,int2=1,int3=1; <br /> <br />    if(int1!=0 & (int2=2)==1){} <br /> <br />    System.out.println("int2="+int2); <br /> <br />    if(int1!=0 && (int3=2)==1){} <br /> <br />    System.out.println("int3="+int3); <br /> <br />    ...... <br /> <br />    //omit some code<br /> <br /> <br /> q行l果: <br /> <br /> int2=2.0 <br /> <br /> int3=1.0 <br /> <br /> l果分析: <br /> <br /> 我想不用我分析了,你应该懂了吧.<br /> <br /> <br /> <br /> <br /> Q?实例变量与类变量 <br /> <br /> 可以通过两种Ҏ在类中存储数据───作ؓ实例变量和类变量.实例变量是特定于对象?如果你有两个对象(即一个类的两个实?,每一个对象中的实例变量独立于另一个对象中的实例变量的;另一斚w,两个对象的类变量均指向相同的数据,q因此面保存相同的?换句话说,cd量被cM的所有对象共?差点忘了,它们在Ş式上的区?cd量在声明时比实例变量多一个static. <br /> <br /> <br /> eg: <br /> <br />    class data <br /> <br />    public int intdata=0;//昄,intdata在这儿是实例变量 <br /> <br />    } <br /> <br />    public class exam <br /> <br />    { <br /> <br />    public static void main(String[] args) <br /> <br />    { <br /> <br />    data a,b; <br /> <br />    a=new data(); <br /> <br />    b=new data(); <br /> <br />    a.intdata=1; <br /> <br />    System.out.println("b.indata="+b.intdata); <br /> <br />    } <br /> <br />    }<br /> <br /> <br /> q行l果: <br /> <br /> b.intdata=0 <br /> <br /> l果分析: <br /> <br /> 可以看出,a.intdata的D然变?但ƈ没有影响b.intdata.但是如果在datacM声明intdata?在其前面加上static变成类变量??public static int intdata=0;),则此时运行结果会变ؓ: <br /> <br /> b.intdata=1 <br /> <br /> q次a.intdata值的改变可把b.intdata影响?事实?对象a和b的类变量均指向相同的数据,所有g?q就是类变量的作? <br /> <br /> <br /> Q?实例Ҏ,cL?构造器Ҏ <br /> <br /> <br /> 我们通常所说的ҎpL实例Ҏ,像c语言中的函数一?其具体方法我׃用说?在这里我主要是用它来区分cL法和构造器Ҏ.cL法与实例Ҏ最大的区别?在Ş式上cL法多一个static,在用法上,不必创徏对象可直接调用cL?而实例方法却一定要先创建对?再通过对象调用). <br /> <br /> <br /> eg: <br /> <br />    class add <br /> <br />    { <br /> <br />    static int addem(int op1,int op2) <br /> <br />    { <br />    return op1+op2; <br /> <br />    } <br /> <br />    } <br /> <br />    public class xxf <br /> <br />    { <br /> <br />    public static void main(String[] args) <br /> <br />    { <br /> <br />    System.out.println("addem(2,2)="+add.addem(2,2)); <br /> <br />    } //直接用类名作为对象调用类Ҏ <br /> <br />    }<br /> <br /> <br />    <br /> <br /> ? 也可按通常的方?卛_创徏对象,再调用方?不过,q时static无M意义? <br /> <br /> <br /> 再说说构造器Ҏ,它是用来初始化对象中的数据的一U方?创徏很容?只需在类中加上一个与q个cd名的Ҏ,不需要在前面加Q何访问说明符或者返回类?另外,构造器也一样可以向Ҏ一样传递参? <br /> <br /> <br /> eg: <br /> <br />   class data <br /> <br />    { <br /> <br />    private String data1;//事先声明 <br />    data(String s) <br /> <br />    { <br /> <br />    data1=s; /*通过接收数据来初始化变量.(?不能在构造器?<br /> <br />    声明变量,事先在外p声明.)*/ <br /> <br />    } <br /> <br />    public String getdata() <br /> <br />    { <br /> <br />    return data1; <br /> <br />    } <br /> <br />    } <br /> <br />    public class xxf <br /> <br />    { <br /> <br />    public static void main(String[] args) <br /> <br />    { <br /> <br />    System.out.println((new data("I love you")).getdata());<br /> /*通过传递参数调用构造器新徏一个对?再通过对象调用Ҏ得到数据*/ <br /> <br />    } <br /> <br />    }<br /> <br /> <br /> Q?接口与类 <br /> <br /> cL对一cȝ定对象的规格说明,我们可以cd义创建对?通过创徏对象来组合所有属于该cȝlg,而接口不能这样做.而接口实质上是一个常量和抽象Ҏ的集?要用一个接?需要在cM实现q个接口,然后作ؓcd义的一部分,~写接口中声明的每一个方?接口中的Ҏ永远是public,abstract,接口中的帔R永远是public static和final,因此不需要ؓ它们说明属?因ؓ在Java中不支持多重l承,但是,可以用接口来实现cM的功?q是接口的重要作用之一. <br /> <br /> <br /> eg: <br /> <br />    interface anyone //定义一个接?<br /> <br />    { <br /> <br />    final double PI=3.1416; <br /> <br />    void setNumber(int number); <br /> <br />    int getNumber(); <br /> <br />    } <br /> <br />    interface anyother //定义另一个接?<br /> <br />    { <br /> <br />    void setString(String str); <br /> <br />    String getString(); <br /> <br />    } <br /> <br />    class xxf implement anyone,anyother //定义一个类,q用两个接?<br /> <br />    { <br /> <br />    int number; <br /> <br />    String str; <br /> <br />    public xxf(){} <br /> <br />    void setNumber(int number) <br /> <br />    { <br /> <br />    this.number=number; <br /> <br />    } <br /> <br />    void setString(String str) <br /> <br />    { <br /> <br />    this.str=str; <br /> <br />    } <br /> <br />    void int getNumber(){}//可以Z个空实现. <br /> <br />    void String getString(){} <br /> <br />    }<br /> <br /> <br /> //在类中必d现接口中声明的所有方?(当然也可不必,但是要用到适配器类或用抽象c?<br /> </div> <img src ="http://www.tkk7.com/yjjlovewjf/aggbug/166449.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/yjjlovewjf/" target="_blank">wǒ愛伱--咑֩ </a> 2007-12-09 15:16 <a href="http://www.tkk7.com/yjjlovewjf/archive/2007/12/09/166449.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>this与super的应?--?/title><link>http://www.tkk7.com/yjjlovewjf/archive/2007/12/09/166442.html</link><dc:creator>wǒ愛伱--咑֩ </dc:creator><author>wǒ愛伱--咑֩ </author><pubDate>Sun, 09 Dec 2007 06:50:00 GMT</pubDate><guid>http://www.tkk7.com/yjjlovewjf/archive/2007/12/09/166442.html</guid><wfw:comment>http://www.tkk7.com/yjjlovewjf/comments/166442.html</wfw:comment><comments>http://www.tkk7.com/yjjlovewjf/archive/2007/12/09/166442.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/yjjlovewjf/comments/commentRss/166442.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/yjjlovewjf/services/trackbacks/166442.html</trackback:ping><description><![CDATA[<div id="bbf7bdf" class="postText">通过用static来定义方法或成员Qؓ我们~程提供了某U便利,从某U程度上可以说它cM于C语言中的全局函数和全局变量。但是,q不是说有了q种便利Q你便可以随处用,如果那样的话Q你侉K要认真考虑一下自己是否在用面向对象的思想~程Q自qE序是否是面向对象的。好了,现在开始讨论this&superq两个关键字的意义和用法?br />   在Java中,this通常指当前对象,super则指父类的。当你想要引用当前对象的某种东西Q比如当前对象的某个ҎQ或当前对象的某个成员,你便可以利用this来实现这个目的,当然Qthis的另一个用途是调用当前对象的另一个构造函敎ͼq些马上p讨论。如果你惛_用父cȝ某种东西Q则非super莫属。由于this与super有如此相似的一些特性和与生俱来的某U关p,所以我们在q一块儿来讨论,希望能帮助你区分和掌握它们两个?br />   在一般方法中<br />   最普遍的情况就是,在你的方法中的某个Ş参名与当前对象的某个成员有相同的名字Q这时ؓ了不至于hQ你侉K要明用this关键字来指明你要使用某个成员Q用方法是“this.成员?#8221;Q而不带this的那个便是Ş参。另外,q可以用“this.Ҏ?#8221;来引用当前对象的某个ҎQ但q时this׃是必ȝ了,你可以直接用Ҏ名来讉K那个ҎQ编译器会知道你要调用的是那一个。下面的代码演示了上面的用法Q?br /> public class DemoThis<br /> { <br /> private String name; <br /> private int age; <br /> DemoThis(String name,int age){  <br /> setName(name); <br /> //你可以加上this来调用方法,像这Pthis.setName(name);但这q不是必ȝ  <br /> setAge(age);  <br /> this.print(); br> }   <br /> public void setName(String name){  <br /> this.name=name;//此处必须指明你要引用成员变量 <br /> } <br /> public void etAge(int age){  <br /> this.age=age; <br /> } <br /> public void print(){  <br /> System.out.println("Name="+name+" ge="+age);<br /> //在此行中q不需要用thisQ因为没有会Dh的东ѝ<br /> } <br /> public static void main(String[] args){  <br /> DemoThis dt=new DemoThis("Kevin","22");<br />   q段代码很简单,不用解释你也应该能看明白。在构造函C你看到用this.print(),你完全可以用print()来代替它Q两者效果一栗下面我们修改这个程序,来演Csuper的用法?br /> <div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #0000ff">class</span><span style="color: #000000"> Person<br /> { <br />     </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">int</span><span style="color: #000000"> c; <br />     </span><span style="color: #0000ff">private</span><span style="color: #000000"> String name; <br />     </span><span style="color: #0000ff">private</span><span style="color: #000000"> </span><span style="color: #0000ff">int</span><span style="color: #000000"> age; <br />     </span><span style="color: #0000ff">protected</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> setName(String name)<br />     {  <br />         </span><span style="color: #0000ff">this</span><span style="color: #000000">.name</span><span style="color: #000000">=</span><span style="color: #000000">name; <br />     } <br />     </span><span style="color: #0000ff">protected</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> setAge(</span><span style="color: #0000ff">int</span><span style="color: #000000"> age)<br />     {  <br />         </span><span style="color: #0000ff">this</span><span style="color: #000000">.age</span><span style="color: #000000">=</span><span style="color: #000000">age;<br />      } <br />     </span><span style="color: #0000ff">protected</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> print()<br />     {  <br />         System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">Name=</span><span style="color: #000000">"</span><span style="color: #000000">+</span><span style="color: #000000">name</span><span style="color: #000000">+</span><span style="color: #000000">"</span><span style="color: #000000"> Age=</span><span style="color: #000000">"</span><span style="color: #000000">+</span><span style="color: #000000">age); <br />     }<br /> }<br /> </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">class</span><span style="color: #000000"> DemoSuper </span><span style="color: #0000ff">extends</span><span style="color: #000000"> Person<br /> { <br />     </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> print()<br />     {  <br />     System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">DemoSuper:</span><span style="color: #000000">"</span><span style="color: #000000">);  <br />     </span><span style="color: #0000ff">super</span><span style="color: #000000">.print(); <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 />     {  <br />         DemoSuper ds</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000"> DemoSuper();  <br />         ds.setName(</span><span style="color: #000000">"</span><span style="color: #000000">kevin</span><span style="color: #000000">"</span><span style="color: #000000">);  <br />         ds.setAge(</span><span style="color: #000000">22</span><span style="color: #000000">);  <br />         ds.print(); <br />     }<br /> }</span></div> <br />   在DemoSuper中,重新定义的printҎ覆写了父cȝprintҎQ它首先做一些自q事情Q然后调用父cȝ那个被覆写了的方法。输出结果说明了q一点:<br />   DemoSuper:<br /> Name=kevin Age=22<br /> <br />   q样的用方法是比较常用的。另外如果父cȝ成员可以被子c访问,那你可以像用this一样用它Q用“super.父类中的成员?#8221;的方式,但常怽q不是这h讉K父类中的成员名的?br />   在构造函C构造函数是一U特D的ҎQ在对象初始化的时候自动调用。在构造函CQthis和super也有上面说的U种使用方式Qƈ且它q有Ҏ的地方,L下面的例子:<br /> <br />   <br /> class Person{ <br /> <br /> public static void prt(String s){  <br /> System.out.println(s); <br /> } <br /> Person(){  <br /> prt("A Person."); <br /> } <br /> Person(String name){ <br />  prt("A person name is:"+name); <br /> <br /> }<br /> }<br /> public class Chinese extends Person{<br />  Chinese(){  <br /> super(); //调用父类构造函敎ͼ1Q  <br /> prt("A chinese.");//(4) <br /> } <br /> Chinese(String name){  <br /> super(name);//调用父类h相同形参的构造函敎ͼ2Q  <br /> prt("his name is:"+name); <br /> } <br /> Chinese(String name,int age){  <br /> this(name);//调用当前h相同形参的构造函敎ͼ3Q  <br /> prt("his age is:"+age); <br /> } <br /> public static void main(String[] args){  <br /> Chinese cn=new Chinese();  <br /> cn=new Chinese("kevin");  <br /> cn=new Chinese("kevin",22); <br /> }<br /> }<br />   在这D늨序中Qthis和super不再是像以前那样?#8220;.”q接一个方法或成员Q而是直接在其后跟<br />   上适当的参敎ͼ因此它的意义也就有了变化。super后加参数的是用来调用父类中具有相同Ş式的<br />   构造函敎ͼ??处。this后加参数则调用的是当前具有相同参数的构造函敎ͼ?处。当Ӟ?br />   Chinese的各个重载构造函CQthis和super在一般方法中的各U用法也仍可使用Q比?处,?br />   可以它替换?#8220;this.prt”(因ؓ它承了父类中的那个ҎQ或者是“super.prt”Q因为它<br />   是父cM的方法且可被子类讉KQ,它照样可以正运行。但q样g有点画蛇添的味道<br />   了?br />   最后,写了q么多,如果你能?#8220;this通常指代当前对象Qsuper通常指代父类”q句话牢记在<br />   心,那么本篇便达C目的Q其它的你自会在以后的编E实践当中慢慢体会、掌握?</div> <img src ="http://www.tkk7.com/yjjlovewjf/aggbug/166442.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/yjjlovewjf/" target="_blank">wǒ愛伱--咑֩ </a> 2007-12-09 14:50 <a href="http://www.tkk7.com/yjjlovewjf/archive/2007/12/09/166442.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>理解Java ClassLoader机制 --?/title><link>http://www.tkk7.com/yjjlovewjf/archive/2007/12/09/166418.html</link><dc:creator>wǒ愛伱--咑֩ </dc:creator><author>wǒ愛伱--咑֩ </author><pubDate>Sun, 09 Dec 2007 03:32:00 GMT</pubDate><guid>http://www.tkk7.com/yjjlovewjf/archive/2007/12/09/166418.html</guid><wfw:comment>http://www.tkk7.com/yjjlovewjf/comments/166418.html</wfw:comment><comments>http://www.tkk7.com/yjjlovewjf/archive/2007/12/09/166418.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/yjjlovewjf/comments/commentRss/166418.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/yjjlovewjf/services/trackbacks/166418.html</trackback:ping><description><![CDATA[当JVMQJava虚拟机)启动Ӟ会Ş成由三个cd载器l成的初始类加蝲器层ơ结构:<br /> <br />        bootstrap classloader<br />                 |<br />        extension classloader<br />                 |<br />        system classloader<br /> <br /> bootstrap classloader Q引|也称为原始)cd载器Q它负责加蝲Java的核心类。在Sun的JVM中,在执行java的命令中使用-Xbootclasspath选项或?- D选项指定sun.boot.class.pathpȝ属性值可以指定附加的cR这个加载器的是非常Ҏ的,它实际上不是 java.lang.ClassLoader的子c,而是由JVM自n实现的。大家可以通过执行以下代码来获得bootstrap classloader加蝲了那些核心类库:<br />         URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();<br />         for (int i = 0; i < urls.length; i++) {<br />             System.out.println(urls[i].toExternalForm());<br />         }<br /> 在我的计机上的l果为:<br /> 文g:/C:/j2sdk1.4.1_01/jre/lib/endorsed/dom.jar<br /> 文g:/C:/j2sdk1.4.1_01/jre/lib/endorsed/sax.jar<br /> 文g:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xalan-2.3.1.jar<br /> 文g:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xercesImpl-2.0.0.jar<br /> 文g:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xml-apis.jar<br /> 文g:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xsltc.jar<br /> 文g:/C:/j2sdk1.4.1_01/jre/lib/rt.jar<br /> 文g:/C:/j2sdk1.4.1_01/jre/lib/i18n.jar<br /> 文g:/C:/j2sdk1.4.1_01/jre/lib/sunrsasign.jar<br /> 文g:/C:/j2sdk1.4.1_01/jre/lib/jsse.jar<br /> 文g:/C:/j2sdk1.4.1_01/jre/lib/jce.jar<br /> 文g:/C:/j2sdk1.4.1_01/jre/lib/charsets.jar<br /> 文g:/C:/j2sdk1.4.1_01/jre/classes<br /> q时大家知道了ؓ什么我们不需要在pȝ属性CLASSPATH中指定这些类库了吧,因ؓJVM在启动的时候就自动加蝲它们了?br /> <br /> extension classloader Q扩展类加蝲器,它负责加载JRE的扩展目录(JAVA_HOME/jre/lib/ext或者由java.ext.dirspȝ属性指定的Q中JAR的类包。这为引入除Java核心cM外的新功能提供了一个标准机制。因为默认的扩展目录Ҏ有从同一个JRE中启动的JVM都是通用的,所以放入这个目录的 JARcdҎ有的JVM和system classloader都是可见的。在q个实例上调用方法getParent()Lq回I值nullQ因为引导加载器bootstrap classloader不是一个真正的ClassLoader实例。所以当大家执行以下代码Ӟ<br />    System.out.println(System.getProperty("java.ext.dirs"));<br />    ClassLoader extensionClassloader=ClassLoader.getSystemClassLoader().getParent();<br />    System.out.println("the parent of extension classloader : "+extensionClassloader.getParent());<br /> l果为:<br /> C:\j2sdk1.4.1_01\jre\lib\ext<br /> the parent of extension classloader : null<br /> extension classloader是system classloader的parentQ而bootstrap classloader是extension classloader的parentQ但它不是一个实际的classloaderQ所以ؓnull?br /> <br /> system classloader Q系l(也称为应用)cd载器Q它负责在JVM被启动时Q加载来自在命ojava中的-classpath或者java.class.pathpȝ属性或?CLASSPATH*作系l属性所指定的JARcd和类路径。总能通过静态方法ClassLoader.getSystemClassLoader()扑ֈ该类加蝲器。如果没有特别指定,则用戯定义的Q何类加蝲器都该cd载器作ؓ它的父加载器。执行以下代码即可获得:<br />    System.out.println(System.getProperty("java.class.path"));<br /> 输出l果则ؓ用户在系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 /> <br /> 每个ClassLoader加蝲Class的过E是Q?br /> 1.此Class是否载入q(卛_cache中是否有此ClassQ,如果有到8,如果没有?<br /> 2.如果parent classloader不存在(没有parentQ那parent一定是bootstrap classloader了)Q到4<br /> 3.hparent classloader载入Q如果成功到8Q不成功?<br /> 4.hjvm从bootstrap classloader中蝲入,如果成功?<br /> 5.LClass文gQ从与此classloader相关的类路径中寻找)。如果找不到则到7.<br /> 6.从文件中载入ClassQ到8.<br /> 7.抛出ClassNotFoundException.<br /> 8.q回Class.<br /> <br /> 其中5.6步我们可以通过覆盖ClassLoader的findClassҎ来实现自q载入{略。甚臌盖loadClassҎ来实现自q载入q程?br /> <br /> cd载器的顺序是Q?br /> 先是bootstrap classloaderQ然后是extension classloaderQ最后才是system classloader。大家会发现加蝲的Class是重要的越在靠前面。这样做的原因是Z安全性的考虑Q试惛_果system classloader“亲自”加蝲了一个具有破坏性的“java.lang.System”cȝ后果吧。这U委托机制保证了用户即h一个这Lc,也把它加入到了类路径中,但是它永q不会被载入Q因个类L由bootstrap classloader来加载的。大家可以执行一下以下的代码Q?br />    System.out.println(System.class.getClassLoader());<br /> 会看到l果是nullQ这p明java.lang.System是由bootstrap classloader加蝲的,因ؓbootstrap classloader不是一个真正的ClassLoader实例Q而是由JVM实现的,正如前面已经说过的?br /> <br /> 下面p我们来看看JVM是如何来为我们来建立cd载器的结构的Q?br /> sun.misc.LauncherQ顾名思义Q当你执行java命o的时候,JVM会先使用bootstrap classloader载入q初始化一个LauncherQ执行下来代码:<br />   System.out.println("the Launcher's classloader is "+sun.misc.Launcher.getLauncher().getClass().getClassLoader());<br /> l果为:<br />   the Launcher's classloader is null (因ؓ是用bootstrap classloader加蝲,所以class loader为null)<br /> Launcher 会根据系l和命o讑֮初始化好class loaderl构QJVMq它来获得extension classloader和system classloader,q蝲入所有的需要蝲入的ClassQ最后执行java命o指定的带有静态的mainҎ的Class。extension classloader实际上是sun.misc.Launcher$ExtClassLoadercȝ一个实例,system classloader实际上是sun.misc.Launcher$AppClassLoadercȝ一个实例。ƈ且都?java.net.URLClassLoader的子cR?br /> <br /> 让我们来看看Launcher初试化的q程的部分代码?br /> <br /> Launcher的部分代码:<br /> public class Launcher  {<br />    public Launcher() {<br />        ExtClassLoader extclassloader;<br />        try {<br />            //初始化extension classloader<br />            extclassloader = ExtClassLoader.getExtClassLoader();<br />        } catch(IOException ioexception) {<br />            throw new InternalError("Could not create extension class loader");<br />        }<br />        try {<br />            //初始化system classloaderQparent是extension classloader<br />            loader = AppClassLoader.getAppClassLoader(extclassloader);<br />        } catch(IOException ioexception1) {<br />            throw new InternalError("Could not create application class loader");<br />        }<br />        //system classloader讄成当前线E的context classloaderQ将在后面加以介l)<br />        Thread.currentThread().setContextClassLoader(loader);<br />        ......<br />    }<br />    public ClassLoader getClassLoader() {<br />        //q回system classloader<br />        return loader;<br />    }<br /> }<br /> <br /> extension classloader的部分代码:<br /> static class Launcher$ExtClassLoader extends URLClassLoader {<br /> <br />    public static Launcher$ExtClassLoader getExtClassLoader()<br />        throws IOException<br />    {<br />        File afile[] = getExtDirs();<br />        return (Launcher$ExtClassLoader)AccessController.doPrivileged(new Launcher$1(afile));<br />    }<br />   private static File[] getExtDirs() {<br />        //获得pȝ属?#8220;java.ext.dirs”<br />        String s = System.getProperty("java.ext.dirs");<br />        File afile[];<br />        if(s != null) {<br />            StringTokenizer stringtokenizer = new StringTokenizer(s, File.pathSeparator);<br />            int i = stringtokenizer.countTokens();<br />            afile = new File;<br />            for(int j = 0; j < i; j++)<br />                afile[j] = new File(stringtokenizer.nextToken());<br /> <br />        } else {<br />            afile = new File[0];<br />        }<br />        return afile;<br />    }<br /> }<br /> <br /> system classloader的部分代码:<br /> static class Launcher$AppClassLoader extends URLClassLoader<br /> {<br /> <br />    public static ClassLoader getAppClassLoader(ClassLoader classloader)<br />        throws IOException<br />    {<br />        //获得pȝ属?#8220;java.class.path”<br />        String s = System.getProperty("java.class.path");<br />        File afile[] = s != null ? Launcher.access$200(s) : new File[0];<br />        return (Launcher$AppClassLoader)AccessController.doPrivileged(new Launcher$2(s, afile, classloader));<br />    }<br /> }<br /> <br /> 看了源代码大家就清楚了吧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讄成ؓcontext classloaderQ但是仅仅返回system classloaderlJVM?br /> <br />   q里怎么又出来一个context classloader呢?它有什么用呢?我们在徏立一个线EThread的时候,可以个线E通过setContextClassLoaderҎ来指定一个合适的classloader作ؓq个U程的context classloaderQ当此线E运行的时候,我们可以通过getContextClassLoaderҎ来获得此context classloaderQ就可以用它来蝲入我们所需要的Class。默认的是system classloader。利用这个特性,我们可以“打破”classloader委托机制了,父classloader可以获得当前U程的context classloaderQ而这个context classloader可以是它的子classloader或者其他的classloaderQ那么父classloader可以从其获得所需?ClassQ这打破了只能向父classloaderh的限制了。这个机制可以满_我们的classpath是在q行时才定,q由定制?classloader加蝲的时?由system classloader(卛_jvm classpath?加蝲的class可以通过context classloader获得定制的classloaderq加载入特定的class(通常是抽象类和接?定制的classloader中是其实?,例如web应用中的servlet是用这U机制加载的.<br /> <br />         好了Q现在我们了解了classloader的结构和工作原理Q那么我们如何实现在q行时的动态蝲入和更新呢?只要我们能够动态改变类搜烦路径和清?classloader的cache中已l蝲入的Classp了,有两个方案,一是我们承一个classloaderQ覆盖loadclassҎQ动态的LClass文gq用defineClassҎ来;另一个则非常单实用,只要重新使用一个新的类搜烦路径来new一?classloaderp了,q样xCcL索\径以便来载入新的ClassQ也重新生成了一个空白的cache(当然,cL索\径不一定必L?。噢Q太好了Q我们几乎不用做什么工作,java.netURLClassLoader正是一个符合我们要求的classloaderQ我们可以直接用或者承它可以了Q?br /> <br /> q是j2se1.4 API的doc中URLClassLoader的两个构造器的描qͼ<br /> URLClassLoader(URL[] urls)<br />          Constructs a new URLClassLoader for the specified URLs using the default delegation parent ClassLoader.<br /> URLClassLoader(URL[] urls, ClassLoader parent)<br />          Constructs a new URLClassLoader for the given URLs.<br /> 其中URL[] urls是我们要设|的cL索\径,parent是q个classloader的parent classloaderQ默认的是system classloader?br /> <br /> <br />         好,现在我们能够动态的载入Class了,q样我们可以利用newInstanceҎ来获得一个Object。但我们如何此Object造型呢?可以此Object造型成它本n的Class吗?<br /> <br />         首先让我们来分析一下java源文件的~译Q运行吧Qjavac命o是调?#8220;JAVA_HOME/lib/tools.jar”中的“com.sun.tools.javac.Main”的compileҎ来编译:<br /> <br />    public static int compile(String as[]);<br /> <br />    public static int compile(String as[], PrintWriter printwriter);<br /> <br /> q回0表示~译成功Q字W串数组as则是我们用javac命o~译时的参数Q以I格划分。例如:<br /> javac -classpath c:\foo\bar.jar;. -d c:\ c:\Some.java<br /> 则字W串数组as为{"-classpath","c:\\foo\\bar.jar;.","-d","c:\\","c:\Some.java"}Q如果带有PrintWriter参数Q则会把~译信息出到q个指定的printWriter中。默认的输出?System.err?br /> <br /> 其中 Main是由JVM使用Launcher初始化的system classloader载入的,Ҏ全盘负责原则Q编译器在解析这个java源文件时所发现的它所依赖和引用的所有Class也将由system classloader载入Q如果system classloader不能载入某个ClassӞ~译器将抛出一?#8220;cannot resolve symbol”错误?br /> <br /> 所以首先编译就通不q,也就是编译器无法~译一个引用了不在CLASSPATH中的未知Class的java源文Ӟ而由于拼写错误或者没有把所需cd攑ֈCLASSPATH中,大家一定经常看到这?#8220;cannot resolve symbol”q个~译错误吧!<br /> <br /> 其次Q就是我们把q个Class攑ֈ~译路径中,成功的进行了~译Q然后在q行的时候不把它攑օ到CLASSPATH中而利用我们自q classloader来动态蝲入这个ClassQ这时候也会出?#8220;java.lang.NoClassDefFoundError”的违例,Z么呢Q?br /> <br /> 我们再来分析一下,首先调用q个造型语句的可执行的Class一定是由JVM使用Launcher初始化的system classloader载入的,Ҏ全盘负责原则Q当我们q行造型的时候,JVM也会使用system classloader来尝试蝲入这个Class来对实例q行造型Q自然在system classloaderL不到q个Class时就会抛?#8220;java.lang.NoClassDefFoundError”的违例?br /> <br /> OKQ现在让我们来ȝ一下,java文g的编译和Class的蝲入执行,都是使用Launcher初始化的system classloader作ؓc蝲入器的,我们无法动态的改变system classloaderQ更无法让JVM使用我们自己的classloader来替换system classloaderQ根据全盘负责原则,限制了~译和运行时Q我们无法直接显式的使用一个system classloaderL不到的ClassQ即我们只能使用Java核心cdQ扩展类库和CLASSPATH中的cd中的Class?br /> <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 /> <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认ؓ不同的classloader载入的相同的名字的ClassQ即使是从同一个class文g中蝲入的Q是不同的!q样做的原因我想大概也是主要Z安全性考虑Q这样就保证所有的核心Javac都是system classloader载入的,我们无法用自qclassloader载入的相同名字的Class的实例来替换它们的实例?br /> <br /> 看到q里Q聪明的读者一定想C该如何动态蝲入我们的ClassQ实例化Q造型q调用了吧!<br /> <br /> 那就是利用面向对象的基本Ҏ之一的多形性。我们把我们动态蝲入的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法的Ҏ。这些方法中也可以引用system classloader不能识别的ClassQ因为根据全盘负责原则,只要载入q个Class的classloaderx们自己定义的 classloader能够定位和蝲入这些Classp了?br /> <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机?<br /> <br /> 对于以上各种情况Q希望大家实际编写一些example来实验一下?br /> <br /> 最后我再说点别的, classloader虽然UCؓcd载器Q但q不意味着只能用来加蝲ClassQ我们还可以利用它也获得囄Q音频文件等资源的URLQ当Ӟq些资源必须在CLASSPATH中的jarcd中或目录下。我们来看API的doc中关于ClassLoader的两个寻找资源和Class的方法描q吧Q?br />         public URL getResource(String name)<br />         用指定的名字来查找资源,一个资源是一些能够被class代码讉K的在某种E度上依赖于代码位置的数据(囄Q音频,文本{等Q?br />                一个资源的名字是以'/'号分隔确定资源的路径名的?br />                q个Ҏ先hparent classloader搜烦资源Q如果没有parentQ则会在内置在虚拟机中的classloaderQ即bootstrap classloaderQ的路径中搜索。如果失败,q个Ҏ调用findResource(String)来寻找资源?br />         public static URL getSystemResource(String name)<br />                从用来蝲入类的搜索\径中查找一个指定名字的资源。这个方法用system class loader来定位资源。即相当于ClassLoader.getSystemClassLoader().getResource(name)?br /> <br /> 例如Q?br />    System.out.println(ClassLoader.getSystemResource("java/lang/String.class"));<br /> 的结果ؓQ?br />    jar:文g:/C:/j2sdk1.4.1_01/jre/lib/rt.jar!/java/lang/String.class<br /> 表明String.class文g在rt.jar的java/lang目录中?br /> 因此我们可以图片等资源随同Class一同打包到jarcd中(当然Q也可单独打包这些资源)q添加它们到class loader的搜索\径中Q我们就可以无需兛_q些资源的具体位|,让class loader来帮我们L了! <img src ="http://www.tkk7.com/yjjlovewjf/aggbug/166418.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/yjjlovewjf/" target="_blank">wǒ愛伱--咑֩ </a> 2007-12-09 11:32 <a href="http://www.tkk7.com/yjjlovewjf/archive/2007/12/09/166418.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 中的堆和栈-Q{http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166336.htmlwǒ愛伱--咑֩ wǒ愛伱--咑֩ Sat, 08 Dec 2007 13:09:00 GMThttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166336.htmlhttp://www.tkk7.com/yjjlovewjf/comments/166336.htmlhttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166336.html#Feedback0http://www.tkk7.com/yjjlovewjf/comments/commentRss/166336.htmlhttp://www.tkk7.com/yjjlovewjf/services/trackbacks/166336.htmlJava 中的堆和?/strong>

单的_
Java把内存划分成两种Q一U是栈内存,一U是堆内存?nbsp;  
   
  在函C定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配?nbsp;  
   
  当在一D代码块定义一个变量时QJava在栈中个变量分配内存空_当超q变量的作用域后QJava会自动释放掉变量所分配的内存空_该内存空间可以立卌另作他用?nbsp;  
   
  堆内存用来存攄new创徏的对象和数组?nbsp;  
   
  在堆中分配的内存Q由Java虚拟机的自动垃圾回收器来理?nbsp;  
   
  在堆中生了一个数l或对象后,q可以在栈中定义一个特D的变量Q让栈中q个变量的取值等于数l或对象在堆内存中的首地址Q栈中的q个变量成了数l或对象的引用变量?nbsp;  
   
  引用变量q当于是ؓ数组或对象v的一个名Uͼ以后可以在E序中用栈中的引用变量来访问堆中的数组或对象?nbsp;  
   


           

具体的说Q?br /> 栈与堆都是Java用来在Ram中存放数据的地方。与C++不同QJava自动理栈和堆,E序员不能直接地讄栈或堆?
          Java的堆是一个运行时数据?cȝ(对象从中分配I间。这些对象通过new、newarray、anewarray和multianewarray{指令徏立,它们不需要程序代码来昑ּ的释放。堆是由垃圾回收来负责的Q堆的优势是可以动态地分配内存大小Q生存期也不必事先告诉编译器Q因为它是在q行时动态分配内存的QJava的垃圾收集器会自动收走这些不再用的数据。但~点是,׃要在q行时动态分配内存,存取速度较慢?
         栈的优势是,存取速度比堆要快Q仅ơ于寄存器,栈数据可以共享。但~点是,存在栈中的数据大与生存期必L定的,~Z灉|性。栈中主要存放一些基本类型的变量Q?int, short, long, byte, float, double, boolean, charQ和对象句柄?
         栈有一个很重要的特D性,是存在栈中的数据可以共享。假设我们同时定义:
int a = 3;
int b = 3Q?
~译器先处理int a = 3Q首先它会在栈中创徏一个变量ؓa的引用,然后查找栈中是否?q个|如果没找刎ͼ将3存放q来Q然后将a指向3。接着处理int b = 3Q在创徏完b的引用变量后Q因为在栈中已经?q个|便将b直接指向3。这P出Ca与b同时均指?的情c这Ӟ如果再oa=4Q那么编译器会重新搜索栈中是否有4|如果没有Q则?存放q来Qƈ令a指向4Q如果已l有了,则直接将a指向q个地址。因此a值的改变不会影响到b的倹{要注意q种数据的共享与两个对象的引用同时指向一个对象的q种׃n是不同的Q因U情况a的修改ƈ不会影响到b, 它是q译器完成的,它有利于节省I间。而一个对象引用变量修改了q个对象的内部状态,会媄响到另一个对象引用变量?

String是一个特D的包装cL据。可以用Q?
String str = new String("abc");
String str = "abc";
两种的Ş式来创徏Q第一U是用new()来新建对象的Q它会在存放于堆中。每调用一ơ就会创Z个新的对象?
而第二种是先在栈中创Z个对Stringcȝ对象引用变量strQ然后查找栈中有没有存放"abc"Q如果没有,则将"abc"存放q栈Qƈ令str指向”abc”Q如果已l有”abc” 则直接ostr指向“abc”?

           比较c里面的数值是否相{时Q用equals()ҎQ当试两个包装cȝ引用是否指向同一个对象时Q用==Q下面用例子说明上面的理论?
String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true
可以看出str1和str2是指向同一个对象的?

String str1 =new String ("abc");
String str2 =new String ("abc");
System.out.println(str1==str2); // false
用new的方式是生成不同的对象。每一ơ生成一个?
       因此用第一U方式创建多?#8221;abc”字符?在内存中其实只存在一个对象而已. q种写法有利与节省内存空? 同时它可以在一定程度上提高E序的运行速度Q因为JVM会自动根据栈中数据的实际情况来决定是否有必要创徏新对象。而对于String str = new String("abc")Q的代码Q则一概在堆中创徏新对象,而不其字符串值是否相{,是否有必要创建新对象Q从而加重了E序的负担?
       另一斚w, 要注? 我们在用诸如String str = "abc"Q的格式定义cLQL惛_然地认ؓQ创ZStringcȝ对象str。担心陷阱!对象可能q没有被创徏Q而可能只是指向一个先前已l创建的对象。只有通过new()Ҏ才能保证每次都创Z个新的对象。由于Stringcȝimmutable性质Q当String变量需要经常变换其值时Q应该考虑使用StringBufferc,以提高程序效率?br />



java中内存分配策略及堆和栈的比较
2.1 内存分配{略
按照~译原理的观?E序q行时的内存分配有三U策?分别是静态的,栈式?和堆式的.
静态存储分配是指在~译时就能确定每个数据目标在q行时刻的存储空间需?因而在~译时就可以l他们分配固定的内存I间.q种分配{略要求E序代码中不允许有可变数据结?比如可变数组)的存?也不允许有嵌套或者递归的结构出?因ؓ它们都会D~译E序无法计算准确的存储空间需?
栈式存储分配也可UCؓ动态存储分?是由一个类g堆栈的运行栈来实现的.和静态存储分配相?在栈式存储方案中,E序Ҏ据区的需求在~译时是完全未知?只有到运行的时候才能够知道,但是规定在运行中q入一个程序模块时,必须知道该程序模块所需的数据区大小才能够ؓ其分配内?和我们在数据l构所熟知的栈一?栈式存储分配按照先进后出的原则进行分配?
静态存储分配要求在~译时能知道所有变量的存储要求,栈式存储分配要求在过E的入口处必ȝ道所有的存储要求,而堆式存储分配则专门负责在编译时或运行时模块入口处都无法定存储要求的数据结构的内存分配,比如可变长度串和对象实例.堆由大片的可利用块或I闲块组?堆中的内存可以按照Q意顺序分配和释放.

2.2 堆和栈的比较
上面的定义从~译原理的教材中ȝ而来,除静态存储分配之?都显得很呆板和难以理?下面撇开静态存储分?集中比较堆和?
从堆和栈的功能和作用来通俗的比?堆主要用来存攑֯象的Q栈主要是用来执行程序的.而这U不同又主要是由于堆和栈的特点决定的:
在编E中Q例如C/C++中,所有的Ҏ调用都是通过栈来q行?所有的局部变?形式参数都是从栈中分配内存空间的。实际上也不是什么分?只是从栈向上用p,好像工厂中的传送带(conveyor belt)一?Stack Pointer会自动指引你到放东西的位|?你所要做的只是把东西放下来就?退出函数的时候,修改栈指针就可以把栈中的内容销?q样的模式速度最? 当然要用来运行程序了.需要注意的?在分配的时?比如Z个即要调用的程序模块分配数据区?应事先知道这个数据区的大?也就说是虽然分配是在E序q行时进行的,但是分配的大多是定?不变?而这?大小多少"是在~译时确定的,不是在运行时.
堆是应用E序在运行的时候请求操作系l分配给自己内存Q由于从操作pȝ理的内存分?所以在分配和销毁时都要占用旉Q因此用堆的效率非常?但是堆的优点在于,~译器不必知道要从堆里分配多存储空_也不必知道存储的数据要在堆里停留多长的时?因此,用堆保存数据时会得到更大的灵zL。事实上,面向对象的多态?堆内存分配是必不可少?因ؓ多态变量所需的存储空间只有在q行时创Z对象之后才能定.在C++中,要求创徏一个对象时Q只需?new命o~制相关的代码即可。执行这些代码时Q会在堆里自动进行数据的保存.当然Qؓ辑ֈq种灉|性,必然会付Z定的代h:在堆里分配存储空间时会花掉更长的旉Q这也正是导致我们刚才所说的效率低的原因,看来列宁同志说的?人的优点往往也是人的~点,人的~点往往也是人的优点(晕~).


2.3 JVM中的堆和?
JVM是基于堆栈的虚拟?JVM为每个新创徏的线E都分配一个堆?也就是说,对于一个JavaE序来说Q它的运行就是通过对堆栈的操作来完成的。堆栈以帧ؓ单位保存U程的状态。JVM对堆栈只q行两种操作:以为单位的压栈和出栈操作?
我们知道,某个U程正在执行的方法称为此U程的当前方?我们可能不知?当前Ҏ使用的UCؓ当前帧。当U程ȀzM个JavaҎ,JVM׃在线E的 Java堆栈里新压入一个。这个自然成ؓ了当前.在此Ҏ执行期间,q个帧将用来保存参数,局部变?中间计算q程和其他数?q个帧在q里和编译原理中的活动纪录的概念是差不多?
从Java的这U分配机制来?堆栈又可以这L?堆栈(Stack)是操作系l在建立某个q程时或者线E?在支持多U程的操作系l中是线E?个线E徏立的存储区域Q该区域h先进后出的特性?
每一个Java应用都唯一对应一个JVM实例Q每一个实例唯一对应一个堆。应用程序在q行中所创徏的所有类实例或数l都攑֜q个堆中,q由应用所有的U程׃n.跟C/C++不同QJava中分配堆内存是自动初始化的。Java中所有对象的存储I间都是在堆中分配的Q但是这个对象的引用却是在堆栈中分配,也就是说在徏立一个对象时从两个地斚w分配内存Q在堆中分配的内存实际徏立这个对象,而在堆栈中分配的内存只是一个指向这个堆对象的指?引用)而已?


wǒ愛伱--咑֩ 2007-12-08 21:09 发表评论
]]>
Java虚拟Zpȝ构概q?Q{Q?/title><link>http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166293.html</link><dc:creator>wǒ愛伱--咑֩ </dc:creator><author>wǒ愛伱--咑֩ </author><pubDate>Sat, 08 Dec 2007 07:53:00 GMT</pubDate><guid>http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166293.html</guid><wfw:comment>http://www.tkk7.com/yjjlovewjf/comments/166293.html</wfw:comment><comments>http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166293.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/yjjlovewjf/comments/commentRss/166293.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/yjjlovewjf/services/trackbacks/166293.html</trackback:ping><description><![CDATA[Java虚拟Z所以称?#8220;虚拟”Q就是因为它仅仅是由一个规范来定义的抽象计机。要q行某个JavaE序Q首先需要一个符合该规范的具体实现。下面主要讨个规范本w? <p style="line-height: 150%"><font color="#0000ff"><strong>Java虚拟机是什?/strong></font> <br />    要理解Java虚拟机,你必L识到Q当你说“Java虚拟?#8221;Ӟ可能指的是如下三U不同的东西Q?/p> <ul> <li>抽象规范  <li>一个具体的实现  <li>一个运行中的虚拟机实例 </li> </ul> <p style="line-height: 150%">Java虚拟机抽象规范仅仅是个概c该规范的具体实玎ͼ可能来自多个提供商,q存在多个^C。它或者完全用软g实现Q或者以g和Y件相l合的方式来实现。当q行一个JavaE序的同Ӟ也就在运行了一个Java虚拟机实例?/p> <p style="line-height: 150%"><font color="#0000ff"><strong>Java虚拟机的生命周期</strong></font> <br />    一个运行时的Java虚拟机实例的天职是Q负责运行一个JavaE序。当启动一个JavaE序Ӟ一个虚拟机实例也就诞生了。当该程序关闭推出,q个虚拟机实例也随之消亡。每个JavaE序都运行在于自qJava虚拟机实例中。Java虚拟机实例通过调用某个初始cȝmain()Ҏ来运行一个JavaE序。而这个main()Ҏ必须是public,static,q回gؓvoid。main()Ҏ作ؓ该程序初始线E的LQQ何其他的U程都是p个初始线E启动的?<br />    Java虚拟机内部有两种U程Q守护线E和非守护线E。守护线E通常p拟机自己使用的,比如执行垃圾攉d的线E。但是,JavaE序也可以把它的创徏的Q何线E标Cؓ守护U程。而JavaE序中的初始U程Q就是开始于main()的那个,是非守护U程。只要有非守护线E在q行Q那么这个JavaE序也在l箋q行Q只有该E序中所有的非守护线E都l止Ӟ虚拟机实例将自动退出?</p> <p style="line-height: 150%"><strong><font color="#0000ff">Java虚拟机的体系l构</font></strong> <br />   Java虚拟机的l构分ؓQ类装蝲子系l,q行时数据区Q执行引擎,本地Ҏ接口。其中运行时数据区又分ؓQ方法区Q堆QJava栈,PC寄存器,本地Ҏ栈?</p> <p style="line-height: 150%"><strong><font color="#0000ff">c装载子pȝ</font></strong> <br />   Java虚拟ZQ负责查扑ƈ装蝲cd的那部分UCؓc装载子pȝ?<br />   Java虚拟机有两种c装载器Q启动类装蝲器和用户自定义类装蝲器。启动类装蝲器是Java虚拟机实现的一部分。用戯定义c装载器是JavaE序的一部分?<br />   c装载器的动作: </p> <ol> <li>装蝲---查找q装载类型的二进制数? <li>q接---执行验证Q准备,以及解析Q可选) <br /> 验证Q确保被导入cd的正?<br /> 准备Qؓcd量分配内存,q将其初始化为默认?<br /> 把类型中的符号引用换为直接引? <li>初始?--把类变量初始化ؓ正确的初始?</li> </ol> <p style="line-height: 150%"><font color="#0000ff"><strong>Ҏ?/strong></font> <br />   在Java虚拟ZQ被装蝲cd的信息存储在一个逻辑上被UCؓҎ区的内存中。当虚拟载某个类型时Q它使用c装载器定位相应的class文gQ然后读入这个class文gQ然后将它传输到虚拟ZQ紧接着虚拟机提取其中的cd信息Qƈ这些信息存储到Ҏ区。该cd中的c(静态)变量同样也是存储在方法区中。方法区的大不必固定,可以Ҏ需要动态调整。方法区也可以被垃圾攉Q因拟机允许通过用户定义的类装蝲器来动态扩展JavaE序Q因此,一些类也会成ؓ“不再引用”的类?nbsp; <br />   对于每个装蝲的类型,虚拟机都会在ҎZ存储以下cd信息Q?</p> <ul> <li>q个cd的全限定名? <li>q个cd的直接超cȝ全限定名Q除非是java.lang.Object,无超c) <li>q个cd是类cdq是接口cd? <li>q个cd的访问修饰符Qpublic,abstract ...) <li>M直接接口的全限定名的有序列?</li> </ul> <p>除了上面列出的基本类型信息外Q虚拟机qؓ每个被装载的cd存储以下信息 </p> <ul> <li>该类型的帔R? <li>字段信息 <li>Ҏ信息 <li>除了帔R以外所有类Q静态)变量 <li>一个到cClassLoader的引? <li>一个到Classcȝ引用 </li> </ul> <p>http://blog.csdn.net/mimicimim/archive/2007/10/08/1815880.aspx</p> <img src ="http://www.tkk7.com/yjjlovewjf/aggbug/166293.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/yjjlovewjf/" target="_blank">wǒ愛伱--咑֩ </a> 2007-12-08 15:53 <a href="http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166293.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从Raylong - 睿狼的blog中收到的知?.U篏?/title><link>http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166291.html</link><dc:creator>wǒ愛伱--咑֩ </dc:creator><author>wǒ愛伱--咑֩ </author><pubDate>Sat, 08 Dec 2007 07:49:00 GMT</pubDate><guid>http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166291.html</guid><wfw:comment>http://www.tkk7.com/yjjlovewjf/comments/166291.html</wfw:comment><comments>http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166291.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/yjjlovewjf/comments/commentRss/166291.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/yjjlovewjf/services/trackbacks/166291.html</trackback:ping><description><![CDATA[对象的存储:Java中所有对象的存储I间都是在堆中分配的Q但是这个对象的引用却是在堆栈中分配,也就是说在徏立一个对象时从两个地斚w分配内存Q在堆中分配的内存实际徏立这个对象,而在堆栈中分配的内存只是一个指向这个堆对象的指?引用)而已。堆的特Ҏ灉|性,但ؓ此牺牲了高效性,可以在运行时动态地分配存储Q堆栈的特点是高效性,但缺乏灵zL,在编译时dȝ道所要分配的I间大小。堆像个大馒_可以Ҏ你的食量随便吃,吃饱了算Q堆栈像是吃大锅饭,每个人都是定食定量的Q你必须告诉厨子你的饭量Q厨子据此做饭,然后你们排队打饭吧。它们没有孰优孰劣之分,各自不同特点有不同的应用?br /> <br /> <br /> 字符串的q接?br /> int i=1,j=2,k=3;<br /> System.out.println(i+j+k);<br /> 输出??br /> int i=1,j=2,k=3;<br /> System.out.println(""+i+j+k);<br /> 输出?23。有吧Q这是因Z左到右的q算序?<a class="weblogtitle" id="Header1_HeaderTitle" href="http://www.tkk7.com/raylong1982/">Raylong - 睿狼</a><br /> <br /> <img src ="http://www.tkk7.com/yjjlovewjf/aggbug/166291.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/yjjlovewjf/" target="_blank">wǒ愛伱--咑֩ </a> 2007-12-08 15:49 <a href="http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166291.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java语法ȝ - Ҏhttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166284.htmlwǒ愛伱--咑֩ wǒ愛伱--咑֩ Sat, 08 Dec 2007 07:05:00 GMThttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166284.htmlhttp://www.tkk7.com/yjjlovewjf/comments/166284.htmlhttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166284.html#Feedback0http://www.tkk7.com/yjjlovewjf/comments/commentRss/166284.htmlhttp://www.tkk7.com/yjjlovewjf/services/trackbacks/166284.html 原文Q?a href="http://www.tkk7.com/raylong1982/">http://www.tkk7.com/raylong1982/以下几篇都是?...
一、方法的重写?br />
1、重写只能出现在l承关系之中。当一个类l承它的父类ҎӞ都有Z重写该父cȝҎ。一个特例是父类的方法被标识为final。重写的主要优点是能够定义某个子cdҎ的行为?br />     class Animal {
        public void eat(){
            System.out.println ("Animal is eating.");
        }
    }
    
    class Horse extends Animal{
        public void eat(){
            System.out.println ("Horse is eating.");
        }
    }

2、对于从父类l承来的抽象ҎQ要么在子类用重写的方式设计该方法,要么把子cM标识为抽象的。所以抽象方法可以说是必要被重写的Ҏ?br />
3、重写的意义?br /> 重写Ҏ可以实现多态,用父cȝ引用来操U子cd象,但是在实际运行中对象运行其自己Ҏ的方法?br />     public class Test {
        public static void main (String[] args) {
            Animal h = new Horse();
            h.eat();    
        }
    }

    class Animal {
        public void eat(){
            System.out.println ("Animal is eating.");
        }
    }
    
    class Horse extends Animal{
        public void eat(){
            System.out.println ("Horse is eating.");
        }
        public void buck(){
        }
    }

一个原则是Q用了什么引用,~译器就会只调用引用cL拥有的方法。如果调用子cȝ有的ҎQ如上例的h.buck(); ~译器会抱怨的。也是_~译器只看引用类型,而不是对象类型?br />
4、重写方法的规则?br /> 若想实现一个合格重写方法,而不是重载,那么必须同时满下面的要求!

A、重写规则之一Q重写方法不能比被重写方法限制有更严格的讉KU别?br /> Q但是可以更q泛Q比如父cL法是包访问权限,子类的重写方法是public讉K权限。)
比如QObjectcL个toString()ҎQ开始重写这个方法的时候我们d易忘记public修饰W,~译器当然不会放qQ何教训我们的Z。出错的原因是Q没有加M讉K修饰W的Ҏh包访问权限,包访问权限比public当然要严gQ所以编译器会报错的?br />
B、重写规则之二:参数列表必须与被重写Ҏ的相同?br /> 重写有个孪生的弟弟叫重蝲Q也是后面要出场的。如果子cL法的参数与父cd应的Ҏ不同Q那么就是你认错ZQ那是重载,不是重写?br />
C、重写规则之三:q回cd必须与被重写Ҏ的返回类型相同?br /> 父类ҎAQvoid eat(){}  子类ҎBQint eat(){}  两者虽然参数相同,可是q回cd不同Q所以不是重写?br /> 父类ҎAQint eat(){}   子类ҎBQlong eat(){}  q回cd虽然兼容父类Q但是不同就是不同,所以不是重写?br />
D、重写规则之四:重写Ҏ不能抛出新的异常或者比被重写方法声明的查异常更q的查异常。但是可以抛出更,更有限或者不抛出异常?br />     import java.io.*;
    public class Test {
        public static void main (String[] args) {
            Animal h = new Horse();
            try {
                h.eat();    
            }
            catch (Exception e) {
            }
        }
    }

    class Animal {
        public void eat() throws Exception{
            System.out.println ("Animal is eating.");
            throw new Exception();
        }
    }
    
    class Horse extends Animal{
        public void eat() throws IOException{
            System.out.println ("Horse is eating.");
            throw new IOException();
        }
    }
q个例子中,父类抛出了检查异常ExceptionQ子cL出的IOException是Exception的子c,也即是比被重写的Ҏ抛出了更有限的异常,q是可以的。如果反q来Q父cL出IOExceptionQ子cL出更为宽泛的ExceptionQ那么不会通过~译的?br /> 注意Q这U限制只是针Ҏ查异常,至于q行时异常RuntimeException及其子类不再q个限制之中?br />
E、重写规则之五:不能重写被标识ؓfinal的方法?br />
F、重写规则之六:如果一个方法不能被l承Q则不能重写它?br /> 比较典型的就是父cȝprivateҎ。下例会产生一个有的现象?br />     public class Test {
        public static void main (String[] args) {
            //Animal h = new Horse();
            Horse h = new Horse();
            h.eat();
        }
    }

    class Animal {
        private void eat(){
            System.out.println ("Animal is eating.");
        }
    }
    
    class Horse extends Animal{
        public void eat(){
            System.out.println ("Horse is eating.");
        }
    }
q段代码是能通过~译的。表面上看来q反了第六条规则Q但实际上那是一点y合。Animalcȝeat()Ҏ不能被承,因此HorsecM的eat()Ҏ是一个全新的ҎQ不是重写也不是重蝲Q只是一个只属于Horsecȝ全新的方法!q点让很多hqh了,但是也不是那么难以理解?br /> main()Ҏ如果是这P
    Animal h = new Horse();
    //Horse h = new Horse();
    h.eat();
~译器会报错Qؓ什么呢QHorsecȝeat()Ҏ是public的啊Q应该可以调用啊Q请牢记Q多态只看父cd用的ҎQ而不看子cd象的ҎQ?br />

二、方法的重蝲?br /> 重蝲是有好的Q它不要求你在调用一个方法之前{换数据类型,它会自动地寻扑֌配的Ҏ。方法的重蝲是在~译时刻决定调用哪个方法了Q和重写不同。最最常用的地方就是构造器的重载?br />
1、基本数据类型参数的重蝲?br />     public class Test {
        static void method(byte b){
            System.out.println ("method:byte");
        }
        static void method(short s){
            System.out.println ("method:short");
        }
        static void method(int i){
            System.out.println ("method:int");
        }
        static void method(float f){
            System.out.println ("method:float");
        }
        static void method(double d){
            System.out.println ("method:double");
        }
        public static void main (String[] args) {
            method((byte)1);
            method('c');
            method(1);
            method(1L);
            method(1.1);
            method(1.1f);
        }
    }
输出l果Q?br /> method:byte
method:int
method:int
method:float
method:double
method:float

可以看出Q首先要L的是数据cd正好匚wҎ。如果找不到Q那么就提升达能力更强的数据cdQ如上例没有正好容纳long的整数类型,那么p{换ؓfloatcd的。如果通过提升也不能找到合适的兼容cdQ那么编译器׃报错。反正是不会自动转换的数据cd的,必须自己强制转换Q自己来承担转变后果?br />
charcd比较ҎQ如果找不到正好匚w的类型,它会转化为int而不是shortQ虽然char?6位的?br />

2、重载方法的规则?br />
A、被重蝲的方法必L变参数列表?br /> 参数必须不同Q这是最重要的!不同有两个方面,参数的个敎ͼ参数的类型,参数的顺序?br />
B、被重蝲的方法与q回cd无关?br /> 也就是说Q不能通过q回cd来区分重载方法?br />
C、被重蝲的方法可以改变访问修饰符?br /> 没有重写Ҏ那样严格的限制?br />
D、被重蝲的方法可以声明新的或者更q的查异常?br /> 没有重写Ҏ那样严格的限制?br />
E、方法能够在一个类中或者在一个子cM被重载?br />

3、带对象引用参数的方法重载?br />     class Animal {}
    class Horse extends Animal{}
    
    public class Test {
        static void method(Animal a){
            System.out.println ("Animal is called.");
        }
        static void method(Horse h){
            System.out.println ("Horse is called.");
        }
        public static void main (String[] args) {
            Animal a = new Animal();
            Horse h = new Horse();
            Animal ah = new Horse();
            
            method(a);
            method(h);
            method(ah);
        }
    }
输出l果是:
Animal is called.
Horse is called.
Animal is called.
前两个输出没有Q何问题。第三个ҎZ么不是输?#8220;Horse is called.”呢?q是那句老话Q要看引用类型而不是对象类型,Ҏ重蝲是在~译时刻决定的了,引用cd军_了调用哪个版本的重蝲Ҏ?br />

4、重载和重写Ҏ区别的小l?br /> 如果能彻底弄明白下面的例子,说明你对重蝲和重写非怺解了Q可以结束这节的复习了?br />     class Animal {
        public void eat(){
            System.out.println ("Animal is eating.");    
        }
    }
    class Horse extends Animal{
        public void eat(){
            System.out.println ("Horse is eating.");    
        }
        public void eat(String food){
            System.out.println ("Horse is eating " + food);
        }
    }
    
    public class Test {
        public static void main (String[] args) {
            Animal a = new Animal();
            Horse h = new Horse();
            Animal ah = new Horse();
            
            a.eat();
            h.eat();
            h.eat("apple");
            ah.eat();
            //a.eat("apple");
            //ah.eat("apple");
        }
    }

四个输出分别是什么?被注释的两条语句Z么不能通过~译Q?br /> W一条:a.eat(); 普通的Ҏ调用Q没有多态,没什么技术含量。调用了Animalcȝeat()ҎQ输出:Animal is eating.
W二条:h.eat(); 普通的Ҏ调用Q也没什么技术含量。调用了Horsecȝeat()ҎQ输出:Horse is eating.
W三条:h.eat("apple"); 重蝲。Horsecȝ两个eat()Ҏ重蝲。调用了Horsecȝeat(String food)ҎQ输出:Horse is eating apple
W四条:ah.eat(); 多态。前面有例子了,不难理解。输出:Horse is eating.
W五条:a.eat("apple"); 低的错误,AnimalcM没有eat(String food)Ҏ。因此不能通过~译?br /> W六条:ah.eat("apple"); 关键点就在这里。解决的Ҏq是那句老话Q不能看对象cdQ要看引用类型。AnimalcM没有eat(String food)Ҏ。因此不能通过~译?br />
结一下:多态不军_调用哪个重蝲版本Q多态只有在军_哪个重写版本时才起作用?br /> 重蝲对应~译Ӟ重写对应q行时。够z的了吧Q?br />

三、构造方法?br /> 构造方法是一U特D的ҎQ没有构造方法就不能创徏一个新对象。实际上Q不仅要调用对象实际cd的构造方法,q要调用其父cȝ构造方法,向上q溯Q直到ObjectcR构造方法不必显式地调用Q当使用new关键字时Q相应的构造方法会自动被调用?br />
1、构造方法的规则?br /> A、构造方法能使用M讉K修饰W。包括privateQ事实上javacd有很多都是这LQ设计者不希望使用者创cȝ对象?br />
B、构造方法的名称必须与类名相同。这样得构造方法与众不同,如果我们遵守sun的编码规范,g只有构造方法的首字母是大写的?br />
C、构造方法不能有q回cd?br /> 反过来说Q有q回cd的不是构造方?br />     public class Test {
        int Test(){
            return 1;
        }
    }
q个Ҏ是什么东西?一个冒充李늚李鬼而已Qint Test()和其他Q何普通方法没什么两P是普通的ҎQ只不过看v来很恶心Q类似恶心的东西在考试卷子里比较多?br />
D、如果不在类中创q构造方法,~译器会自动生成默认的不带参数的构造函数?br /> q点很容易验证!写一个这L单的c,~译?br /> class Test {
}
对生成的Test.class文g反编译:javap TestQ可以看刎ͼ
D:"JavaCode"bin>javap Test
Compiled from "Test.java"
class Test extends java.lang.Object{
    Test();
}
看到~译器自动添加的默认构造函C吧!

E、如果只创徏了带参数的构造方法,那么~译器不会自动添加无参的构造方法的Q?br />
F、在每个构造方法中Q如果用了重蝲构造函数this()ҎQ或者父cȝ构造方法super()ҎQ那么this()Ҏ或者super()Ҏ必须攑֜W一行。而且q两个方法只能选择一个,因此它们之间没有序问题?br />
G、除了编译器生成的构造方法,而且没有昑ּ地调用super()ҎQ那么编译器会插入一个super()无参调用?br />
H、抽象类有构造方法?br />

四、静态方法的重蝲与重写(覆盖Q?br />
1、静态方法是不能被覆盖的。可以分两种情况讨论Q?br />
A、子cȝ非静态方?#8220;覆盖”父类的静态方法?br /> q种情况下,是不能通过~译的?br />
class Father{
    
static void print(){
        System.out.println (
"in father  method");
    }
}
class Child extends Father{
    
void print(){
        System.out.println (
"in child method");
    }
}

staticҎ表示该方法不兌具体的类的对象,可以通过cd直接调用Q也是~译的前期就l定了,不存在后期动态绑定,也就是不能实现多态。子cȝ非静态方法是与具体的对象l定的,两者有着不同的含义?br />
B、子cȝ静态方?#8220;覆盖”父类静态方法?br /> q个覆盖依然是带引号的。事实上把上面那个例子ChildcȝprintҎ前面加上static修饰W,实能通过~译Q但是不要以是多态!多态的特点是动态绑定,看下面的例子Q?br />
class Father{
    
static void print(){
        System.out.println (
"in father  method");
    }
}
class Child extends Father{
    
static void print(){
        System.out.println (
"in child method");
    }
}

class Test{
    
public static void main (String[] args) {
        Father f 
=new Child();
        f.print();
    }
}

输出l果是:in father  method
从这个结果可以看出,q没有实现多态?br /> 但是q种形式很迷惑hQ貌似多态,实际~程中千万不要这hQ会把大家搞늚Q?br /> 它不W合覆盖表现出来的特性,不应该算是覆盖!
总而言之,静态方法不能被覆盖?br />
2、静态方法可以和非静态方法一栯重蝲?br /> q样的例子太多了Q我不想写例E了。看看javacd中很多这L例子?br /> 如java.util.Arrayscȝ一堆重载的binarySearchҎ?br /> 在这里提一下是因ؓ查资料时看到q样的话“sun的SL275评_静态方法只能控刉态变量(他们本n没有Q,静态方法不能被重蝲和覆?#8230;…”
大家不要怿啊!可以重蝲的。而且静态与非静态方法可以重载?br />
从重载的机制很容易就理解了,重蝲是在~译时刻决定的了,非静态方法都可以Q静态方法怎么可能不会呢?


wǒ愛伱--咑֩ 2007-12-08 15:05 发表评论
]]>
Java语法ȝ - U程http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166283.htmlwǒ愛伱--咑֩ wǒ愛伱--咑֩ Sat, 08 Dec 2007 07:03:00 GMThttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166283.htmlhttp://www.tkk7.com/yjjlovewjf/comments/166283.htmlhttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166283.html#Feedback0http://www.tkk7.com/yjjlovewjf/comments/commentRss/166283.htmlhttp://www.tkk7.com/yjjlovewjf/services/trackbacks/166283.html
一提到U程好像是g很麻烦很复杂的事Q事实上实如此Q涉及到U程的编E是很讲I技巧的。这需要我们变换思维方式Q了解线E机制的比较通用的技巧,写出高效的、不依赖于某个JVM实现的程序来。毕竟仅仅就Java而言Q各个虚拟机的实现是不同的。学习线E时Q最令我印象深刻的就是那U不定性、没有保障性,各个U程的运行完全是以不可预料的方式和速度推进Q有的一个程序运行了Nơ,其结果差异性很大?br />

1、什么是U程Q线E是彼此互相独立的、能独立q行的子dQƈ且每个线E都有自q调用栈。所谓的多Q务是通过周期性地CPU旉片切换到不同的子dQ虽然从微观上看来,单核的CPU上同时只q行一个子dQ但是从宏观来看Q每个子dg是同时连l运行的。(但是JAVA的线E不是按旉片分配的Q在本文的最后引用了一D늽友翻译的JAVA原著中对U程的理解。)

2、在java中,U程指两个不同的内容Q一是java.lang.Threadcȝ一个对象;另外也可以指U程的执行。线E对象和其他的对象一P在堆上创建、运行、死亡。但不同之处是线E的执行是一个轻量的进E,有它自己的调用栈?br /> 可以q样惻I每个调用栈都对应一个线E,每个U程又对应一个调用栈?br /> 我们q行javaE序时有一个入口函数main()函数Q它对应的线E被UCؓȝE。一个新U程一旦被创徏Q就产生一个新调用栈,从原ȝE中qQ也是与主U程q发执行?br />

4、当提到U程Ӟ很少是有保障的。我们必M解到什么是有保障的操作Q什么是无保障的操作Q以便设计的E序在各Ujvm上都能很好地工作。比如,在某些jvm实现中,把javaU程映射为本地操作系l的U程。这是java核心的一部分?br />
5、线E的创徏?br /> 创徏U程有两U方式:
A、承java.lang.ThreadcR?br />     class ThreadTest extends Thread{
        public void run() {
            System.out.println ("someting run hereQ?);
        }
        public void run(String s){
            System.out.println ("string in run is " + s);
        }
        public static void main (String[] args) {
            ThreadTest tt = new ThreadTest();
            tt.start();
            tt.run("it won't auto run!");
        }
    }

输出的结果比较有:
string in run is it won't auto run!
someting run hereQ?br /> 注意输出的顺序:好像与我们想象的序相反了!Z么呢Q?br /> 一旦调用start()ҎQ必ȝJVMҎ_让它配置q程。而在它配|完成之前,重蝲的run(String s)Ҏ被调用了Q结果反而先输出?#8220;string in run is it won't auto run!”Q这时ttU程完成了配|,输出?#8220;someting run hereQ?#8221;?br /> q个l论是比较容易验证的Q?br /> 修改上面的程序,在tt.start();后面加上语句for (int i = 0; i<10000; i++); q样ȝE开始执行运量比较大的for循环了,只有执行完for循环才能q行后面的tt.run("it won't auto run!");语句。此ӞttU程和主U程q行执行了,已经有够的旉完成U程的配|!因此先到一步!修改后的E序q行l果如下Q?br /> someting run hereQ?br /> string in run is it won't auto run!
注意Q这U输出结果的序是没有保障的Q不要依赖这U结论!

没有参数的run()Ҏ是自动被调用的,而带参数的run()是被重蝲的,必须昑ּ调用?br /> q种方式的限制是Q这U方式很单,但不是个好的Ҏ。如果承了Threadc,那么׃能承其他的cMQjava是单l承l构的,应该把承的Z留给别的cR除非因Z有线E特有的更多的操作?br /> ThreadcM有许多管理线E的ҎQ包括创建、启动和暂停它们。所有的操作都是从run()Ҏ开始,q且在run()Ҏ内编写需要在独立U程内执行的代码。run()Ҏ可以调用其他ҎQ但是执行的U程L通过调用run()?br />
B、实现java.lang.Runnable接口?br />     class ThreadTest implements Runnable {
        public void run() {
            System.out.println ("someting run here");
        }
        public static void main (String[] args) {
            ThreadTest tt = new ThreadTest();
        Thread t1 = new Thread(tt);
        Thread t2 = new Thread(tt);
        t1.start();
        t2.start();
            //new Thread(tt).start();
        }
    }

比第一U方法复杂一点,Z使代码被独立的线E运行,q需要一个Thread对象。这样就把线E相关的代码和线E要执行的代码分d来?br />
另一U方式是Q参数Ş式的匿名内部cd建方式,也是比较常见的?br />     class ThreadTest{
        public static void main (String[] args) {
            Thread t = new Thread(new Runnable(){
                public void run(){
                    System.out.println ("anonymous thread");
                }
            });    
            
            t.start();
        }
    }
如果你对此方式的声明不感冒,请参看本人ȝ的内部类?br />
W一U方式用无参构造函数创建线E,则当U程开始工作时Q它调用自qrun()Ҏ?br /> W二U方式用带参数的构造函数创建线E,因ؓ你要告诉q个新线E用你的run()ҎQ而不是它自己的?br /> 如上例,可以把一个目标赋l多个线E,q意味着几个执行U程运行完全相同的作业?br />
6、什么时候线E是zȝQ?br /> 在调用start()Ҏ开始执行线E之前,U程的状态还不是zȝ。测试程序如下:
    class ThreadTest implements Runnable {
        public void run() {
            System.out.println ("someting run here");
        }
        public static void main (String[] args) {
            ThreadTest tt = new ThreadTest();
            Thread t1 = new Thread(tt);
            System.out.println (t1.isAlive());
            t1.start();
            System.out.println (t1.isAlive());
        }
    }

l果输出Q?br /> false
true
isAliveҎ是确定一个线E是否已l启动,而且q没完成run()Ҏ内代码的最好方法?br />
7、启动新U程?br /> U程的启动要调用start()ҎQ只有这h能创建新的调用栈。而直接调用run()Ҏ的话Q就不会创徏新的调用栈,也就不会创徏新的U程Qrun()Ҏ׃普通的Ҏ没什么两样了Q?br />
8、给U程起个有意义的名字?br /> 没有该线E命名的话,U程会有一个默认的名字Q格式是Q?#8220;Thread-”加上U程的序P如:Thread-0
q看h可读性不好,不能从名字分辨出该线E具有什么功能。下面是l线E命名的方式?br /> W一U:用setName()函数
W二U:选用带线E命名的构造器
    class ThreadTest implements Runnable{
        public void run(){
            System.out.println (Thread.currentThread().getName());
        }
        public static void main (String[] args) {
        ThreadTest tt = new ThreadTest();     
        //Thread t = new Thread (tt,"eat apple");
        Thread t = new Thread (tt);
        t.setName("eat apple");
        t.start();
        }
    }

9?#8220;没有保障”的多U程的运行。下面的代码可能令h印象深刻?br />     class ThreadTest implements Runnable{
        public void run(){
            System.out.println (Thread.currentThread().getName());
        }
        public static void main (String[] args) {
            ThreadTest tt = new ThreadTest();
            Thread[] ts =new Thread[10];
        
            for (int i =0; i < ts.length; i++)
                ts[i] = new Thread(tt);
                
            for (Thread t : ts)
                t.start();
        }
    }
在我的电脑上q行的结果是Q?br /> Thread-0
Thread-1
Thread-3
Thread-5
Thread-2
Thread-7
Thread-4
Thread-9
Thread-6
Thread-8
而且每次q行的结果都是不同的Ql引用前面的话,一旦涉及到U程Q其q行多半是没有保障。这个保障是指线E的q行完全是由调度E序控制的,我们没法控制它的执行序Q持l时间也没有保障Q有着不可预料的结果?br />

10、线E的状态?br /> A、新状态?br /> 实例化Thread对象Q但没有调用start()Ҏ时的状态?br /> ThreadTest tt = new ThreadTest();     
或者Thread t = new Thread (tt);
此时虽然创徏了Thread对象Q如前所qͼ但是它们不是zȝQ不能通过isAlive()试?br />
B、就l状态?br /> U程有资D行,但调度程序还没有把它选ؓq行U程所处的状态。也是具备了运行的条gQ一旦被选中马上pq行?br /> 也是调用start()Ҏ后但没运行的状态。此时虽然没在运行,但是被认为是zȝQ能通过isAlive()试。而且在线E运行之后、或者被d、等待或者睡眠状态回来之后,U程首先q入qA状态?br />
C、运行状态?br /> 从就l状态池Q注意不是队列,是池Q中选择一个ؓ当前执行q程Ӟ该线E所处的状态?br />
D、等待、阻塞、睡眠状态?br /> q三U状态有一个共同点Q线E依然是zȝQ但是缺运行的条gQ一旦具备了条就可以{为就l状态(不能直接转ؓq行状态)。另外,suspend()和stop()Ҏ已经被废弃了Q比较危险,不要再用了?br />
E、死亡状态?br /> 一个线E的run()Ҏq行l束Q那么该U程完成其历史命,它的栈结构将解散Q也是M了。但是它仍然是一个Thread对象Q我们仍可以引用它,像其他对象一P它也不会被垃圑֛收器回收了,因ؓ对该对象的引用仍然存在?br /> 如此说来Q即使run()Ҏq行l束U程也没有死啊!事实是,一旦线E死去,它就永远不能重新启动了,也就是说Q不能再用start()Ҏ让它q行hQ如果强来的话会抛出IllegalThreadStateException异常。如Q?br /> t.start();
t.start();
攑ּ吧,人工呼吸或者心脏v搏器都无于?#8230;…U程也属于一ơ性用品?br />
11、阻止线E运行?br /> A、睡眠。sleep()Ҏ
让线E睡眠的理由很多Q比如:认ؓ该线E运行得太快Q需要减~一下,以便和其他线E协调;查询当时的股h|每睡5分钟查询一ơ,可以节省带宽Q而且x性要求也不那么高?br /> 用Thread的静态方法可以实现Thread.sleep(5*60*1000); 睡上5分钟吧。sleep的参数是毫秒。但是要注意sleep()Ҏ会抛出检查异常InterruptedExceptionQ对于检查异常,我们要么声明Q要么用处理程序?br />     try {
        Thread.sleep(20000);
    }
    catch (InterruptedException ie) {
        ie.printStackTrace();
    }
既然有了sleep()ҎQ我们是不是可以控制U程的执行顺序了Q每个线E执行完毕都睡上一觉?q样p控制U程的运行顺序了Q下面是书上的一个例子:
    class ThreadTest implements Runnable{
        public void run(){
            for (int i = 1; i<4; i++){
                System.out.println (Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ie) { }
            }
        }
        public static void main (String[] args) {
            ThreadTest tt = new ThreadTest();
            Thread t0 = new Thread(tt,"Thread 0");
            Thread t1 = new Thread(tt,"Thread 1");
            Thread t2 = new Thread(tt,"Thread 2");
            t0.start();
            t1.start();
            t2.start();            
        }
    }

q且l出了结果:
Thread 0
Thread 1
Thread 2
Thread 0
Thread 1
Thread 2
Thread 0
Thread 1
Thread 2
也就是Thread 0  Thread 1 Thread 2 按照q个序交替出现Q作者指然结果和我们预料的似乎相同,但是q个l果是不可靠的。果然被我的双核电脑验证了:
Thread 0
Thread 1
Thread 2
Thread 2
Thread 0
Thread 1
Thread 1
Thread 0
Thread 2
看来U程真的很不可靠啊。但是尽如此,sleep()Ҏ仍然是保证所有线E都有运行机会的最好方法。至它保证了一个线E进入运行之后不会一直到q行完位|?br />
旉的精性。再一下,U程醒来之后不会q入q行状态,而是q入qA状态。因此sleep()中指定的旉不是U程不运行的_旉Q不能依赖sleep()Ҏ提供十分_的定时。我们可以看到很多应用程序用sleep()作ؓ定时器,而且没什么不好的Q确实如此,但是我们一定要知道sleep()不能保证U程醒来p马上q入q行状态,是不_的?br />
sleep()Ҏ是一个静态的ҎQ它所指的是当前正在执行的U程休眠一个毫U数。看到某些书上的Thread.currentThread().sleep(1000); Q其实是不必要的。Thread.sleep(1000);可以了。类ggetName()Ҏ不是静态方法,它必针对具体某个线E对象,q时用取得当前线E的ҎThread.currentThread().getName();

B、线E优先和让步?br /> U程的优先。在大多数jvm实现中调度程序用基于线E优先的抢先调度机制。如果一个线E进入可q行状态,q且它比池中的Q何其他线E和当前q行的进E的h更高的优先Q则优先U较低的U程q入可运行状态,最高优先的线E被选择L行?br />
于是有了这Ll论Q当前运行线E的优先U通常不会比池中Q何线E的优先U低。但是ƈ不是所有的jvm的调度都q样Q因此一定不能依赖于U程优先U来保证E序的正操作,q仍然是没有保障的,要把U程优先U用作一U提高程序效率的ҎQƈ且这U方法也不能依赖优先U的操作?br />
另外一个没有保障的操作是:当前q行的线E与池中的线E,或者池中的U程h相同的优先ӞJVM的调度实C选择它喜Ƣ的U程。也许是选择一个去q行Q直臛_完成Q或者用分配旉片的方式Qؓ每个U程提供均等的机会?br />
优先U用正整数设|,通常?-10QJVM从不会改变一个线E的优先U。默认情况下Q优先?。Threadcd有三个定义线E优先范围的静态最l常量:Thread.MIN_PRIORITY Qؓ1Q?Thread.NORM_PRIORITY Qؓ5Q?Thread.MAX_PRIORITY Qؓ10Q?br />
静态Thread.yield()Ҏ?br /> 它的作用是让当前q行的线E回到可q行状态,以便让具有同{优先的其他线E运行。用yield()Ҏ的目的是让同{优先的线E能适当地轮转。但是,q不能保证达到此效果Q因为,即当前变成可运行状态,可是q有可能再次被JVM选中Q也是qQ?br />
非静态join()Ҏ?br /> 让一个线E加入到另一个线E的N。让BU程加入AU程Q意味着在AU程q行完成之前QBU程不会q入可运行状态?br />     Thread t = new Thread();
    t.start();
    t.join;
q段代码的意思是取得当前的线E,把它加入到tU程的尾部,{tU程q行完毕之后Q原U程l箋q行。书中的例子在我的电脑里效果很糟p,看不Z么效果来。也许是CPU太快了,而且是双核的Q也许是JDK1.6的原因?

12、没ȝ完。线E这部分很重要,内容也很多,看太快容易消化不良,偶要慢慢地消化掉……



附: java原著中对U程的解释?br />
e文原文:

Thread Scheduling

In Java technology,threads are usually preemptive,but not necessarily Time-sliced(the process of giving each thread an equal amount of CPU time).It is common mistake to believe that "preemptive" is a fancy word for "does time-slicing".

For the runtime on a Solaris Operating Environment platform,Java technology does not preempt threads of the same priority.However,the runtime on Microsoft Windows platforms uses time-slicing,so it preempts threads of the same priority and even threads of higher priority.Preemption is not guaranteed;however,most JVM implementations result in behavior that appears to be strictly preemptive.Across JVM implementations,there is no absolute guarantee of preemption or time-slicing.The only guarantees lie in the coder’s use of wait and sleep.

The model of a preemptive scheduler is that many threads might be runnable,but only one thread is actually running.This thread continues to run until it ceases to be runnable or another thread of higher priority becomes runnable.In the latter case,the lower priority thread is preempted by the thread of higher priority,which gets a chance to run instead.

A thread might cease to runnable (that is,because blocked) for a variety of reasons.The thread’s code can execute a Thread.sleep() call,deliberately asking the thread to pause for a fixed period of time.The thread might have to wait to access a resource and cannot continue until that resource become available.

All thread that are runnable are kept in pools according to priority.When a blocked thread becomes runnable,it is placed back into the appropriate runnable pool.Threads from the highest priority nonempty pool are given CPU time.

The last sentence is worded loosed because:
(1) In most JVM implementations,priorities seem to work in a preemptive manner,although there is no guarantee that priorities have any meaning at all;
(2) Microsoft Window’s values affect thread behavior so that it is possible that a Java Priority 4 thread might be running,in spite of the fact that a runnable Java Priority 5 thread is waiting for the CPU.
In reality,many JVMs implement pool as queues,but this is not guaranteed hehavior.


热心|友译的版本:

在java技术中Q线E通常是抢占式的而不需要时间片分配q程Q分配给每个U程相等的cpu旉的进E)。一个经常犯的错误是认ؓ“抢占”是“分配旉?#8221;?br /> 在Solarisq_上的q行环境中,相同优先U的U程不能怺抢占Ҏ的cpu旉。但是,在用时间片的windowsq_q行环境中,可以抢占相同甚至更高优先U的U程的cpu旉。抢占ƈ不是l对的,可是大多数的JVM的实现结果在行ؓ上表现出了严格的抢占。纵观JVM的实玎ͼq没有绝对的抢占或是旉片,而是依赖于编码者对wait和sleepq两个方法的使用?br /> 抢占式调度模型就是许多线E属于可以运行状态({待状态)Q但实际上只有一个线E在q行。该U程一直运行到它终止进入可q行状态({待状态)或是另一个具有更高优先的线E变成可q行状态。在后一U情况下Q底优先U的U程被高优先U的U程抢占Q高优先U的U程获得q行的机会?br /> U程可以因ؓ各种各样的原因终止ƈq入可运行状态(因ؓ堵塞Q。例如,U程的代码可以在适当时候执行Thread.sleep()ҎQ故意让U程中止Q线E可能ؓ了访问资源而不得不{待直到该资源可用ؓ止?br /> 所有可q行的线E根据优先保持在不同的池中。一旦被堵塞的线E进入可q行状态,它将会被攑֛适当的可q行池中。非I最高优先的池中的U程获得cpu旉?br /> 最后一个句子是不精的Q因为:
Q?Q在大多数的JVM实现中,虽然不能保证说优先有Q何意义,但优先看v来象是用抢占方式工作?br /> Q?Q微软windows的评价媄响线E的行ؓQ以臛_一个处于可q行状态的优先Uؓ5的javaU程正在{待cpu旉Q但是一个优先?的javaU程却可能正在运行?br /> 实际上,许多JVM用队列来实现池,但没有保证行为?br />

wǒ愛伱--咑֩ 2007-12-08 15:03 发表评论
]]>
Java语法ȝ - 内部c?/title><link>http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166277.html</link><dc:creator>wǒ愛伱--咑֩ </dc:creator><author>wǒ愛伱--咑֩ </author><pubDate>Sat, 08 Dec 2007 06:52:00 GMT</pubDate><guid>http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166277.html</guid><wfw:comment>http://www.tkk7.com/yjjlovewjf/comments/166277.html</wfw:comment><comments>http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166277.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/yjjlovewjf/comments/commentRss/166277.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/yjjlovewjf/services/trackbacks/166277.html</trackback:ping><description><![CDATA[从Java1.1开始引入了内部cM来,它就引v了h们的Ȁ烈争论。其实Q何优U的语aҎ用得不好就是滥用,内部cȝ得不好就会导致代码像q宫一PD出现毫无重用的综合征?br /> <br /> 1、内部类分ؓ成员内部cR静态嵌套类、方法内部类、匿名内部类?br /> 几种内部cȝ共性:<br /> A、内部类仍然是一个独立的c,在编译之后会内部cM被编译成独立?class文gQ但是前面冠以外部类的类命和$W号?br /> B、内部类不能用普通的方式讉K。内部类是外部类的一个成员,因此内部cd以自由地讉K外部cȝ成员变量Q无论是否是private的?br /> <br /> 2、成员内部类QŞ式如?br />     class Outer {<br />         class Inner{}<br />     }       <br /> ~译上述代码会生两个文ӞOuter.class和Outer$Inner.class?br /> 成员内部cd不允许有M静态声明!下面代码不能通过~译?br />     class Inner{<br />         static int a = 10;<br />     } <br /> 能够讉K成员内部cȝ唯一途径是通过外部cȝ对象Q?br /> <br /> A、从外部cȝ非静态方法中实例化内部类对象?br /> <br /> <div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #000000">    </span><span style="color: #0000ff">class</span><span style="color: #000000"> Outer {<br />         </span><span style="color: #0000ff">private</span><span style="color: #000000"> </span><span style="color: #0000ff">int</span><span style="color: #000000"> i </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">10</span><span style="color: #000000">;<br />         </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> makeInner(){<br />             Inner in </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> Inner();<br />             in.seeOuter();<br />         }<br />         </span><span style="color: #0000ff">class</span><span style="color: #000000"> Inner{<br />             </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> seeOuter(){<br />                 System.out.print(i);<br />             }<br />         }<br />     }</span></div> <br /> 表面上,我们q没有创建外部类的对象就实例化了内部cd象,和上面的话矛盾。事实上Q如果不创徏外部cd象也׃可能调用makeInner()ҎQ所以到头来q是要创建外部类对象的?br /> 你可能试图把makeInner()Ҏ修饰为静态方法,即static public void makeInner()。这样不创徏外部cd可以实例化外部类了!但是在一个静态方法里能访问非静态成员和Ҏ吗?昄不能。它没有this引用。没能蟩出那条规则!但是如果在这个静态方法中实例化一个外部类对象Q再用这个对象实例化外部cdQ完全可以!也就是下一条的内容?br /> <br /> B、从外部cȝ静态方法中实例化内部类对象?br />     class Outer {<br />         private int i = 10;<br />         class Inner{<br />             public void seeOuter(){<br />                 System.out.print(i);<br />             }<br />         }    <br />         public static void main(String[] args) {<br />             Outer out = new Outer();<br />             Outer.Inner in = out.new Inner();<br />             //Outer.Inner in = new Outer().new Inner();<br />             in.seeOuter();<br />         }<br />     }<br /> <br /> 被注释掉的那行是它上面两行的合ƈ形式Q一条简z的语句?br /> Ҏ一下:在外部类的非静态方法中实例化内部类对象是普通的new方式QInner in = new Inner();<br /> 在外部类的静态方法中实例化内部类对象Q必d创徏外部cd象:Outer.Inner in = new Outer().new Inner();<br /> <br /> C、内部类的this引用?br /> 普通的cd以用this引用当前的对象,内部cM是如此。但是假若内部类惛_用外部类当前的对象呢Q用“外部cd”.thisQ的形式,如下例的Outer.this?br />     class Outer {<br />         class Inner{<br />             public void seeOuter(){<br />                 System.out.println(this);<br />                 System.out.println(Outer.this);<br />             }<br />         }<br />     }<br /> <br /> D、成员内部类的修饰符?br /> 对于普通的c,可用的修饰符有final、abstract、strictfp、public和默认的包访问?br /> 但是成员内部cL像一个成员变量和Ҏ?br /> 可用的修饰符有:final、abstract、public、private、protected、strictfp和static?br /> 一旦用static修饰内部c,它就变成静态内部类了?br /> <br /> <br /> 3、方法内部类?br /> ֐思义Q把cL在方法内?br />     class Outer {<br />         public void doSomething(){<br />             class Inner{<br />                 public void seeOuter(){<br />                 }<br />             }    <br />         }<br />     }<br /> A、方法内部类只能在定义该内部cȝҎ内实例化Q不可以在此Ҏ外对其实例化?br /> <br /> B、方法内部类对象不能使用该内部类所在方法的非final局部变量?br /> 因ؓҎ的局部变量位于栈上,只存在于该方法的生命期内。当一个方法结束,其栈l构被删除,局部变量成为历双Ӏ但是该Ҏl束之后Q在Ҏ内创建的内部cd象可能仍然存在于堆中Q例如,如果对它的引用被传递到其他某些代码Qƈ存储在一个成员变量内。正因ؓ不能保证局部变量的存活期和Ҏ内部cd象的一样长Q所以内部类对象不能使用它们?br /> 下面是完整的例子Q?br />     class Outer {<br />         public void doSomething(){<br />             final int a =10;<br />             class Inner{<br />                 public void seeOuter(){<br />                     System.out.println(a);<br />                 }<br />             }   <br />             Inner in = new Inner();<br />             in.seeOuter(); <br />         }<br />         public static void main(String[] args) {<br />             Outer out = new Outer();<br />             out.doSomething();<br />         }<br />      }<br /> <br /> C、方法内部类的修饰符?br /> 与成员内部类不同Q方法内部类更像一个局部变量?br /> 可以用于修饰Ҏ内部cȝ只有final和abstract?br /> <br /> D、静态方法内的方法内部类?br /> 静态方法是没有this引用的,因此在静态方法内的内部类遭受同样的待遇,卻I只能讉K外部cȝ静态成员?br /> <br /> <br /> 4、匿名内部类?br /> ֐思义Q没有名字的内部cR表面上看v来它们似乎有名字Q实际那不是它们的名字?br /> <br /> A、承式的匿名内部类?br />     class Car {<br />         public void drive(){<br />             System.out.println("Driving a car!");<br />         }<br />     }<br />     <br />     class Test{<br />         public static void main(String[] args) {<br />             Car car = new Car(){<br />                 public void drive(){<br />                     System.out.println("Driving another car!");<br />                 }<br />             };<br />             car.drive();<br />         }<br />     }<br /> l果输出了:Driving another car! Car引用变量不是引用Car对象Q而是Car匿名子类的对象?br /> 建立匿名内部cȝ关键Ҏ重写父类的一个或多个Ҏ。再一下,是重写父cȝҎQ而不是创建新的方法。因为用父类的引用不可能调用父类本n没有的方法!创徏新的Ҏ是多余的。简a之,参考多态?br /> <br /> B、接口式的匿名内部类?br />     interface  Vehicle {<br />         public void drive();<br />     }<br />     <br />     class Test{<br />         public static void main(String[] args) {<br />             Vehicle v = new Vehicle(){<br />                 public void drive(){<br />                     System.out.println("Driving a car!");<br />                 }<br />             };<br />             v.drive();<br />         }<br />     }<br /> 上面的代码很怪,好像是在实例化一个接口。事实ƈ非如此,接口式的匿名内部cL实现了一个接口的匿名cR而且只能实现一个接口?br /> <br /> C、参数式的匿名内部类?br /> class Bar{<br />     void doStuff(Foo f){}<br /> }<br /> <br /> interface Foo{<br />     void foo();<br /> }<br /> <br /> class Test{<br />     static void go(){<br />         Bar b = new Bar();<br />         b.doStuff(new Foo(){<br />             public void foo(){<br />                 System.out.println("foofy");<br />             }<br />         });<br />     }<br /> }<br /> <br /> <br /> 5、静态嵌套类?br /> 从技术上Ԍ静态嵌套类不属于内部类。因为内部类与外部类׃n一U特D关p,更确切地说是对实例的׃n关系。而静态嵌套类则没有上q关pR它只是位置在另一个类的内部,因此也被UCؓ嵌套cR?br /> 静态的含义是该内部cd以像其他静态成员一P没有外部cd象时Q也能够讉K它。静态嵌套类不能讉K外部cȝ成员和方法?br />     class Outer{<br />         static class Inner{}<br />     }<br />     class Test {<br />         public static void main(String[] args){<br />             Outer.Inner n = new Outer.Inner();<br />         }<br />     } <br /> <img src ="http://www.tkk7.com/yjjlovewjf/aggbug/166277.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/yjjlovewjf/" target="_blank">wǒ愛伱--咑֩ </a> 2007-12-08 14:52 <a href="http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166277.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java语法ȝ - 异常http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166276.htmlwǒ愛伱--咑֩ wǒ愛伱--咑֩ Sat, 08 Dec 2007 06:48:00 GMThttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166276.htmlhttp://www.tkk7.com/yjjlovewjf/comments/166276.htmlhttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166276.html#Feedback0http://www.tkk7.com/yjjlovewjf/comments/commentRss/166276.htmlhttp://www.tkk7.com/yjjlovewjf/services/trackbacks/166276.html
软g开发中一个古老的说法是:80%的工作?0%的时间?0%是指查和处理错误所付出的努力。在许多语言中,~写查和处理错误的程序代码很乏味Qƈ使应用程序代码变得冗ѝ原因之一是它们的错误处理方式不是语a的一部分。尽如此,错误和处理仍然是Q何健壮应用程序最重要的组成部分?br />
Java提供了一U很好的机制Q用强制规定的Ş式来消除错误处理q程中随心所Ʋ的因素Q异常处理。它的优U之处在于不用~写Ҏ代码返回值就能很Ҏ地检错误。而且它让我们把异常处理代码明地与异生代码分开Q代码变得更有条理。异常处理也是Java中唯一正式的错误报告机制?br />
W一部分    异常

1、抛出异常。所有的标准异常c都有两个构造器Q一个是~省构造器Q一个是带参数的构造器Q以便把相关信息攑օ异常对象中?br />     throw new NullPointerException();
    throw new NullPointerException("t = null");

2、如果有一个或者多个catch块,则它们必ȝ跟在try块之后,而且q些catch块必M相紧跟着Q不能有其他M代码。C++没有q样的限Ӟ所以C++的异常处理处理不好就会写得很乱,抛来拋去的?br />
3、用try块把可能出现异常的代码包含在其中Q这么做的好处是Q处理某U指定的异常的代码,只需~写一ơ。作业没写完的同学到走廊|站去,q符合我们处理问题的方式Q不用挨个地告诉?br />
4、无论是否抛出异常,finally块封装的代码总能够在try块之后的某点执行?br /> 例子Q?br />     try {
        return ;    
    }
    finally{
        System.out.print("You can't jump out of my hand!");    
    }

甚至你在try块内用return语句惌q去都不可以Qfinally内的输出语句q是执行了!别想逃出我的手掌心!

5、catch块和finally块是可选的Q你可以只用try。但是这么做有意思吗Q?br />
6、推卸责仅RJava允许你推卸责任,没有必要从相应的try块ؓ每个可能的异帔R~写catch子句。Java2cd中很多方法都会抛出异常,是是把异常处理的权限交l了我们用户。毕竟,Java不知道你的自行R被偷了之后,你会L案还是会忍气吞声自认倒霉Q或者偷别h的自行R。我们需要这U处理异常的自由度?br />
7、调用栈。调用栈是程序执行以讉K当前Ҏ的方法链。被调用的最后一个方法在栈的剙Q它被最先执行完毕,然后弹出Q第一个调用方法位于底部,也就是main函数。在catch子句中用printStackTrace()Ҏ打调用栈信息是比较常用的定位异常的方法。printStackTrace()l承自Throwable?br />
8、异常的传播。在一个方法A中,如果一个异常没有得到处理,它就会被自动抛到调用AҎ的BҎ中。如果BҎ也没有处理这个异常,他就会被l箋依次向上抛,直到mainҎ。如果main也没有理会它Q那么异常将DJVM停止Q程序就中止了。你被同学揍了,先去告诉老师。老师不理你你去告诉教导处主任,教导处主M不管那只能告诉校长,校长q不!没有比他更大的了Q于是你崩溃了,学业中止?#8230;…下面q段E序记录了悲惨的辍学历史Q?br />     class ExceptionDemo {
        static void student() throws Exception{
            teacher();
        }
        static void teacher() throws Exception{
            schoolmaster();
        }
        static void schoolmaster() throws Exception{
            throw new Exception();
        }
        public static void main(String[] args) {
            try {
            student();
        }
        catch (Exception e) {
            e.printStackTrace();
        }         
        }
    }
输出l果是:
java.lang.Exception
    at ExceptionDemo.schoolmaster(ExceptionDemo.java:9)
    at ExceptionDemo.teacher(ExceptionDemo.java:6)
    at ExceptionDemo.student(ExceptionDemo.java:3)
    at ExceptionDemo.main(ExceptionDemo.java:13)
可以看出函数的调用栈Q一U一U地哭诉……

9、异常的层次l构及Error?br />         Object
        Throwable
    Error        Exception
Throwablel承自ObjectQError和Exceptionl承自Throwable。Error比较ҎQ它对应于我们常说的不可抗拒的外力,房屋中介的合同上L一条,如遇不可抗拒的外力本合同中止Q返q乙Ҏ金。我不安地问Q不可抗拒的外力指什么?中介回答Q比如战争、彗星撞d球等。对Java来说Error是指JVM内存耗尽{这cM是程序错误或者其他事情引LҎ情况。一般地Q程序不能从Error中恢复,因此你可以能眼睁睁地看着E序崩溃而不必责怪自己。严格来ԌError不是异常Q因为它不是l承自Exception?br />
10、谁之错Q一般地Q异怸是我们程序员的错Q不是程序设计上的缺陗比如读取一个重要文Ӟq个文g被用戯删了Q正上着|呢Q网U被用户的宠物咬断了。ؓ了程序的健壮性,我们量考虑出现可能性大的异常,q处理,但我们不能穷?br />
11、异常的捕获之一。catch子句的参数是某种cd异常的对象,如果抛出的异常是该参数的子类Q那么这个异常将被它捕获。也是说被抛出的异怸会精地L最匚w的捕莯(catch子句Q,只要是它的承结构的直系上层可以捕获它?br />
按照q个逻辑Qcatch(Exception e) 不就能捕h有的异常吗?事实上,实如此?但是一般地Q不使用q种一站式的异常处理。因样就丢失了具体的异常信息Q不能ؓ某个具体的异常编写相应的异常处理代码Q失M异常处理的意义。从哲学角度来讲Q具体问题要具体分析Q能ȝ病的万能药一般都是无效的保健品?br />
Java在此处ؓ什么这么设计呢Q因为有另一U机制的存在Q请看下条分解?br />
12、异常的捕获之二。当抛出一个异常时QJava试图L一个能捕获它的catch子句Q如果没扑ֈ׃沿着栈向下传播。这个过E就是异常匹配。Java规定Q最具体的异常处理程序必LL攑֜更普通异常处理程序的前面。这条规定再合理不过了,试想如果把catch(Exception e)攑֜最上面Q那么下面的catch子句岂不是永q不能执行了Q如果你非要把更普遍的异常处理放在前面,对不P通不q编译!虽然~译器不会这h错:“It is so stupid to do like that!”……

13、捕h声明规则。如果在一个方法中抛出异常Q你有两个选择Q要么用catch子句捕获所有的异常Q要么在Ҏ中声明将要抛出的异常,否则~译器不会让你得逞的?br /> Ҏ一Q处理异?br />     void ex(){
        try{
            throw new Exception();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
Ҏ二:抛出?br />     void ex() throws Exception{
        throw new Exception();
    }
比较一下行数就知道了,在代码的世界里推卸责M是那么简单,一个throws关键字包含了多少人生哲理?#8230;…现实生活中我们有很多角色Q儿奟뀁父母、学生、老师、老板、员?#8230;…每个人都占了几条。可是你能尽到所有责dQ按照古代的孝道Q父母尚在h世就不能q行。各U责L有矛盄Q顾此失彼啊?br />
但是q条规则有个特例。一个承自Exception名ؓRuntimeException的子c,也就是运行时异常Q不受上q规则的限制。下面的代码完全能编译,只不q调用之后在q行时会抛出异常?br />     void ex(){
        throw new RuntimeException();
    }

14、throw和thrwos关键字。throw用在Ҏ体中抛出异常Q后面是一个具体的异常对象。throws用在Ҏ参数列表括号的后面,用来声明此方法会抛出的异常种c,后面跟着一个异常类?br />
15、非查异常。RuntimeException、Error以及它们的子c都是非查异常,不要求定义或处理非检查异常。Java2cd中有很多Ҏ抛出查异常,因此会常常编写异常处理程序来处理不是你编写的Ҏ产生的异常。这U机制强制开发h员处理错误,使得JavaE序更加健壮Q安全?br />
16、自定义异常cd。觉得现有的异常无法描述你想抛出的异常,okQJava允许你自定义异常cdQ只需要承Exception或者它的子c,然后换上有个性的名字?br />     class NotEnoughMoney extends Exception {
        public NotEnoughMoney() {}
        public NotEnoughMoney(String msg) { super(msg); }
    }
希望大家在生z里不要抛出cM的异常?br />
17、重新抛出异常。一个很无聊的话题,Ua的语法研IӞ实际意义不大。当catch子句捕获到异怹后可以重新抛出,那么它所在的Ҏ必须声明该异常?br />     void ex() throws Exception{
        try {
            throw new Exception();
        }
        catch (Exception mex) {
            throw me;
        }    
    }

18、异常处理机制的效率。待补充……

19、终止与恢复模型。异常处理理Z有两U模型:
一、终止模型。错误很关键且无法挽回,再执行下M没意义,只能中止?#8220;|密Ƨ,我们分手吧!”“好吧Q朱丽叶Q?#8221;
二、恢复模型。经q错误修正重新尝试调用原来出问题的方法?#8220;|密Ƨ,我们分手吧!”“׃Ӟ我错了!请再原谅我一ơ吧Q?#8221;“好的Q再原谅你最后一ơ!”
昄我们更喜Ƣ恢复模型,但在实际中,q种模式是不易实现和l护的?br /> 例子Q用戯入了非法的字W,分别按照两种模式处理
一、终止模型。输出出错信息而已Q一旦用h一抖眼一׃的代码就崩溃?br />     double number;
    String sNumber = "";
    try {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        sNumber = bf.readLine();
        number = Double.parseDouble(sNumber);    
    } catch (IOException ioe) {
        System.err.println("some IOException");
    } catch (NumberFormatException nfe) {
        System.err.println(sNumber + " is Not a legal number!");
    }
    //System.out.println(number);

二、恢复模型。小P不输入正的数据cd别想离开Q?br />     double number = 0;
    String sNumber = "";
    while(true){
        try {
            BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
            sNumber = bf.readLine();
            number = Double.parseDouble(sNumber);
            break;    //如果代码能执行到q一行,p明没有抛出异?br />         } catch (IOException ioe) {
            System.err.println("some IOException");
        } catch (NumberFormatException nfe) {
            System.err.println(sNumber + " is Not a legal number!");
        }
    }
    System.out.println(number);

直到用户输入正确的信息才会被该代码放q。这是一U简单的恢复模型的实玎ͼ看的,我很喜欢Q?br />
20、try、catch、finally内变量的作用域和可见性?br /> 在try块内定义的变量,它在catch或者finally块内都是无法讉K到的Qƈ且在整个异常处理语句之外也是不可见的?br /> 补充一点初始化Q第一个例中最后一句被注释掉了。number是在q行时由用户输入而初始化的,但是在编译时dƈ没有初始化,~译器会抱怨的?br />
21、输出异怿息。捕捉到异常之后Q通常我们会输出相关的信息Q以便更加明异常?br />     catch (Exception mex) {
        System.err.println("caught a exception!");
    }
用标准错误流System.err比System.out要好。因为System.out也许会被重定向,System.err则不会?br />
22、更高的话题我会补充上的,但是我的肚子抛出了Hungry异常Q我必须catch然后调用eat()Ҏ补充能量。昨晚的鱉K盖浇饭很好吃……


wǒ愛伱--咑֩ 2007-12-08 14:48 发表评论
]]>
Java语法ȝ - 字符?/title><link>http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166273.html</link><dc:creator>wǒ愛伱--咑֩ </dc:creator><author>wǒ愛伱--咑֩ </author><pubDate>Sat, 08 Dec 2007 06:34:00 GMT</pubDate><guid>http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166273.html</guid><wfw:comment>http://www.tkk7.com/yjjlovewjf/comments/166273.html</wfw:comment><comments>http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166273.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/yjjlovewjf/comments/commentRss/166273.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/yjjlovewjf/services/trackbacks/166273.html</trackback:ping><description><![CDATA[<br /> <br /> Java的String太特别了Q也太常用了Q所以重要。我初学Javap它搞蒙了Q太多؜淆的概念了,比如它的不变性。所以必L入机制地ȝ解它?br /> <br /> <br /> 1、String中的每个字符都是一?6位的Unicode字符Q用Unicode很容易表达丰富的国际化字W集Q比如很好的中文支持。甚至Java的标识符都可以用汉字Q但是没Z用吧Q只在一本清华的《Java2实用教程》看q)?br /> <br /> 2、判断空字符丌Ӏ根据需要自己选择某个或者它们的l合<br />     if ( s == null )    //从引用的角度<br />     if ( s.length() == 0 )     //从长度判?br />     if ( s.trim().length () == 0 )     //是否有多个空白字W?br /> trim()Ҏ的作用是是移除前导和N的Unicode值小?"u0020'的字W,q返?#8220;修剪”好的字符丌Ӏ这U方法很常用Q比如需要用戯入用户名Q用户不心加了前导或者尾部空|一个好的程序应该知道用户不是故意的Q即使是故意的也应该点地处理?br /> 判断IZ是很常用的操作,但是Javacd直到1.6才提供了isEmpty()Ҏ。当且仅?length() ?0 时返?true?br /> <br /> 3、未初始化、空?"与null。它们是不同的概c对未初始化的对象操作会被编译器挡在门外Qnull是一个特D的初始化|是一个不指向M对象的引用,对引用ؓnull的对象操作会在运行时抛出异常NullPointerExceptionQ而空串是长度?的字W串Q和别的字符串的唯一区别是长度??br /> 例子Q?br />     public class StringTest{<br />         static String s1;<br />         public static void main(String[] args) {<br />             String s2;<br />             String s3 = "";<br />             System.out.print(s1.isEmpty());     //q行时异?br />             System.out.print(s2.isEmpty());     //~译出错<br />             System.out.print(s3.isEmpty());     //okQ输出true<br />         }<br />     }<br /> <br /> 4、StringcȝҎ很多Q在~写相关代码的时候看看JDK文档时有好处的,要不然花了大量时间实C个已l存在的Ҏ是很不值得的,因ؓ~写、测试、维护自q代码佉K目的成本增加Q利润减,严重的话会导致开不出工资……<br /> <br /> 5、字W串的比较?br /> Java不允许自定义操作W重载,因此字符串的比较要用compareTo() 或?compareToIgnoreCase()。s1.compareTo(s2)Q返回值大?则,则前者大Q等?Q一般大Q小?Q后者大。比较的依据是字W串中各个字W的Unicode倹{?br /> <br /> 6、toString()Ҏ?br /> Java的Q何对象都有toString()ҎQ是从Object对象l承而来的。它的作用就是让对象在输出时看v来更有意义,而不是奇怪的对象的内存地址。对试也是很有帮助的?br /> <br /> 7、String对象是不变的Q可以变化的是String对象的引用?br /> String name = "ray";<br /> name.concat("long");  //字符串连?br /> System.out.println(name); //输出nameQokQ还?ray"<br /> name = name.concat("long");  //把字W串对象q接的结果赋l了name引用<br /> System.out.println(name);  //输出nameQohQ,变成?raylong"<br /> 上述三条语句其实产生?个String对象Q?ray"Q?long"Q?raylong"。第2条语句确实生了"raylong"字符Ԍ但是没有指定把该字符串的引用赋给谁,因此没有改变name引用。第3条语句根据不变性,q没有改?ray"QJVM创徏了一个新的对象,?ray"Q?long"的连接赋l了name引用Q因此引用变了,但是原对象没变?br /> <br /> 8、String的不变性的机制昄会在String帔R内有大量的冗余。如Q?1" + "2" + "3" +......+ "n" 产生了n+(n+1)个String对象Q因此JavaZ更有效地使用内存QJVM留出一块特D的内存区域Q被UCؓ“String帔R?#8221;。对String多么照顾啊!当编译器遇见String帔R的时候,它检查该池内是否已经存在相同的String帔R。如果找刎ͼ把新常量的引用指向现有的StringQ不创徏M新的String帔R对象?br /> <br /> 那么可能出现多个引用指向同一个String帔RQ会不会有别名的危险呢?No problemQString对象的不变性可以保证不会出现别名问题!q是String对象与普通对象的一点区别?br /> <br /> 乍看hq是底层的机ӞҎ们编E没什么媄响。而且q种机制会大q度提高String的效率,实际上却不是q样。ؓq接n个字W串使用字符串连接操作时Q要消耗的旉是n的^方Q因为每两个字符串连接,它们的内定w要被复制。因此在处理大量的字W串q接Ӟ而且要求性能Ӟ我们不要用StringQStringBuffer是更好的选择?br /> <br /> 8、StringBuffercRStringBuffercL可变的,不会在字W串帔R池中Q而是在堆中,不会留下一大堆无用的对象。而且它可字W串~冲区安全地用于多个U程。每个StringBuffer对象都有一定的定w。只要StringBuffer对象所包含的字W序列的长度没有出此容量,无需分配新的内部~冲区数l。如果内部缓冲区溢出Q则此容量自动增大。这个固定的定w?6个字W。我l这U算法v个名字叫“添饭法”。先l你一满碗饭,不够了再l你一满碗饭?br /> 例子Q?br />     StringBuffer sb = new StringBuffer();    //初始定w?16 个字W?br />     sb.append("1234");    //q是4个字W,那么16个字W的定wp够了Q没有溢?br />     System.out.println(sb.length());    //输出字符串长度是4<br />     System.out.println(sb.capacity());    //输出该字W串~冲区的定w?6<br /> <br />     sb.append("12345678901234567");        //q是17个字W,16个字W的定w不够了,扩容?7+16个字W的定w<br />     System.out.println(sb.length());    //输出字符串长度是17<br />     System.out.println(sb.capacity());    //输出该字W串~冲区的定w?4<br /> <br />     sb.append("890").reverse().insert(10,"-");    <br />     System.out.println(sb);        //输出0987654321-09876543214321<br /> <br /> 字符串的长度和字W缓冲区的容量是两个概念Q注意区别?br /> q有串联的方式看h是不是很P用返回D接v来可以实现这U简z和优雅?br /> <br /> 10、StringBuildercR?从J2SE 5.0 提供了StringBuilderc,它和StringBuffercL孪生兄弟Q很像。它存在的h值在于:对字W串操作的效率更高。不的是线E安全无法保证,不保证同步。那么两者性能到底差多呢Q很多!<br /> 请参阅:http://book.csdn.net/bookfiles/135/1001354628.shtml<br /> 实践Q?br /> 单个U程的时候用StringBuilderc,以提高效率,而且它的API和StringBuffer兼容Q不需要额外的学习成本Q物h廉。多U程时用StringBufferQ以保证安全?br /> <br /> 11、字W串的比较?br /> 下面q条可能会让你晕Q所以你可以选择看或者不看。它不会对你的职业生涯造成M影响。而且谨记一条,比较字符串要用equals()ok了!一旦用?#8220;==”׃出现很怪异的现象。之所以把q部分放在最后,是想节省大家的时_因ؓq条又臭又长。推荐三UhQ一、没事闲着型。二、想深入地理解Java的字W串Q即使明明知道学了也没用。三、和我一L好研I?#8220;?#8221;字有几种写法?br /> <br /> q是那句老话QString太特D了Q以至于某些规则对String不v作用。个人感觉这U特D性ƈ不好。看例子Q?br /> 例子AQ?br />     String str1 = "java";<br />     String str2 = "java";<br />     System.out.print(str1==str2);<br /> 地球上有点Java基础的h都知道会输出falseQ因?=比较的是引用Qequals比较的是内容。不是我忽悠大家Q你们可以在自己的机子上q行一下,l果是trueQ原因很单,String对象被放q常量池里了Q再ơ出?#8220;java”字符串的时候,JVM很兴奋地把str2的引用也指向?#8220;java”对象Q它认ؓ自己节省了内存开销。不隄解吧 呵呵<br /> 例子BQ?br />     String str1 = new String("java");<br />     String str2 = new String("java");<br />     System.out.print(str1==str2);<br /> 看过上例的都学聪明了Q这ơ肯定会输出trueQ很不幸QJVMq没有这么做Q结果是false。原因很单,例子A中那U声明的方式实是在String帔R池创?#8220;java”对象Q但是一旦看到new关键字,JVM会在堆中为String分配I间。两者声明方式貌合神,q也是我?#8220;如何创徏字符串对?#8221;攑ֈ后面来讲的原因。大家要沉住气,q有一个例子?br /> 例子CQ?br />     String str1 = "java";<br />     String str2 = "blog";<br />     String s = str1+str2;<br />     System.out.print(s=="javablog");<br /> 再看q个例子Q很多同志不敢妄a是trueq是false了吧。爱玩脑{急{弯的Z说是false?#8230;…恭喜你,你会抢答了!把那?#8220;?#8221;字去掉你完全正。原因很单,JVM实会对型如String str1 = "java"; 的String对象攑֜字符串常量池里,但是它是在编译时刻那么做的,而String s = str1+str2; 是在q行时刻才能知道Q我们当然一眼就看穿了,可是Java必须在运行时才知道的Qh脑和电脑的结构不同)Q也是说str1+str2是在堆里创徏的,s引用当然不可能指向字W串帔R池里的对象。没崩溃的hl箋看例子D?br /> 例子DQ?br />     String s1 = "java";<br />     String s2 = new String("java");<br />     System.out.print(s1.intern()==s2.intern());<br /> intern()是什么东东?反正l果是true。如果没用过q个ҎQ而且训练有素的程序员会去看JDK文档了。简单点说就是用intern()Ҏ可以用“==”比较字符串的内容了。在我看到intern()Ҏ到底有什么用之前Q我认ؓ它太多余了。其实我写的q一条也很多余,intern()Ҏq存在诸多的问题Q如效率、实C的不l一……<br /> 例子EQ?br />     String str1 = "java";<br />     String str2 = new String("java");<br />     System.out.print(str1.equals(str2));<br /> 无论在常量池q是堆中的对象,用equals()Ҏ比较的就是内容,p么简单!看完此条的h一定很后悔Q但是在开始我劝你别看?#8230;…<br /> <br /> 后记Q用彪哥的话?#8220;有意思吗Q?#8221;Q确实没劌Ӏ在写这D늚时候我也是思量再三Q感觉自己像孔乙q耀“?#8221;字有几种写法。我查了一下茴 Q回Q囘Q囬Q还有一U是“?#8221;字里面有?#8220;?#8221;字,后面q四个都加上草字?#8230;…<br /> <img src ="http://www.tkk7.com/yjjlovewjf/aggbug/166273.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/yjjlovewjf/" target="_blank">wǒ愛伱--咑֩ </a> 2007-12-08 14:34 <a href="http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166273.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java语法ȝ - 数组http://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166272.htmlwǒ愛伱--咑֩ wǒ愛伱--咑֩ Sat, 08 Dec 2007 06:32:00 GMThttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166272.htmlhttp://www.tkk7.com/yjjlovewjf/comments/166272.htmlhttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166272.html#Feedback0http://www.tkk7.com/yjjlovewjf/comments/commentRss/166272.htmlhttp://www.tkk7.com/yjjlovewjf/services/trackbacks/166272.html
数组QarrayQ是相同cd变量的集合,可以使用共同的名字引用它。数l可被定义ؓMcdQ可以是一l或多维。数l中的一个特别要素是通过下标来访问它。数l提供了一U将有联pȝ信息分组的便利方法。注意:如果你熟悉C/C++Q请注意Q?Java数组的工作原理与它们不同?br />
1、数l不是集合,它只能保存同U类型的多个原始cd或者对象的引用。数l保存的仅仅是对象的引用Q而不是对象本w?br />
2、数l本w就是对象,Java中对象是在堆中的Q因此数l无Z存原始类型还是其他对象类型,数组对象本n是在堆中的?br />
3、数l声明的两种形式Q一、int[] arr; 二、int arr[];  推荐使用前者,q符合Sun的命名规范,而且Ҏ了解到关键点Q这是一个int数组对象Q而不是一个int原始cd?br />
4、在数组声明中包含数l长度永q是不合法的Q如Qint[5] arr; 。因为,声明的时候ƈ没有实例化Q何对象,只有在实例化数组对象ӞJVM才分配空_q时才与长度有关?br />
5、在数组构造的时候必L定长度,因ؓJVM要知道需要在堆上分配多少I间。反例:int[] arr = new int[];

6、多l数l的声明。int[][][] arr; 是三lint型数l?br />
7、一l数l的构造。Ş如:String[] sa = new String[5]; 或者分成两句:String[] sa;  sa = new String[5];

8、原始类型数l元素的默认倹{对于原始类型数l,在用new构造完成而没有初始化ӞJVM自动对其q行初始化。默认|byte、short?int、long--0  float--0.0f double--0.0  boolean--false  char--'"u0000'。(无论该数l是成员变量q是局部变量)

9、对象类型数l中的引用被默认初始化ؓnull。如QCar[] myCar = new Car[10]; 相当于从myCar[0]到myCar[9]都这栯自动初始化ؓmyCar[i] = null;

10、对象类型的数组虽然被默认初始化了,但是q没有调用其构造函数。也是_Car[] myCar = new Car[10];只创Z一个myCar数组对象Qƈ没有创徏Car对象的Q何实例!

11、多l数l的构造。float[][] ratings = new float[9][]; W一l的长度必须l出Q其余的可以不写Q因为JVM只需要知道赋l变量ratings的对象的长度?br />
12、数l烦引的范围。数l中各个元素的烦引是?开始的Q到length-1。每个数l对象都有一个length属性,它保存了该数l对象的长度。(注意和String对象的length()Ҏ区分开来,q两者没有统一h是很遗憾的。)

13、Java有数l下标检查,当访问超出烦引范围时Q将产生ArrayIndexOutOfBoundsExceptionq行时异常。注意,q种下标查不是在~译时刻q行的,而是在运行时Q也是说int[] arr = new int[10];  arr[100] = 100; q么明显的错误可以通过~译Q但在运行时抛出QJava的数l下标检查是需要额外开销的,但是Z安全的权衡还是值得的,因ؓ很多语言在用数l时是不安全的,可以L讉K自n内存块外的数l,~译q行都不会报错,产生难以预料的后果!


wǒ愛伱--咑֩ 2007-12-08 14:32 发表评论
]]>
Java语法ȝ - 基本数据cdhttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166270.htmlwǒ愛伱--咑֩ wǒ愛伱--咑֩ Sat, 08 Dec 2007 06:27:00 GMThttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166270.htmlhttp://www.tkk7.com/yjjlovewjf/comments/166270.htmlhttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166270.html#Feedback0http://www.tkk7.com/yjjlovewjf/comments/commentRss/166270.htmlhttp://www.tkk7.com/yjjlovewjf/services/trackbacks/166270.htmlJava不是U的面向对象的语aQ不U的地方是q些基本数据cd不是对象。当然初期Java的运行速度很慢Q基本数据类型能在一定程度上改善性能。如果你想编写纯的面向对象的E序Q用包装器类是取代基本数据类型就可以了?br />
1、基本类型的存储I间。byte--8位,short--16位,int--32位,long--64位,float--32位,double--64位。这六种数字cd都是有符L。固定的存储I间正是Java可移植性、跨q_的原因之一Q?br />
2、基本类型的存在D了Java OOP的不Ua性。因为基本类型不是对象,一切皆对象是个小的谎a。这是出于执行效率的权衡?br />
3、用公?2的(位数-1Q次q到2的(位数-1Q次q?1定整数cd的范_byte、short、int、longQ?br />
4、char?6位Unicode字符或者说?6位无W号整数Q范围从0?5535。即便如此,可以强制转换非法的数据,如:char c1 = (char) 10000;  char c2 = (char) -200;。可以从二进制存储的角度理解q点?br />
5、整数有八进Ӟ?开头的整数Q、十q制、十六进Ӟ?x?X开头的整数Q表C?br />
6、char可以用单引号表示单个字符Q如Q??。也可以用unicode?"ucafe'Q四位十六进制数Q?br />
7、布型boolean。布型只能是true或者falseQƈ且测试它为真q是假。它不能q行M其他的运,或者{化ؓ其他cd?br /> 正例Qboolean b1 = 1 > 2;    反例Qint seen = button.isVisible();
实践Q简z是dQ请不要q样写:if ( is == true && done == false ) Q只有新手才那么写?br /> 对于ME序?if ( whether && !done ) 都不隄解吧。所以去掉所有的==fasle ?==true?br />
8、默认的点cd是双_ֺQdoubleQ,要想要一个float必须在QҎ后面加F或者f。如Qfloat pi = 3.14;是错误的?br />
9、默认的整数cd是int型,要想使用长整型可在后面加“l”?#8220;L”Q如Q?000L。(写lҎ被误认ؓ1Q不推荐用)

10、float可以_?位有效数字,W?位的数字是第9位数字四舍五入上取得的;double可以_?6位有效数字,W?7位的数字是第18位数字四舍五入上取得的。盖茨到底有多少钱?要用double表示Q用float是装不下?#8230;…

11、如果要求精的{案Q请不要使用float和doubleQ因为它们是Z在广域数D围上提供较ؓ_的快速近D而精心设计的。然而,它们没有提供完全_的结果。尤其是对货币计尤Z适合Q因让一个float或double_地表?.1Q或?0的Q何)

12、BigInteger支持L_ֺ的整数。BigDecimal支持L_ֺ的定Ҏ?br />
13、初始化无论怎么都不q分QJava为所有的成员变量提供了默认初始化Qbyte、short?int、long--0  float--0.0f double--0.0  boolean--false  char--'"u0000'Q特别地对象cd的引用全被初始化为null。(注意Q除了数l之外的局部变量是得不到这U优待的Q需要你自己初始化。另外,默认初始化的值是你想要的吗?所以最好明地对变量进行初始化Q一般是在构造函C。)

14、基本类型之间的转化。Java的类型检查很严格Q从低精度{换到高精度是无须昑ּ转换的,double d = 123;。但是反q来Q进行窄化{换,由高_ֺ向低_ֺQ或者一U类型到另一U类型,则必M用强制类型{化。Java提供了安全{化机Ӟ但是l果是否是期望的Q你自己保证吧?br /> double d = 12.5;
float f = (int) d; //l果不是13Q而是12Q?br /> 点型{化ؓ整型Ӟ不进行四舍五入,直接截断数点后面的数?br />
15、提升。各U基本数据类型进行؜合运,l果会是表达能力最强的那种。如Qint和longq算Q结果是longQ整型和点型运结果是点型。特D的一ҎQ只要类型比int(如char、byte、shortQ,那么在运之前,q些g自动地{换成int。例子:
byte b1 = 12;
byte b2 = b1 + 1; //在编译时出错了!因ؓb1+1已经是int型了Q切讎ͼ

16、Q点类型的U学表示法。在数学中e代表自然ҎQMath.El出了double|Q而在Java中e代表10的幂ơ。Q点型的数可以q样表示float f = 1e-27f; 代表1乘以10的负27ơ幂?br />



wǒ愛伱--咑֩ 2007-12-08 14:27 发表评论
]]>
Java API introducehttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166230.htmlwǒ愛伱--咑֩ wǒ愛伱--咑֩ Sat, 08 Dec 2007 03:30:00 GMThttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166230.htmlhttp://www.tkk7.com/yjjlovewjf/comments/166230.htmlhttp://www.tkk7.com/yjjlovewjf/archive/2007/12/08/166230.html#Feedback0http://www.tkk7.com/yjjlovewjf/comments/commentRss/166230.htmlhttp://www.tkk7.com/yjjlovewjf/services/trackbacks/166230.htmlJavacd׃下几个包l成Q?br /> java.lang
java.io
java.util
java.awt
java.applet
java.net

java基础cd在java.lang包中Q?br /> Object  class
method:
1.protected Object clone()
2.public boolean equals(Object obj)
3.public final class getClass()
4.protected void finalize()
5.public String toString()
6.public final void notify()

Math       class
method:
1.public static double abs(double d)
2.public static double exp(double d)求e的dơ幂
3.public static double floor(double d)求不大于d的最大整?br /> 4.public static double log(doulble d)求d 的自然对?br /> 5.public static double max(double d1,double d2)
6.public static double min(double d1,double d2)
7.public static double pow(double d1,double d2)d1的d2ơ方
8.public static double random()获取0~1中的随机?br /> 9.public static double rint(double d)求d的4舍5?br /> 10.pulblic static double sqrt(double d)
11.public static double sin(double d)
12.public static double cos(double d)
13.public static double tan(double d)
此全为静态变?.可用Math.method()表示


System    class
属?
public static InputStream in;
pulbic static PrintStream out;
public static PrintStream err;
method:
public static long currentTimeMillis()
public static void exit(int status)
public static void gc()强制调用虚拟机的垃圾回收功能


String      class
分ؓString cdStringBufferc?br /> String:
构造函?
public String();
public Stirng(StringValue);
public String(StringBuffer buffer);
public String(char value[]);
method:
public int length();
public boolean startsWith(String prefix)
public boolean endsWith(Stirng suffix)
查找字符串中指定的字W?br /> public int indexOf(char ch)
public int indexOf(char ch,int fromIndex)
public int lastIndexOf(char ch)
public int lastInderOf(char ch,int fromIndex)
查找字符串中指定的子?br /> public int indexOf(String str)
public int indexOf(String str,int fromIndex)
public int lastIndexOf(String str)
public int lastInderOf(String str,int fromIndex)
比较两字W串:
public int compareTo(String str)
public boolean equals(Object obj)
public boolean equalsIgnoreCase(String str)
q接两字W串
public String concat(String str)
求字W串中的字符和子?br /> public char chaAt(int index)
public String substirng(int startIndex,int endIndex)
public String substring(int startIndex)

StringBuffer:
构造函敎ͼ
public StringBuffer()
public StringBuffer(int length)
public StringBuffer(String str)
method:
public int length()
public int capacity()
public void setLength(int newLength)
public charAt(int index)
public void setChartAt(int index,char ch)
public StringBuffer append(<参数cd> <参数?gt;)
public StringBuffer insert(int <输入位置>,<参数cd> <参数?gt;)



wǒ愛伱--咑֩ 2007-12-08 11:30 发表评论
]]>
JAVA如何调用DOS命o http://www.tkk7.com/yjjlovewjf/archive/2007/12/05/165450.htmlwǒ愛伱--咑֩ wǒ愛伱--咑֩ Wed, 05 Dec 2007 04:30:00 GMThttp://www.tkk7.com/yjjlovewjf/archive/2007/12/05/165450.htmlhttp://www.tkk7.com/yjjlovewjf/comments/165450.htmlhttp://www.tkk7.com/yjjlovewjf/archive/2007/12/05/165450.html#Feedback2http://www.tkk7.com/yjjlovewjf/comments/commentRss/165450.htmlhttp://www.tkk7.com/yjjlovewjf/services/trackbacks/165450.html 用Java~写应用Ӟ有时需要在E序中调用另一个现成的可执行程序戒pȝ命oQ这时可以通过l合使用Java提供的RuntimecdProcesscȝҎ实现。下面是一U比较典型的E序模式Q?... Process process = Runtime.getRuntime().exec(".\\p.exe"); process.waitfor( ); ... 在上面的E序中,W一行的“.\\p.exe”是要执行的程序名QRuntime.getRuntime()q回当前应用E序的Runtime对象Q该对象的exec()Ҏ指示Java虚拟机创Z个子q程执行指定的可执行E序Qƈq回不该子进E对应的Process对象实例。通过Process可以控制该子q程的执行戒获取该子q程的信息。第二条语句的目的等待子q程完成再往下执行?但在windowsq_上,如果处理丌当Q有时ƈ丌能得到预期的结果。下面是W者在实际~程中ȝ的几U需要注意的情冴Q?1、执行DOS的内部命?如果要执行一条DOS内部命oQ有两种Ҏ。一U方法是把命令解释器包含在exec()的参C。例如,执行dir命oQ在NT上, 可写成exec("cmd.exe /c dir")Q在windows 95/98下,可写?#8220;command.exe /c dir”Q其中参?#8220;/c”表示命o执行后关闭Dos立即关闭H口。另一U方法是Q把内部命o攑֜一个批命omy_dir.bat文g中,在JavaE序中写成exec("my_dir.bat")。如果仅仅写成exec("dir")QJava虚拟机则会报q行旉误。前一U方法要保证E序的可UL性,需要在E序中读取运行的操作pȝq_Q以调用丌同的命令解释器。后一U方法则丌需要做更多的处理?2、打开一个丌可执行的文g 打开一个丌可执行的文gQ但该文件存在关联的应用E序Q则可以有两U方式?以打开一个word文档a.doc文gZQJava中可以有以下两种写法Q?exec("start .\\a.doc"); exec(" c:\\Program Files\\Microsoft Office\\office\\winword.exe .\\a.doc"); 昄Q前一U方法更为简hѝ?3、执行一个有标准输出的DOS可执行程?br /> 在windowsq_上,q行被调用程序的DOSH口在程序执行完毕后往往q丌会自动关闭,从而导致Java应用E序d在waitfor( )。导致该现象的一个可能的原因是,该可执行E序的标准输出比较多Q而运行窗口的标准输出~冲Z够大。解决的办法是,利用Java提供的ProcesscL供的Ҏ让Java虚拟机截莯调用E序的DOSq行H口的标准输出,在waitfor()命o之前dH口的标准输出缓冲区中的内容。一D典型的E序如下Q?... String ls_1; Process process = Runtime.getRuntime().exec("cmd /c dir \\windows"); BufferedReader bufferedReader = new BufferedReader( \ new InputStreamReader(process.getInputStream()); while ( (ls_1=bufferedReader.readLine()) != null) System.out.println(ls_1); ?process.waitfor( ); ...
以上内容{载~下面内容为原创! 今天在做客户端程序的自动更新Q简单描qC下,是从服务器上将更新包下载下来,然后在本地解压羃Q最后删掉~功能很简单~ 但是问题出在使用JAVA的ZIP模块做文件的解压~丌是想象的那么单,资源需要释放,一个丌心没有办法删除掉原有ZIP文g了~资源的占用确实是个大问题Q但是好在,客户端程序更新完是要重启的,一切都烟消云散了~对于删除丌掉ZIP文g的问题,我也氓一下~用DEL删除~此处一定要注意Q?Process process = Runtime.getRuntime().exec("cmd /c del f:\\aaa.doc"); q样的调用是没有问题~
Process process = Runtime.getRuntime().exec("del f:\\aaa.doc"); q样写是丌可能对的~ 记录一下,警告一下后人!

wǒ愛伱--咑֩ 2007-12-05 12:30 发表评论
]]>
AWT, SWT, Swing: Java GUI Clean Uphttp://www.tkk7.com/yjjlovewjf/archive/2007/12/05/165449.htmlwǒ愛伱--咑֩ wǒ愛伱--咑֩ Wed, 05 Dec 2007 04:25:00 GMThttp://www.tkk7.com/yjjlovewjf/archive/2007/12/05/165449.htmlhttp://www.tkk7.com/yjjlovewjf/comments/165449.htmlhttp://www.tkk7.com/yjjlovewjf/archive/2007/12/05/165449.html#Feedback0http://www.tkk7.com/yjjlovewjf/comments/commentRss/165449.htmlhttp://www.tkk7.com/yjjlovewjf/services/trackbacks/165449.html阅读全文

wǒ愛伱--咑֩ 2007-12-05 12:25 发表评论
]]>
JAVA 初学单词?/title><link>http://www.tkk7.com/yjjlovewjf/archive/2007/12/04/165341.html</link><dc:creator>wǒ愛伱--咑֩ </dc:creator><author>wǒ愛伱--咑֩ </author><pubDate>Tue, 04 Dec 2007 15:34:00 GMT</pubDate><guid>http://www.tkk7.com/yjjlovewjf/archive/2007/12/04/165341.html</guid><wfw:comment>http://www.tkk7.com/yjjlovewjf/comments/165341.html</wfw:comment><comments>http://www.tkk7.com/yjjlovewjf/archive/2007/12/04/165341.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/yjjlovewjf/comments/commentRss/165341.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/yjjlovewjf/services/trackbacks/165341.html</trackback:ping><description><![CDATA[<div id="l7phprz" class="t_msgfont" id="postmessage_978834">Abstract window toolkit(AWT) 抽象H口工具?br /> Abstraction 抽象<br /> Anonymous class 匿名c?br /> Anonymous inner class 匿名内部c?br /> Application programming interface(API) 应用<span id="7t9jrzx" class="t_tag" onclick="tagshow(event)" href="tag.php?name=%E7%A8%8B%E5%BA%8F">E序</span>接口<br /> Array 数组<br /> Attribute 属?br /> Base class 父类<br /> Byte stream 字节?br /> Casting cd转换<br /> Character <span id="179f99t" class="t_tag" onclick="tagshow(event)" href="tag.php?name=%E5%AD%97%E7%AC%A6">字符</span><br /> Character stream 字符?br /> Child class 子类<br /> Class c?br /> Class member cL?br /> Class method cL?br /> Class variable cd?br /> Collection interface Collection接口<br /> Constructor 构造方?br /> Container 容器<br /> Data Definition Language(DDL) 数据定义<span id="l7thn1z" class="t_tag" onclick="tagshow(event)" href="tag.php?name=%E8%AF%AD%E8%A8%80">语言</span><br /> Data source <span id="7nfz97z" class="t_tag" onclick="tagshow(event)" href="tag.php?name=%E6%95%B0%E6%8D%AE%E6%BA%90">数据?/span><br /> Database Management System(DBMS) <span id="17zbbvt" class="t_tag" onclick="tagshow(event)" href="tag.php?name=%E6%95%B0%E6%8D%AE%E5%BA%93">数据?/span>理pȝ<br /> Declaration 声名<br /> Derived classzcR子c?br /> Encapsulation装<br /> Event事g<br /> Event source事g?br /> Exception 异常<br /> Exception handing 异常处理<br /> Garbage collection 垃圾回收机指<br /> Generalization 一般化Q?br /> Graphics User Interface(GUI) 囑Ş用户界面<br /> Identifier 标识W?br /> Inheritance l承<br /> Inner class 内部c?br /> Instance 实例<br /> Integrated Development Environment(IDE)集成开发环?br /> Interface 接口<br /> J2EE java2q_企业?br /> JDBC java数据库连?br /> JDK java开发工具包<br /> JFC java基础c?br /> JRM javaq行时环?br /> JVM java虚拟?br /> Keyword 关键?br /> Layout manager 布局理?br /> Local variable 局部变?br /> Member 成员<br /> Meta data 元数?br /> Method Ҏ<br /> Modifier 修饰W?br /> Multithread 多线E?br /> Object 对象<br /> OOP 面向对象~成<br /> ODBC 开攑ּ数据库连?br /> Overloaded method 重蝲Ҏ<br /> Overridden method 重写Ҏ<br /> Package ?br /> Parent class 父类<br /> Platform independent 跨^?br /> polymorphism 多?br /> Runtime exception q行时异?br /> Structured Query Language(SQL) l构?span class="t_tag" onclick="tagshow(event)" href="tag.php?name=%E6%9F%A5%E8%AF%A2">查询</span>语言<br /> <span id="pb9p99f" class="t_tag" onclick="tagshow(event)" href="tag.php?name=Sub">Sub</span> class 子类<br /> Super class 类Q父c?br /> Synchronized method 同步Ҏ<br /> Thread U程<br /> Uniform Resource Locator(URL) l一资源定位?br /> </div> <img src ="http://www.tkk7.com/yjjlovewjf/aggbug/165341.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/yjjlovewjf/" target="_blank">wǒ愛伱--咑֩ </a> 2007-12-04 23:34 <a href="http://www.tkk7.com/yjjlovewjf/archive/2007/12/04/165341.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://www52a.com" target="_blank">Ʒ޳AA߹ۿ </a>| <a href="http://adcbgy.com" target="_blank">츾AVպ츾</a>| <a href="http://747767.com" target="_blank">˳ӰԺ</a>| <a href="http://juguanghr.com" target="_blank">޼Ƶ</a>| <a href="http://caocl1024liu.com" target="_blank">AV뾫Ʒɫҹ </a>| <a href="http://155562.com" target="_blank">Ļѹۿ</a>| <a href="http://34007c.com" target="_blank">Ƶ69½</a>| <a href="http://jmdehong.com" target="_blank">պػɫƬƵ</a>| <a href="http://s4lm0x.com" target="_blank">ַѹۿ </a>| <a href="http://heifengmi.com" target="_blank">84paoǿѸ</a>| <a href="http://yanhx.com" target="_blank">9277ֻƵۿ</a>| <a href="http://941sese.com" target="_blank">Ļȫ </a>| <a href="http://www52a.com" target="_blank">˿wwwѸ </a>| <a href="http://19520888.com" target="_blank">þ޾Ʒgv</a>| <a href="http://pchbgs.com" target="_blank">ձϵ1ҳϵ</a>| <a href="http://baoyutv777.com" target="_blank">ѲŮһëƬ</a>| <a href="http://yu388.com" target="_blank">һëƬaѲɫӰ</a>| <a href="http://8izh.com" target="_blank">йڵëƬѸ</a>| <a href="http://ruidamo.com" target="_blank">ҳƵվ</a>| <a href="http://semaopu.com" target="_blank">**aaaaaëƬͬͬŮ</a>| <a href="http://xingdagx.com" target="_blank">Aѹۿ</a>| <a href="http://344zx.com" target="_blank">վ߹ۿ</a>| <a href="http://666fzw.com" target="_blank">ѹҹӰ</a>| <a href="http://wjjccw.com" target="_blank">ھƷþþþþþ</a>| <a href="http://zfjhw.com" target="_blank">AV߹ۿ</a>| <a href="http://1000hu.com" target="_blank">þþƷž޾Ʒ</a>| <a href="http://91haikala.com" target="_blank"></a>| <a href="http://haiwaizhuyun.com" target="_blank">ؼaa**ëƬѹۿ</a>| <a href="http://www321fafa.com" target="_blank">ҹ뾫Ʒѿ</a>| <a href="http://yjszhukao.com" target="_blank">9277ֻƵۿ</a>| <a href="http://tj-zhongfa.com" target="_blank">˿ҹëƬ</a>| <a href="http://001mc.com" target="_blank">޳aƬ߹ۿ</a>| <a href="http://lswqn.com" target="_blank">޹ƷרӰԺ</a>| <a href="http://directzx.com" target="_blank">޾Ʒվ</a>| <a href="http://fantoment.com" target="_blank">AV뾫Ʒҹ.</a>| <a href="http://mm9d.com" target="_blank">һػ¼Ƶ</a>| <a href="http://33sse.com" target="_blank">18ŮëƬˮ</a>| <a href="http://s8023.com" target="_blank">ձһaƵѹۿ</a>| <a href="http://91sebo.com" target="_blank">˾þô߽ۺͼƬ</a>| <a href="http://199044.com" target="_blank">777޾Ʒþþþþ </a>| <a href="http://jcss99.com" target="_blank">鶹91Ƶ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>