﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-我思故我强</title><link>http://www.blogjava.net/balajinima/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 12 Apr 2026 18:51:19 GMT</lastBuildDate><pubDate>Sun, 12 Apr 2026 18:51:19 GMT</pubDate><ttl>60</ttl><item><title>Java 设计模式与建模专题-Java 建模</title><link>http://www.blogjava.net/balajinima/articles/299405.html</link><dc:creator>李云泽</dc:creator><author>李云泽</author><pubDate>Thu, 22 Oct 2009 09:31:00 GMT</pubDate><guid>http://www.blogjava.net/balajinima/articles/299405.html</guid><wfw:comment>http://www.blogjava.net/balajinima/comments/299405.html</wfw:comment><comments>http://www.blogjava.net/balajinima/articles/299405.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/balajinima/comments/commentRss/299405.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/balajinima/services/trackbacks/299405.html</trackback:ping><description><![CDATA[<!--anchor_link_list_begin--><img alt="" src="//www.ibm.com/i/c.gif" width="1" height="5" /><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N101A0" cmimpressionsent="1">统一建模语言（UML）基础</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N101ED" cmimpressionsent="1">Java 建模：UML 工作簿</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N10222" cmimpressionsent="1">Java 建模：子整体软件开发</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N1023F" cmimpressionsent="1">Java 建模语言（Java Modeling Language，JML）</a></td>
        </tr>
    </tbody>
</table>
<img alt="" src="//www.ibm.com/i/c.gif" width="1" height="5" /><br />
<img alt="" src="//www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" height="1" /><br />
<img alt="" src="//www.ibm.com/i/c.gif" width="443" height="1" /><br />
<!--anchor_link_list_end-->
<p>本专题为 Java 软件工程师们提供了面向 Java 的设计模式和建模方面相关的文章和教程。帮助读者理解、学习作为专业软件工程师必需掌握的设计模式与建模技术。</p>
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N101A0">统一建模语言（UML）基础</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/rational/r-uml/" cmimpressionsent="1">UML基础：统一建模语言简介</a> </strong><br />
回顾 20 世纪晚期 -- 准确地说是 1997 年，OMG 组织（Object Management Group 对象管理组织）发布了统一建模语言（Unified Modeling Language，UML）。UML 的目标之一就是为开发团队提供标准通用的设计语言来开发和构建计算机应用。UML 提出了一套IT专业人员期待多年的统一的标准建模符号。通过使用 UML，这些人员能够阅读和交流系统架构和设计规划--就像建筑工人多年来所使用的建筑设计图一样。</p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/rational/321_uml/" cmimpressionsent="1">统一建模语言(UML) 版本 2.0</a> </strong><br />
所谓的&#8220;模型驱动&#8221;开发（MDD）方式，已经显示出了它们从根本性上提高软件质量和开发生产力方面的潜力。与传统的方法相比，这种方式是基于较高层次上的抽象和更好的自动化利用的。由于建模语言对MDD的成功具有关键性的作用，所以最近完成了对基于工业标准的统一建模语言（UML）的主要修订。随着一些重要的新的建模能力添加到其中――比如更精确地获得软件架构的能力――这次修订的主要特性使得语言定义更加精确，从而达到了更高层次的自动化。这篇文章解释了这一特性是如何实现的，并且描述了 UML 2.0 的其他亮点。</p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/rational/rationaledge/content/feb05/bell/" cmimpressionsent="1">UML 基础：类图</a> </strong><br />
在 UML 2 中，作为新结构图类型的最重要实例，类图可以在整个软件开发生命周期中，被分析师，业务建模人员，开发者和测试者使用的。本文提供了全面的介绍。</p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/rational/rationaledge/content/feb05/bell/3101.html" cmimpressionsent="1">UML 基础：序列图</a> </strong><br />
本文作为 UML 基础的、关于统一建模语言的基础图的一系列文章的一部分，提供对序列图的详细介绍。它也介绍了最近的 UML 2.0 规范的几个新符号元件。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/rational/rationaledge/content/feb05/bell/bell.html" cmimpressionsent="1">UML 基础：组件图</a> </strong><br />
这篇文章介绍组件图，一个在新的统一建模语言 2.0 中规定的结构图。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/rational/rationaledge/content/feb05/bell/bell.html" cmimpressionsent="1">UML 基础：组件图</a> </strong><br />
这篇文章介绍组件图，一个在新的统一建模语言 2.0 中规定的结构图。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N101ED">Java 建模：UML 工作簿</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-jmod/part1/" cmimpressionsent="1">Java 建模：UML 工作簿，第 1 部分：序列图简介 </a></strong><br />
Granville Miller 在其新专栏的第一部分中介绍了&#8220;统一建模语言&#8221;(UML) 的一个构件：序列图。在整个设计过程中都会用到序列图，此图用于演示系统执行时参与者与对象之间的内部交互。让我们跟着 Granville 一起创建其中一个图，我们将使用一个贷款处理应用程序作为示例。</p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-jmod/part2/" cmimpressionsent="1">Java 建模： UML 工作簿：第 2 部分：序列图中的条件逻辑</a> </strong><br />
Granville 继续讨论&#8220;统一建模语言&#8221;和序列图的绘制。他仔细研究了序列图绘制过程中条件逻辑的角色，并讨论了为什么要在图中包含或排除条件和循环。Granville 还描述了序列图的两种形态 -- 常规和实例 -- 并说明了它们在开发周期中各自的应用。</p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-jmod/part3/" cmimpressionsent="1">Java 建模： UML 工作簿，第 3 部分：在用例建模上的用户接口逻辑</a> </strong><br />
在这一部分的 Java 建模中，Granville 引领您进入介于建模和方法之间的区域，同时看一下通过用例建模所收集的需求。他特别着重讨论了用户接口、系统接口和用例描述之间的关系。尽管现在正试图在用例中包括用户接口逻辑，但这通常被认为是不好的形式。接着， Grancille 用序列图和系统接口告诉您具体原因。请点击文章顶部或底部的讨论，参与讨论论坛，与本文作者和其他读者分享您对本文的想法。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-jmod/part6/" cmimpressionsent="1">Java 建模：UML 工作簿，第 4 部分 </a></strong><br />
本文深入讨论用例图的基本组件之一：参与者（actor）。参与者不仅在 UML 建模中不可或缺，而且在创建 Java 应用程序时，它也能起到很重要的作用，甚至可以就 J2EE 应用程序设计中的模式提出建议。对于开发诸如 Web 服务（在其系统设计中，外部交互扮演了很重要的角色）这样的复杂系统，参与者变得尤其重要。Granville 用序列图和类图来阐述参与者在用例图的绘制和 Java 应用程序开发中的角色。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N10222">Java 建模：子整体软件开发</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-jmod/part4/" cmimpressionsent="1">Java 建模：子整体软件开发，第 1 部分：宣言</a> </strong><br />
Granville Miller 暂时放弃需求收集主题，着手讨论另一个引人入胜的主题：子整体软件编程。 让我们找找这个方法如何补充和扩展灵活开发运动原则，以及它在主流开发界中的出现如何可能改变软件开发者的教育和软件开发实践。请在 讨论论坛与作者和其他读者分享您关于本文的想法。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-jmod/part5/" cmimpressionsent="1">Java 建模：子整体软件开发，第 2 部分：需求收集：工作的恰当过程</a> </strong><br />
Granville Miller 继续他关于子整体软件开发的讨论，并在概念上对需求收集作了概括。 让我们看看四个最常见的需求收集过程 ― 功能特性、用户情景、用例和传统的软件需求规范 ― 怎样适应灵活的软件开发过程更广阔的环境。 请在 讨论论坛与作者和其他读者分享您关于本文的想法。 过程太少，非凡的人能做平凡的事； 过程太多，即使是非凡的人也不能做非凡的事。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N1023F">Java 建模语言（Java Modeling Language，JML）</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-jml/" cmimpressionsent="1">JML 入门</a> </strong><br />
Java 建模语言（Java Modeling Language，JML）是一种用来进行详细设计的表示法（notation），它倡导一种思考方法和类的新思路。在这篇入门文章中，Java 编程顾问 Joe Verzulli 介绍了 JML 及其一些最重要的说明构造。 </p>
<img src ="http://www.blogjava.net/balajinima/aggbug/299405.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/balajinima/" target="_blank">李云泽</a> 2009-10-22 17:31 <a href="http://www.blogjava.net/balajinima/articles/299405.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 设计模式与建模专题-设计模式</title><link>http://www.blogjava.net/balajinima/articles/299404.html</link><dc:creator>李云泽</dc:creator><author>李云泽</author><pubDate>Thu, 22 Oct 2009 09:27:00 GMT</pubDate><guid>http://www.blogjava.net/balajinima/articles/299404.html</guid><wfw:comment>http://www.blogjava.net/balajinima/comments/299404.html</wfw:comment><comments>http://www.blogjava.net/balajinima/articles/299404.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/balajinima/comments/commentRss/299404.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/balajinima/services/trackbacks/299404.html</trackback:ping><description><![CDATA[<!--anchor_link_list_begin-->
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-graphic-tab-lblue-table"><img class="display-img" alt="" src="//www.ibm.com/i/c.gif" width="1" height="4" /></td>
        </tr>
        <tr>
            <td class="v14-graphic-tab-dblue-table"><img class="display-img" alt="" src="//www.ibm.com/i/c.gif" width="1" height="1" /></td>
        </tr>
    </tbody>
</table>
<img alt="" src="//www.ibm.com/i/c.gif" width="1" height="5" /><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N10043" cmimpressionsent="1">Factory Method 模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N1006C" cmimpressionsent="1">Singleton 模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N1007D" cmimpressionsent="1">Observer 模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N1008E" cmimpressionsent="1">State 模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N1009F" cmimpressionsent="1">控制反转（IoC）模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N100B0" cmimpressionsent="1">Single Call 模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N100C1" cmimpressionsent="1">其它模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N100EA" cmimpressionsent="1">反模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N100FB" cmimpressionsent="1">从 Java 类库看设计模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N1013C" cmimpressionsent="1">使用设计模式改善程序结构</a></td>
        </tr>
    </tbody>
</table>
<img alt="" src="//www.ibm.com/i/c.gif" width="1" height="5" /><br />
<img alt="" src="//www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" height="1" /><br />
<img alt="" src="//www.ibm.com/i/c.gif" width="443" height="1" /><br />
<!--anchor_link_list_end-->
<p>本专题为 Java 软件工程师们提供了面向 Java 的设计模式和建模方面相关的文章和教程。帮助读者理解、学习作为专业软件工程师必需掌握的设计模式与建模技术。</p>
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N10043">Factory Method 模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-factory/" cmimpressionsent="1">Factory Method 模式在 Javamail 中的应用</a> </strong><br />
设计模式在软件工程中占有重要地位，而 JavaMail 是 Java 平台的一个扩展，为管理电子邮件提供了统一的应用编程接口。本文讨论 Factory Method 设计模式在Javamail 中的应用。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/designpattern/factory/" cmimpressionsent="1">在 Java 中应用设计模式 - Factory Method </a></strong><br />
在设计模式中,Factory Method也是比较简单的一个,但应用非常广泛，EJB,RMI,COM,CORBA,Swing中都可以看到此模式的影子，它是最重要的模式之一。在很多地方我们都会看到xxxFactory这样命名的类,那么,什么是Factory Method,为什么要用这个模式,如何用Java语言来实现该模式,这就是本文想要带给大家的内容。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-factorydp/" cmimpressionsent="1">Factory 模式的优点</a> </strong><br />
最常见的构造一个 Object 的方法是通过构造函数. 例: String strTemp = new String('Hello World'); 其实还有一种一种更灵活的创建Object 的方式---利用Factory 模式. 这是著名的'四人帮'(Gangs Of Four)的经典之作'设计模式'[(Design Pattern) 所记载的23模式之一. 它有着构造函数不可比拟的一些优点. </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N1006C">Singleton 模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/designpattern/singleton/" cmimpressionsent="1">在 Java 中应用设计模式 -- Singleton</a> </strong><br />
本文介绍了设计模式中 Singleton 的基本概念,对其功能和用途进行了简单的分析,列出了通常实现 Singleton 的几种方法,并给出了详细的Java 代码。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N1007D">Observer 模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-observerinj2ee/" cmimpressionsent="1">Observer 模式在 J2EE 中的实现</a> </strong><br />
设计模式是经验的文档化。它是对被用来在特定场景下解决一般设计问题的类和相互通信的对象的描述。更通俗的来说，它是一个问题/解决方案对。一旦我们掌握了设计模式，就等于拥有了一支强有力的专家队伍。它甚至能够使面向对象的新手利用前人的经验找出职责明确的类和对象，从而获得优雅的解决方案。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N1008E">State 模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-state/" cmimpressionsent="1">State 模式在客户端软件中的应用</a> </strong><br />
在对一个 J2EE 项目的重构、增加新功能的过程中，对客户端 GUI 程序，我们使用了 State 模式。结果显示，该模式的使用，不但减少了客户端 GUI 程序的程序规模（LOC），而且，该部分的开发及单元测试时间大大减少，同时，在集成测试中发现的缺陷数量比使用该模式前平均减少了3倍。本文就该项目中使用 State 模式的方式进行介绍。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N1009F">控制反转（IoC）模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-ioc/" cmimpressionsent="1">在方法签名中使用控制反转（IoC）</a> </strong><br />
控制反转（IoC）模式通常用于组件。本文描述了如何对方法签名使用该模式，以减少组件间的耦合并改善性能。IBM Global Business Services 顾问 Andr Fachat 用两个例子展示了这种方法的灵活性。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N100B0">Single Call 模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-single-call/" cmimpressionsent="1">Single Call 模式</a> </strong><br />
在本文中，作者向大家讲述了 Single Call 模式的原理，同时也介绍了 Single Call 模式的实现问题。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N100C1">其它模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/views/java/tutorials.jsp?cv_doc_id=84987" cmimpressionsent="1">Java 设计模式 201：超越四人组</a> </strong><br />
您可以在本教程中发现，到底还有多少设计模式您不知道。首先，我们会探讨一些资源，学习设计模式的新手通常会忽略它们。这些资源为各种计算领域（如商业应用程序、Web 应用程序，甚至 Web 设计）提供了极为有用的模式。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-lo-ui-assembler-pattern/" cmimpressionsent="1">界面组装器模式</a> </strong><br />
本文提出了一种界面设计中的架构模式－界面组装器模式，它致力于分解界面，将界面和组装行为解耦，将界面逻辑处理与领域逻辑处理解耦，这样我们在开发 GUI 胖客户端界面应用时可以从众多的界面控制管理中解脱出来，而专注于我们的后台业务逻辑的开发。通过该模式，我们可以动态地组装我们的界面，我们甚至还可以在我们的界面中轻松地插入 transaction 事务或 session 会话管理。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-lo-archpattern-validator/" cmimpressionsent="1">数据校验器架构模式组</a> </strong><br />
本文阐述软件架构与设计模式，它为架构师和开发人员提供了一组关于数据校验的架构模式（隔离校验器，可组装校验器，动态策略校验器，动态注册校验器等），数据校验是任何类型的开发中都不可或缺的环节，如果没有统一的架构，可能校验代码会遍布整个应用，如何将数据校验与应用逻辑解耦，如何适应各种粒度的数据和各种复杂程度业务规则，正是本文要探讨的。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N100EA">反模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-bitterjava/" cmimpressionsent="1">反模式可以如何提高编程</a> </strong><br />
设计模式对软件开发来说很重要，这一点从它在技术贸易新闻中所占的数量就可见一斑。不过，鉴于其在开发过程中的实用性，设计模式只解决了问题的一半。反模式 ― 描述&#8220;对产生绝对负面结果的问题的一种常用解决方案&#8221; ― 旨在通过向 Java 程序员展示如何避免常见的 Java 陷阱来解决问题的另一半。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N100FB">从 Java 类库看设计模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-jdkdp/part1/" cmimpressionsent="1">从 Java 类库看设计模式，第一部分</a> </strong><br />
在这一部分的内容中，介绍的是一个相对简单但功能强大的模式：Observer 模式。希望通过这部分地叙述，大家看了之后，能够对设计模式有一个比较全面地，感性的认识。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-jdkdp/part2/" cmimpressionsent="1">从 Java 类库看设计模式，第二部分</a> </strong><br />
这部分及以后的内容，将会步入正题，从 Java 类库的分析入手，来阐叙设计模式是如何应用到一个完美的设计中的。实际上，Java 类库非常的庞杂，这儿不可能把所有能够找到的设计模式的例子一一列举，只是找了一些容易发现的例子。实际上也没有必要，因为只要对一个设计模式有足够的理解，对于它的具体应用而言，倒是一件不是很困难的事情。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-jdkdp/part3/" cmimpressionsent="1">从 Java 类库看设计模式，第三部分</a> </strong><br />
主要介绍几个结构型的模式如 Bridge 模式和 Decorator 模式。对于 Bridge 模式可能需要更多的理解，因为它在很大程度上说，例示了设计模式的基本的设计思路和原则。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-jdkdp/part4/" cmimpressionsent="1">从 Java 类库看设计模式，第四部分</a> </strong><br />
在上一部分中，介绍了两个结构型的模式：Bridge和Decorator。这一部分的内容，将会接着上面的讲解，继续我们的设计模式之旅。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-jdkdp/part5/" cmimpressionsent="1">从 Java 类库看设计模式，第五部分</a> </strong><br />
有了前面诸多设计模式的基础，这儿可以提出一个比较特殊的模式 MVC。MVC并不属于 GOF 的 23 个设计模式之列，但是它在 GOF 的书中作为一个重要的例子被提出来，并给予了很高的评价。一般的来讲，我们认为GOF的23个模式是一些中级的模式，在它下面还可以抽象出一些更为一般的低层的模式，在其上也可以通过组合来得到一些高级的模式。MVC就可以看作是一些模式进行组合之后的结果（实际上，MVC的出现要早于设计模式的提出，这而只是对它在设计模式的基础上进行在分析）。如果没有前面的基础，理解MVC或许会有一些困难。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N1013C">使用设计模式改善程序结构</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-dpstruct/part1/" cmimpressionsent="1">使用设计模式改善程序结构（一）</a> </strong><br />
设计模式是对特定问题经过无数次经验总结后提出的能够解决它的优雅的方案。但是，如果想要真正使设计模式发挥最大作用，仅仅知道设计模式是什么，以及它是如何实现的是很不够的，因为那样就不能使你对于设计模式有真正的理解，也就不能够在自己的设计中正确、恰当的使用设计模式。本文试图从另一个角度（设计模式的意图、动机）来看待设计模式，通过这种新的思路，设计模式会变得非常贴近你的设计过程，并且能够指导、简化你的设计，最终将会导出一个优秀的解决方案。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-dpstruct/part2/" cmimpressionsent="1">使用设计模式改善程序结构（二）</a> </strong><br />
在本系列的第一篇文章中，描述了如何通过设计模式来指导我们的程序重构过程，并且着重介绍了设计模式意图、动机的重要性。在本文中我们将继续上篇文章进行讨论，这次主要着重于设计模式的适用性，对于设计模式适用性的掌握有助于从另一个不同的方面来判断一个设计模式是否真正适用于我们的实际问题，从而做出明智的选择。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-dpstruct/part3/" cmimpressionsent="1">使用设计模式改善程序结构（三）</a> </strong><br />
设计模式在某种程度上确实能够改善我们的程序结构，使设计具有更好的弹性。也正是由于这个原因，会导致我们可能过度的使用它。程序结构具有过度的、不必要的灵活性和程序结构没有灵活性一样都是有害的</p>
<table border="0" cellspacing="0" cellpadding="0">
    <tbody>
        <tr>
            <td class="v14-graphic-tab-selected2"><img class="display-img" alt="" src="//www.ibm.com/i/c.gif" width="7" height="19" /></td>
            <td class="v14-graphic-tab-selected"><a class="v14-tab-link-selected" onmouseover="linkQueryAppend(this)" href="index.html" cmimpressionsent="1">设计模式</a></td>
            <td class="v14-tab-hlrt2"><img alt="" src="//www.ibm.com/i/c.gif" width="24" height="1" /></td>
            <td class="v14-graphic-tab-unselected"><a class="v14-tab-link-unselected" onmouseover="linkQueryAppend(this)" href="http://www.ibm.com/developerworks/cn/java/design/model.html?S_TACT=105AGX52&amp;S_CMP=tec-csdn" cmimpressionsent="1" doneonce="true">Java 建模</a></td>
            <td class="v14-tab-dmrt-end2"><img alt="" src="//www.ibm.com/i/c.gif" width="24" height="1" /></td>
        </tr>
    </tbody>
</table>
<!--anchor_link_list_begin-->
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-graphic-tab-lblue-table"><img class="display-img" alt="" src="//www.ibm.com/i/c.gif" width="1" height="4" /></td>
        </tr>
        <tr>
            <td class="v14-graphic-tab-dblue-table"><img class="display-img" alt="" src="//www.ibm.com/i/c.gif" width="1" height="1" /></td>
        </tr>
    </tbody>
</table>
<img alt="" src="//www.ibm.com/i/c.gif" width="1" height="5" /><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N10043" cmimpressionsent="1">Factory Method 模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N1006C" cmimpressionsent="1">Singleton 模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N1007D" cmimpressionsent="1">Observer 模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N1008E" cmimpressionsent="1">State 模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N1009F" cmimpressionsent="1">控制反转（IoC）模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N100B0" cmimpressionsent="1">Single Call 模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N100C1" cmimpressionsent="1">其它模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N100EA" cmimpressionsent="1">反模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N100FB" cmimpressionsent="1">从 Java 类库看设计模式</a></td>
        </tr>
        <tr valign="top">
            <td width="16"><img alt="" src="//www.ibm.com/i/v14/icons/d_bold.gif" width="16" height="16" /></td>
            <td width="100%"><a class="fbox" href="#N1013C" cmimpressionsent="1">使用设计模式改善程序结构</a></td>
        </tr>
    </tbody>
</table>
<img alt="" src="//www.ibm.com/i/c.gif" width="1" height="5" /><br />
<img alt="" src="//www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" height="1" /><br />
<img alt="" src="//www.ibm.com/i/c.gif" width="443" height="1" /><br />
<!--anchor_link_list_end-->
<p>本专题为 Java 软件工程师们提供了面向 Java 的设计模式和建模方面相关的文章和教程。帮助读者理解、学习作为专业软件工程师必需掌握的设计模式与建模技术。</p>
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N10043">Factory Method 模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-factory/" cmimpressionsent="1">Factory Method 模式在 Javamail 中的应用</a> </strong><br />
设计模式在软件工程中占有重要地位，而 JavaMail 是 Java 平台的一个扩展，为管理电子邮件提供了统一的应用编程接口。本文讨论 Factory Method 设计模式在Javamail 中的应用。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/designpattern/factory/" cmimpressionsent="1">在 Java 中应用设计模式 - Factory Method </a></strong><br />
在设计模式中,Factory Method也是比较简单的一个,但应用非常广泛，EJB,RMI,COM,CORBA,Swing中都可以看到此模式的影子，它是最重要的模式之一。在很多地方我们都会看到xxxFactory这样命名的类,那么,什么是Factory Method,为什么要用这个模式,如何用Java语言来实现该模式,这就是本文想要带给大家的内容。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-factorydp/" cmimpressionsent="1">Factory 模式的优点</a> </strong><br />
最常见的构造一个 Object 的方法是通过构造函数. 例: String strTemp = new String('Hello World'); 其实还有一种一种更灵活的创建Object 的方式---利用Factory 模式. 这是著名的'四人帮'(Gangs Of Four)的经典之作'设计模式'[(Design Pattern) 所记载的23模式之一. 它有着构造函数不可比拟的一些优点. </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N1006C">Singleton 模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/designpattern/singleton/" cmimpressionsent="1">在 Java 中应用设计模式 -- Singleton</a> </strong><br />
本文介绍了设计模式中 Singleton 的基本概念,对其功能和用途进行了简单的分析,列出了通常实现 Singleton 的几种方法,并给出了详细的Java 代码。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N1007D">Observer 模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-observerinj2ee/" cmimpressionsent="1">Observer 模式在 J2EE 中的实现</a> </strong><br />
设计模式是经验的文档化。它是对被用来在特定场景下解决一般设计问题的类和相互通信的对象的描述。更通俗的来说，它是一个问题/解决方案对。一旦我们掌握了设计模式，就等于拥有了一支强有力的专家队伍。它甚至能够使面向对象的新手利用前人的经验找出职责明确的类和对象，从而获得优雅的解决方案。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N1008E">State 模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-state/" cmimpressionsent="1">State 模式在客户端软件中的应用</a> </strong><br />
在对一个 J2EE 项目的重构、增加新功能的过程中，对客户端 GUI 程序，我们使用了 State 模式。结果显示，该模式的使用，不但减少了客户端 GUI 程序的程序规模（LOC），而且，该部分的开发及单元测试时间大大减少，同时，在集成测试中发现的缺陷数量比使用该模式前平均减少了3倍。本文就该项目中使用 State 模式的方式进行介绍。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N1009F">控制反转（IoC）模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-ioc/" cmimpressionsent="1">在方法签名中使用控制反转（IoC）</a> </strong><br />
控制反转（IoC）模式通常用于组件。本文描述了如何对方法签名使用该模式，以减少组件间的耦合并改善性能。IBM Global Business Services 顾问 Andr Fachat 用两个例子展示了这种方法的灵活性。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N100B0">Single Call 模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-single-call/" cmimpressionsent="1">Single Call 模式</a> </strong><br />
在本文中，作者向大家讲述了 Single Call 模式的原理，同时也介绍了 Single Call 模式的实现问题。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N100C1">其它模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/views/java/tutorials.jsp?cv_doc_id=84987" cmimpressionsent="1">Java 设计模式 201：超越四人组</a> </strong><br />
您可以在本教程中发现，到底还有多少设计模式您不知道。首先，我们会探讨一些资源，学习设计模式的新手通常会忽略它们。这些资源为各种计算领域（如商业应用程序、Web 应用程序，甚至 Web 设计）提供了极为有用的模式。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-lo-ui-assembler-pattern/" cmimpressionsent="1">界面组装器模式</a> </strong><br />
本文提出了一种界面设计中的架构模式－界面组装器模式，它致力于分解界面，将界面和组装行为解耦，将界面逻辑处理与领域逻辑处理解耦，这样我们在开发 GUI 胖客户端界面应用时可以从众多的界面控制管理中解脱出来，而专注于我们的后台业务逻辑的开发。通过该模式，我们可以动态地组装我们的界面，我们甚至还可以在我们的界面中轻松地插入 transaction 事务或 session 会话管理。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-lo-archpattern-validator/" cmimpressionsent="1">数据校验器架构模式组</a> </strong><br />
本文阐述软件架构与设计模式，它为架构师和开发人员提供了一组关于数据校验的架构模式（隔离校验器，可组装校验器，动态策略校验器，动态注册校验器等），数据校验是任何类型的开发中都不可或缺的环节，如果没有统一的架构，可能校验代码会遍布整个应用，如何将数据校验与应用逻辑解耦，如何适应各种粒度的数据和各种复杂程度业务规则，正是本文要探讨的。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N100EA">反模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/j-bitterjava/" cmimpressionsent="1">反模式可以如何提高编程</a> </strong><br />
设计模式对软件开发来说很重要，这一点从它在技术贸易新闻中所占的数量就可见一斑。不过，鉴于其在开发过程中的实用性，设计模式只解决了问题的一半。反模式 ― 描述&#8220;对产生绝对负面结果的问题的一种常用解决方案&#8221; ― 旨在通过向 Java 程序员展示如何避免常见的 Java 陷阱来解决问题的另一半。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N100FB">从 Java 类库看设计模式</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-jdkdp/part1/" cmimpressionsent="1">从 Java 类库看设计模式，第一部分</a> </strong><br />
在这一部分的内容中，介绍的是一个相对简单但功能强大的模式：Observer 模式。希望通过这部分地叙述，大家看了之后，能够对设计模式有一个比较全面地，感性的认识。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-jdkdp/part2/" cmimpressionsent="1">从 Java 类库看设计模式，第二部分</a> </strong><br />
这部分及以后的内容，将会步入正题，从 Java 类库的分析入手，来阐叙设计模式是如何应用到一个完美的设计中的。实际上，Java 类库非常的庞杂，这儿不可能把所有能够找到的设计模式的例子一一列举，只是找了一些容易发现的例子。实际上也没有必要，因为只要对一个设计模式有足够的理解，对于它的具体应用而言，倒是一件不是很困难的事情。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-jdkdp/part3/" cmimpressionsent="1">从 Java 类库看设计模式，第三部分</a> </strong><br />
主要介绍几个结构型的模式如 Bridge 模式和 Decorator 模式。对于 Bridge 模式可能需要更多的理解，因为它在很大程度上说，例示了设计模式的基本的设计思路和原则。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-jdkdp/part4/" cmimpressionsent="1">从 Java 类库看设计模式，第四部分</a> </strong><br />
在上一部分中，介绍了两个结构型的模式：Bridge和Decorator。这一部分的内容，将会接着上面的讲解，继续我们的设计模式之旅。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-jdkdp/part5/" cmimpressionsent="1">从 Java 类库看设计模式，第五部分</a> </strong><br />
有了前面诸多设计模式的基础，这儿可以提出一个比较特殊的模式 MVC。MVC并不属于 GOF 的 23 个设计模式之列，但是它在 GOF 的书中作为一个重要的例子被提出来，并给予了很高的评价。一般的来讲，我们认为GOF的23个模式是一些中级的模式，在它下面还可以抽象出一些更为一般的低层的模式，在其上也可以通过组合来得到一些高级的模式。MVC就可以看作是一些模式进行组合之后的结果（实际上，MVC的出现要早于设计模式的提出，这而只是对它在设计模式的基础上进行在分析）。如果没有前面的基础，理解MVC或许会有一些困难。 </p>
<br />
<br />
<!--spacer--><br />
<table border="0" cellspacing="0" cellpadding="0" width="100%">
    <tbody>
        <tr>
            <td class="v14-header-3"><a name="N1013C">使用设计模式改善程序结构</a></td>
        </tr>
    </tbody>
</table>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-dpstruct/part1/" cmimpressionsent="1">使用设计模式改善程序结构（一）</a> </strong><br />
设计模式是对特定问题经过无数次经验总结后提出的能够解决它的优雅的方案。但是，如果想要真正使设计模式发挥最大作用，仅仅知道设计模式是什么，以及它是如何实现的是很不够的，因为那样就不能使你对于设计模式有真正的理解，也就不能够在自己的设计中正确、恰当的使用设计模式。本文试图从另一个角度（设计模式的意图、动机）来看待设计模式，通过这种新的思路，设计模式会变得非常贴近你的设计过程，并且能够指导、简化你的设计，最终将会导出一个优秀的解决方案。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-dpstruct/part2/" cmimpressionsent="1">使用设计模式改善程序结构（二）</a> </strong><br />
在本系列的第一篇文章中，描述了如何通过设计模式来指导我们的程序重构过程，并且着重介绍了设计模式意图、动机的重要性。在本文中我们将继续上篇文章进行讨论，这次主要着重于设计模式的适用性，对于设计模式适用性的掌握有助于从另一个不同的方面来判断一个设计模式是否真正适用于我们的实际问题，从而做出明智的选择。 </p>
<p><strong><a href="http://www.ibm.com/developerworks/cn/java/l-dpstruct/part3/" cmimpressionsent="1">使用设计模式改善程序结构（三）</a> </strong><br />
设计模式在某种程度上确实能够改善我们的程序结构，使设计具有更好的弹性。也正是由于这个原因，会导致我们可能过度的使用它。程序结构具有过度的、不必要的灵活性和程序结构没有灵活性一样都是有害的</p>
<img src ="http://www.blogjava.net/balajinima/aggbug/299404.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/balajinima/" target="_blank">李云泽</a> 2009-10-22 17:27 <a href="http://www.blogjava.net/balajinima/articles/299404.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java认证之精屁总结</title><link>http://www.blogjava.net/balajinima/articles/298543.html</link><dc:creator>李云泽</dc:creator><author>李云泽</author><pubDate>Fri, 16 Oct 2009 03:50:00 GMT</pubDate><guid>http://www.blogjava.net/balajinima/articles/298543.html</guid><wfw:comment>http://www.blogjava.net/balajinima/comments/298543.html</wfw:comment><comments>http://www.blogjava.net/balajinima/articles/298543.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/balajinima/comments/commentRss/298543.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/balajinima/services/trackbacks/298543.html</trackback:ping><description><![CDATA[<p>3.switch里面只能是short,int,char,byte的.<br />
4.if (a="a") 编译错, if(a=false)编译ok,原因是a=false的a代表了个boolean值<br />
6.这种写法Outer.Inner i = new Outer().new Inner(); OK!<br />
7.文件里, 8 默认是int, 8.0默认是double<br />
8.八进制是 0开头,不是O(英文o)<br />
9.byte -128~127 ,-128是二进制的多少<br />
11. -1&gt;&gt;32还是-1, -1&gt;&gt;&gt;32为什么还是-1<br />
12. char c='c'; String s ="s"; s+=c;结果是 sc!!!<br />
13. boolean b1=true; boolean b2=true; System.out.println(b1|b2); 结果是true.编译没错!<br />
java的默认import包有哪些<br />
AWT&nbsp;<wbr><br />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
1. 所有组件flowLayout会被压缩为它们的最小尺寸<br />
2. BorderLayout的North,South,West,East,Center就是这个样子,四个单词大小写区分,必须这么写,否则错<br />
2.1如果只是add,而不写东南西北中,默认是中<br />
2.2如果不加component到中,那中就空着<br />
2.3如果某个方位有个component,如果你还往上面加component,后来的会覆盖原来的<br />
3. applet,panel默认布局是flowlayout<br />
4. frame,dialog默认布局是borderlayout<br />
5. 各种awe类的继承关系,frame,window,component,...<br />
6. window,frame,dialog不能被嵌入到容器里.注意:window!<br />
7. action event作用于button和textfeild的回车时刻<br />
8. item event作用于list,choice,checkbox的选择改变时刻<br />
9. 如果容器不可见,新layout管理器后前的component将跟随这个新的layout变化,如果容器可见,这些component将不受后来的layout影响<br />
10.gridLayout里的component尺寸一样<br />
11.gridBagLayout里,component可以占用多个grid<br />
12.System.exit();在Applet里面不允许调用.<br />
AWT事件<br />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
1.事件类有<br />
(symantic)语义事件:ActionEvent,AdjustEvent,ItemEvent,TextEvent<br />
低级事件:ComponentEvent,ContainerEvent,FocusEvent,InputEvent,KeyEvent,MouseEvent,PaintEvent,WindowEvent<br />
2.监听器:<br />
ActionListener,AdjustListener,CompentListener,ContainerListener,FocusListener,ItemListener,<br />
KeyListener,MouseListener,MouseMotionListener,TextListener,WindwosListener, 共11个Listener,<br />
七个adpter,少的4个是ActionLisenter,AdjustListener,ItemListener,TextListener,它们只有一个方法.<br />
3,鼠标MouseListener有5个方法:clicked,pressed,released,entered,exited<br />
4.鼠标MouseMotionListener有2个方法:mouseDragged,mouseMoved<br />
类和对象(Class and Object)<br />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
0.最外层的类可以声明成final: "$file a":&lt; final class a{}&gt; ok!,但是不能是private和static的.<br />
1.overload是同类里同样的方法名,override是父子的继承<br />
2.override的返回结果必须一样,否则编译错哦<br />
The return type of an overriding method is identical to the return type of the method it overrides.<br />
2.1 override的modifier可以扩大,但是不能缩小.比如父类private void test(){} 子类:public void test(){} ,没问题;如果反了,就死翘翘了!<br />
3.super.super(),靠,错的,没这么写的<br />
4.static和非static之间永远无法override!<br />
5. 看程序<br />
public class A{<br />
void test1() throws BaseEx{hi();}<br />
void hi(){System.out.println("say hi,a");}<br />
}<br />
class AA extends A{<br />
void hi(){System.out.println("say hi,aa");}<br />
}<br />
class test{<br />
static void main(String b[]) throws Exception{<br />
A a = new AA();<br />
a.test1();<br />
}<br />
}<br />
结果是,"say hi,aa",这说明什么说明,方法永远跟着类的原来面目走;而,变量恰恰相反!<br />
6.一个非抽象方法死活也别想override成一个抽象方法<br />
7.override的子类的方法抛出的的异常只能是父类方法抛出异常的子异常类,或者无!<br />
8.构造器不能是native,final,static,synchronized的,可以是public,private,什么都没有的,呵呵<br />
9.构造器函数里还可以写return呢,但后面什么都不许有,甚至null(这不是废话吗,哈哈)<br />
10.构造器不能返回值.这大家都知道,但如果有个"构造器"反值了,别紧张,它就不是构造器喽,只是个普通函数<br />
11.super();this();这两个函数只能在构造函数里调用.<br />
12,成员变量声明时候赋值,比构造函数还早.int i=1; ealier than Test(){}<br />
13.方法的参数变量可以是final.<br />
14. hashCode返回一个int<br />
15. void wait() throws InterruptException wait扔InterruptException异常<br />
16. java.lang.Void 是void的包装类<br />
17. Byte,Interger,Double...所有的跟数有关的包装类都是继承于Number</p>
<p>接口Interface)<br />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
1.接口的所有方法默认都是public,abstract和non-static的<br />
2.接口的所有变量默认都是public,static,final的.所以,接口的变量不能改值,在它的实现类里.<br />
3.接口的实现类实现的方法必须和接口的方法抛出同样的异常,不许是子类,这和override不一样!同样,如果接口方法没有抛,实现方法也不能抛.<br />
4.实现类实现的方法必须显式的声明成public,什么都不写都不行,啊!!!<br />
5.接口不能声明成final,要不它怎么被实现呢(这好像又是废话啊<br />
6.一个类实现两个接口,如果两个接口有相同的方法,实现类就实现这个方法,没问题的.</p>
<p>内嵌类Inner Class)<br />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
1.内嵌类可以访问outer类的任何变量,包括私有的.<br />
2.静态inner类,只能访问outer类的任何static变量<br />
2.1内嵌类可以是final,abstract的<br />
3.我靠,方法内的内嵌类不能为static: void test(){ static class A{}} XXXXX!!!!<br />
4.我靠,方法内的内嵌类也不能带任何modifier,void test(){ public class A{}} XXXXX!!!!<br />
5.我靠,方法内的内嵌类只能访问方法内的final变量,但是,可以访问outer类的任何变量.<br />
6.匿名类不能有构造器,但声明时候带参数,相当于构造器的参数传递.<br />
class ABC{}<br />
class ABCD{private ABCD(int i){}}<br />
ABC test3(){return new ABC(){};}<br />
ABCD test4(){return new ABCD(3){};}<br />
interface iii{}<br />
iii test5(){return new iii(){};}<br />
//class BCD extends ABCD{} compile error,因为,<br />
看上面就知道,new iii(){};实际上匿名类实现了iii接口;new ABC(){};实际上是匿名类继承了ABC.<br />
8.<br />
class A {private A(){System.out.println("a!");}}<br />
class B extends A{}<br />
我靠,没错!B实例的时候会主动调用父类A的构造,即使是private的,看来也没问题!!!<br />
9.内部类可以有synchronized方法,那么锁是这个内部类,跟外部类没一点关系,内外分别的,在锁的问题上.<br />
10.外部类不能通过this被访问,this这时候应该指的是内部类,享用外部类的成员就直接用,不用加任何限定词<br />
11.如何用this呢请看:<br />
class Outer{ int i;<br />
class Inner{<br />
class InnerInner{<br />
void Test(){<br />
Outer.this.i=1;<br />
}<br />
}<br />
}<br />
}<br />
看见了吧,类名.this.变量名,可以引用到i,第一次看到吧,嘿嘿,孤陋寡闻.<br />
12.注意这两种写法都可以<br />
Class Outer.Inner i = new Outer().new Inner();<br />
或者, Class o= new Outer(); Class Outer.Inner i=o.new Inner();</p>
<p>线程Thread)<br />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
去看Thread的API!!!!<br />
1.线程启动必须通过start函数.<br />
2.run函数不许也只能是public的.<br />
3.线程有优先级从1到10,通过Thread.setPriority(int);来改变,不能超过10,否则会出现运行异常<br />
4.线程优先级默认是5,即NORM_PRIORITY.NORM_PRIORITY是Thread的静态变量吗<br />
5.Thread.yeild();是静态方法,所以,使用格式是Thread.yield();她强迫当前的进程放弃CUP.<br />
6.sleep(1000),是说线程睡觉1秒,然后,进入Ready状态,注意,不是运行状态,它还要等OS来调度来获得CUP.</p>
<p>java.lang.*;<br />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
1.数组的科隆: int ia[][]={{1,2},null}; int ib[][]=(int[][])ia.clone();<br />
2.什么是NaN然后看ceil(NaN),floor(NaN),...<br />
3.Math.floor(-1.1f);//-2.0<br />
Math.ceil(-1.1f);//-1.0<br />
Math.round(-1.6d)//-2<br />
4.0=&lt;1<br />
5.Math,Interger,Boolean...等类型包装类都是final的,不可继承<br />
6.int round(float); long round(double);唉,round永远返回不了小数点<br />
7.static double ceil(double)<br />
8.static double floor(double)注意，ceil,floor的只有这个double版本,什么都转成double!<br />
9.static double sin(double 弧度); 还有cos,tan<br />
10. new String; 可以是byte[];char[];String;StringBuffer<br />
11. String的一些函数: int length(); char charAt(int); String toUpperCase(); String toLowerCase();<br />
12. String("Abc").equals(String("abc"))不相等的,不然就不会有boolean equalsIgnoreCase(String)函数<br />
13."012345678"是一个串的顺序号码,indexOf('1'),indexOf("1")都返回1,subString(1,5)是2345,嘿嘿:是"[)"的感觉<br />
14, trim()连tab都退毛,"\t\n java ",trim()一下就只剩下"java"了<br />
15. 关于对象的科隆,去喳喳API<br />
16. "abcd".trim(),"abcd" + new String("ef")都是合理的写法<br />
17. StringBuffer的3个构造器: ()初始化容量为16,(int 初始化容量),(String),初始化容量为串长加上16<br />
18. StringBuffer的一些函数: String toString(); append();reverse();insert();delete(int start,int end);deleteCharAt(int);setLength(int newLength);<br />
19. String s=""; StringBuffer sb=new StringBuffer(); if (s==sb){}编译错!因为,s,sb类型不一样,不能比较<br />
集合:<br />
1.各接口和类的关系,只有最后一个是类<br />
Collection:List:vector,ArrayList,LinkedList<br />
Map:SortedMap:TreeMap<br />
Collection:Set:SortedSet:TreeSet<br />
Map:HashTable<br />
Collection:Set:HashSet</p>
<p>基础Base)<br />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
1.java application的main可以不是public的.但必须是static的<br />
2.一个文件只能有一个public类,而且还得跟文件名一样,包括大小写<br />
3.变量只能是字母,$,_开头,接下来的第二个可以是,数字<br />
4.ch\u0061r='a'; char \u0063='b'; char c='\u0063';都是合法的<br />
5.1e-5d,合法.e-5d不合法,必须有前面的系数<br />
6.int[] i[]={null{1,2}}正确! int i[]={1,2,3,} 正确!","和没有的效果一样<br />
7.局部array,跟变量一样,使用前要初始化<br />
8.main方法可以为final</p>
<p>操作符和分配符(Operator and Assignment)<br />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
1.System.out.printl(1+2+"3");//33 System.out.printl("1"+2+3);//123<br />
2.int i=0; i=i++;i=i++;i=i++; 结果,i=0!<br />
3.int i[]; index=0; i[index]=index=5; 结果是,i[0]=5;!!!<br />
4.byte b=10;可以,因为,10可以被自动从int转成byte<br />
5.接下来,byte b=b+10;不可以!!因为,10+b后的int无法被自动从int转成byte,问我,我也不知道为什么!靠!<br />
6.byte b1 = 4; byte b2 = 6; b1 = b1 + b2;错!编译错!b1 + b2后,必须强制转成byte,b1x1+b2);<br />
7.XOR 一样的为0，不一样为1 1,1=0;0,0=0;1,0/0,1=1<br />
8. x == Float.NaN编译错，应该是Float.IsNaN<br />
9. x == Double.POSITIVE_INFINITY编译可以<br />
10.-1是1111.... 1111,&lt;&lt;永远右补零，&gt;&gt;正补零，负补一，&gt;&gt;&gt;恒补零<br />
10.1 -1&gt;&gt;多少位都是-1 ; 1&lt;&lt;31变成了最小负数,1000....0000<br />
11.最大正数是01111....1111<br />
12.最小负数是1000....0000(-2147483648)<br />
13. a instanceof b,b必须是类/接口，不能是实例<br />
--------补充------------------------------<br />
1. byte,short,char 都存在 var = -var;编译错误,因为,这时候的-var已经自动转成个int类型了<br />
2. int/0会扔出ArithmeticException<br />
double,float/0得INF或者-INF<br />
0/0得NaN<br />
3. int a-b-c;是不符合命名规则的变量名编译会出错.<br />
4. char a='\u0001';对! char b=\u0001;编译错!<br />
5. boolean b1,b2,b3,b4,b5;<br />
b1 = b2==b3;<br />
b1 = b2&lt;=b3 &amp;&amp; b4==b5;<br />
b1 = b2==b3==true<br />
都是对的!靠!变态!<br />
b1 = b2==b3==b4 XXXXXXX编译错!<br />
6. 1&gt;&gt;1 是0<br />
7. %= &lt;&lt;= =&gt;&gt; =&gt;&gt;&gt;都是合法符号<br />
8. --1-10*4 这种写法没错,就是 (--1)-10*4<br />
9. k=1;++k + k++ + +k ;结果是7,相当于 (++2)+(2++)+(+3)<br />
10.标号不能标示声明.<br />
hi:<br />
if {<br />
break hi;<br />
//break hi1;不行,不能向后调转<br />
}<br />
//hi1:不行,不能放在声明前<br />
int i;<br />
hi1:<br />
i=1;<br />
11.public static void main(String s[]) throws Exception{}可以噢,main可以扔出异常<br />
12. hi:<br />
if(b==true){break hi;}<br />
break 标号，可以用在if里面.别的任何都不行,包括break,continue 标号.<br />
13.int x = i*-j; 我靠,没问题的!!!编译没错! int x = i*j++ + +i++; 这个也没问题,</p>
<p>变量修饰符(Modifier)<br />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
1.最外面一层的类不能声明成protect和pravite的<br />
2.同一个类的两个实例之间可以访问彼此的私有方法和私有变量,酷<br />
3.protect和无修饰符的具体区别关于外包可以访问被子类访问的是哪个<br />
4.成员变量被修饰成final后,必须声明时候就赋初值或者在构造器里面赋初值,别指望她可以得到default值.<br />
5.抽象方法不能是static的!!!<br />
6.静态方法将随着类的变化而变化,看例子:<br />
class Parent{<br />
static void test(){System.out.println("hi,parent")};<br />
}<br />
class Child extends Parent{<br />
static void test(){System.out.println("hi,child")};<br />
}<br />
Parent p = new Child();<br />
p.test(); //打出来的是hi,parent!<br />
7.静态方法可以通过类的实例调用.<br />
new Child().test(); 和 Child.test(); 都OK!<br />
8.transient只能用在类的成员变量上,不能用在方法里.<br />
9.transient变量不能是final和static的<br />
10.native方法可以是private,abstractd的</p>
<p>流程控制<br />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
1。不可到达的语句声明为错：while(false){} ;for(;false{};if(false){}都无法编译<br />
2。for(第一部分;的第一部分可以用来声明或者赋值，但不能两者都<br />
3。byte b; switch&nbsp;<wbr> { case 200: // 200 not in range of byte，因为200超过b的范围，将编译错误<br />
4。带标签的continue回达到标签的位置，从新进入紧接在标签后面的循环<br />
5。带标签的break会中断当前循环，并转移到标签标示的的循环的末尾</p>
<p>转型和上溯(Converting and Casting)<br />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
Binary operators convert the smaller(less precise) operand to the type of the larger(more precise) operand.<br />
All operators will convert things smaller than ints to ints or larger. This includes char 's!<br />
1.byte,char,short默认转成int<br />
2.byte-&gt;short-&gt;int-&gt;long-&gt;float-&gt;double<br />
char^<br />
这是默认可以转型的方向,反了必须要显式cast! 特别注意:long-&gt;float是默认的,别看long64,float32,嘿嘿<br />
还有就是看得出来,char和 byte,short之间无法互相默认转换<br />
3.float f=1/3; OK!float f=1.0/3.0;编译出错,因为1.0/3.0结果是double的,噢噢~,错喽!!<br />
4.int i=1; byte b=i;错!需要显式cast.<br />
final i=1; byte b=i;就ok! 我也不知道为什么,final就可以.而且,据我实验只有int和byte的关系这样,其他不行.<br />
5.int i[]; Object[] obj=i;错! Object obj=i;对! 数组只能转成Object,而不能是Object[]<br />
6.int i[]; Object[] obj;i=(int[])obj; 对! 对象可以通过显式来转成一个数组.</p>
<p>I/O<br />
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
1.File类的一些重要方法:isFile();isDirectory();String[] list();exists();getAbsolutePath();getParent();<br />
2.通过delete();mkdir();rename(File newname);可以操纵文件,但是却改变不了文件的内容<br />
2.1 File类无法改变当前目录,除非重新创建一个File对象.<br />
3.InputStreamReader(InputStream in,String encodingName);<br />
OutputStreamReader(OutputStream in,String encodingName);<br />
Encoding: 8859_1是Latin-1,包含ASCII<br />
4.关闭close一个流,就自动调用了flush.<br />
5.System.in,System.out,System.err,由JVM自动创建<br />
6.RandomAccessFile(File file,String mode);mode有,r,rw</p>
<img src ="http://www.blogjava.net/balajinima/aggbug/298543.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/balajinima/" target="_blank">李云泽</a> 2009-10-16 11:50 <a href="http://www.blogjava.net/balajinima/articles/298543.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA概念总结</title><link>http://www.blogjava.net/balajinima/articles/298542.html</link><dc:creator>李云泽</dc:creator><author>李云泽</author><pubDate>Fri, 16 Oct 2009 03:49:00 GMT</pubDate><guid>http://www.blogjava.net/balajinima/articles/298542.html</guid><wfw:comment>http://www.blogjava.net/balajinima/comments/298542.html</wfw:comment><comments>http://www.blogjava.net/balajinima/articles/298542.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/balajinima/comments/commentRss/298542.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/balajinima/services/trackbacks/298542.html</trackback:ping><description><![CDATA[<p>◆<strong>传值与传引</strong></p>
<p>严格来说，Java中所有方法参数都是传值。因为即使是传递的参数是对象的引数时，引数本身也是传值的。所有基本类型都是传值的。</p>
<p><strong>传值：</strong>被传入的参数被视为内部的局域变量，其变化不影响外部变量的原始值。</p>
<p><strong>传引</strong><strong>：</strong>对于引数本身来讲也是传值的，但是在方法内部若对引数所指向的对象属性有改变，则会直接实时地影响所指向的对象属性。</p>
<p>理解传引这一概念的最佳方式就是画出指向图。eg. A&#224;(Object)O 对于A本身而言它是传值的，也就是说当A作为参数传递的时候，假若在方法内部把其它的引数赋给了A，但是当方法返回时，A仍旧是指向原来的对象，而不会改变。其次，对于传引来说，假若在方法内部对A所指向的对象属性有改变，那么对象属性的改变会是直接实时的。</p>
<p>再次强调，Java中所有的参数传递都是传值的。</p>
<p>传值这种题型的考试很多，基本类型传值问题考的较多的是对某一变量，故意用某一方法试图改变它，然后方法返回时再打印它。按传值的说法，实际上该变量并没有改变。</p>
<p>◆<strong>构造函数</strong></p>
<p>a．构造器没有任何返回类型，哪怕是void也不行。<strong>假如指定了返回值，那么</strong><strong>Java</strong><strong>会视为一个普通的方法。</strong></p>
<p>b．如果没有显示地调用父类的构造器，Java总是自动地调用父类的默认构造器。（也就是第一行会默认为super( )）</p>
<p>c．只要类中显式地定义一个或多个构造器，那么Java不会再为你定义一个默认的构造器</p>
<p>d．构造函数可以被重载，并且在其体内可以用this()和super()来调用其它的构造器。但是this()和super()只能放在构造函数体的第一行进行调用。</p>
<p>e．构造器的修饰符只可以是接入控制符public、private、protected、(default)。其它修饰符一律不可。</p>
<p>f．构造方法不可被继承。</p>
<p>◆<strong>重载与覆盖</strong></p>
<p>&nbsp;<wbr> 重载的英文为Overload，而覆盖的英文为Override。重载是出现在同一类中多个同名函数，而覆盖是出现在类继承体系中同名函数。（注意：覆盖有时被称为重写）</p>
<p>&nbsp;<wbr> <strong>重载</strong>是依据同名方法<strong>参数的个数</strong>、<strong>参数的类型</strong>和<strong>参数的顺序</strong>来确定的。方法的修饰符、返回值、抛出的异常均不能作为区分重载方法的依据。（继承体系中也有重载现象）</p>
<p><strong>&nbsp;<wbr></strong> <strong>覆盖</strong>是在继承体系中子类覆盖超类中定义的方法。子类中覆盖方法的<strong><u>返回类型</u></strong>和<strong><u>参数类型</u></strong>必须精确匹配。<strong>接入控制符</strong>只能更加公有化；<strong>抛出的异常</strong>是超类抛出的子集或不抛。</p>
<p><strong>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></strong> <strong>（static</strong>方法不能覆盖，<strong>private</strong>方法也不能覆盖。Java视它们为被隐藏<strong>）</strong></p>
<p><strong>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></strong> &#183; 参数类型一致，返回类型不同，编译错误，提示&#8220;试图用不兼容的返回类型覆盖&#8221;。</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &#183; 只要参数类型不一致，返回类型同与不同，编译都能通过，此不为覆盖而是重载。</p>
<p>◆<strong>多态</strong></p>
<p>&nbsp;<wbr> 多态是出现于类的继承层次中，通过<strong>向上转型</strong>和<strong>方法重写</strong>的机制来实现的。</p>
<p>&nbsp;<wbr> 面向对象程序设计的目标是：<strong>希望所撰写的程序代码都只对基类进行操作</strong>。这么一来，当加入新的继承类时，大部分程序代码都不会受影响而改写（也即是说代码具有扩充性）。所以当调用新加入的继承类时，都会首先向上转型为基类。这就是多态的向上转型。</p>
<p>&nbsp;<wbr> 当你希望通过调用基类的方法而能让继承类产生正确的行为时，这显然需要在继承类进行重写该方法。而究竟是该调用哪个继承类，这是由Java的动态绑定决定的。</p>
<p>&nbsp;<wbr> 多态最重要的一点在于<strong><em>run-time binding</em></strong>。多态是面向对象程序设计的目标。</p>
<p>&nbsp;<wbr> 关于多态中覆盖注意如下：</p>
<p><strong>属性</strong>既可以继承，也是可以&#8220;覆盖&#8221;的。但是对属性而言没有动态绑定这一特性，所以覆盖的属性被认为是子类的特别属性。从某种意义上来讲，属性决定了类（性质）。另一方面，申明的类型就决定了对象的属性。这是因为，任何对象或变量等号右面是用来赋值给符合等号左面所申明类型的，所以左面的类型是先决条件，赋值必须要符合申明类型。对于向上转型而言，因为等号右面的对象is a申明类型，所以是成立的。一定要记住，<strong>属性永远都是跟着申明类型走</strong>。但是，对<strong>方法</strong>而言是在运行时动态绑定的，它取决于对象自身的实际类型（实际上对方法而言，也是先检查向上转型后的基类该方法，若无该方法的定义，则编译错，然后再动态绑定到继承类的覆盖方法）。</p>
<p>另外，<strong>static</strong>方法不能覆盖，<strong>private</strong>方法也不能覆盖。</p>
<p>还需特别注意，方法覆盖时，若覆盖得不对（例如参数一致，仅依靠返回类型不同），则编译会出错，而不是被Java认为方法重载（除非参数类型也不一样，这样java会认为不是override，实际上它是overload）。</p>
<p>◆<strong>类初始化</strong></p>
<p>&nbsp;<wbr> 类的初始化大致上有这么几个方面。</p>
<p>a．静态变量的初始化 b．一般实例变量的初始化 c．构造函数的初始化</p>
<p>&nbsp;<wbr> 初始化的难点在于继承体系中。当有继承体系时，初始化始终要遵循的原则就是，无论如何必先初始化基类</p>
<p>&nbsp;<wbr>&nbsp;<wbr> 0．当载入当前类时，若当前类有继承体系，则依次无条件载入基类</p>
<p>&nbsp;<wbr>&nbsp;<wbr> 0&#8217;．先从最顶的基类开始顺序初始化其静态static变量，接着初始化当前类的静态static变量（也就是说，static变量的初始化是伴随着类被装载时而初始化的，它的初始化在任何构造函数执行前）</p>
<p>&nbsp;<wbr>&nbsp;<wbr> 1．先从最顶端基类，构造基类对象。</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> （假如构造函数中有this或super调用，则先执行此调用）</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 1.1．首先按出现次序初始化其实例变量</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr> 1.2．再执行其构造函数体</p>
<p>&nbsp;<wbr>&nbsp;<wbr> 2．依次递归上述步骤</p>
<p>&nbsp;<wbr> &lt;此外，实例变量可以不显式初始化（系统会赋默认值），但是局部变量必须显式初始化&gt;</p>
<p>◆<strong>异常</strong></p>
<p><strong>throws</strong><strong>是异常的申明，它置于方法的定义处；throw</strong><strong>是异常的掷出，它置于方法体内。</strong></p>
<p><strong>异常可分为可检测异常和非检测异常，调用申明为可检测异常的方法时必须捕获异常。</strong></p>
<p>a．方法申明了可检测异常，则调用该方法的块一定要捕获异常，否则编译出错</p>
<p>&nbsp;<wbr>&nbsp;<wbr> b．throw后面不能跟任何语句，否则编译提示语句不可到达</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>c．多个catch语句，要求更具体的异常在前，超类异常在后，否则编译出错</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>d．finally语句会在return语句之前执行，即在跳出方法之前一定会执行finally语句</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>e．假如遇到的是System.exit(0)，则无论如何，程序马上退出，finally语句不会执行</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>f．方法申明了异常，但是在方法体内可以不显示地用throw抛出异常</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>g．没有申明可检测异常的方法调用时，不可用catch捕获，否则编译出错</p>
<p>其它注意：</p>
<p>a子类中覆盖的方法只能抛出父类方法抛出异常的子集，也可以不抛出任何异常（这本身就是子集）</p>
<p>&nbsp;<wbr>&nbsp;<wbr> b 但是对于非检测异常RuntimeException则不会受到上面的约束，它们可以被随时抛出。也不受范围限制。</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> c 当继承的子类没有申明异常时，假如它的一个实例被申明为超类（向上转型），这时再调用子类没有申明异常的方法，而用了catch，程序也会编译通过。（实际运行中调用的还是子类中的方法）</p>
<p>◆<strong>equals()</strong><strong>和==</strong></p>
<p>&nbsp;<wbr> 对于上述关于equals()总结如下:</p>
<p>&nbsp;<wbr>&nbsp;<wbr> a．类型不兼容的两个对象可以用equals()，但是只要比较的对象类型不同（哪怕值相同），永远返回false</p>
<p>&nbsp;<wbr>&nbsp;<wbr> b．对于没有覆盖equals()的类，即使对象类型相同，值也相同，但返回的仍旧是false，因为它用的是object的默认equals方法（与==相同）</p>
<p>&nbsp;<wbr>&nbsp;<wbr> c然而对于覆盖equals()的类，只要值相同，便返回true。这些类是String,Wrappers,Date,Calendar,BitSet等</p>
<p>&nbsp;<wbr> 对于==总结如下：</p>
<p>&nbsp;<wbr>&nbsp;<wbr> a．类型不兼容的两个对象不可以用==，若用则编译错误</p>
<p>&nbsp;<wbr>&nbsp;<wbr> b．同种类型的对象，假如不是指引同一个对象，则返回为false（只有指向同一个内存块的对象才返回true）</p>
<p>&nbsp;<wbr>&nbsp;<wbr> c．对于String情况有些不同，因为String对象有字面量和构造函数之分。字面量对象是放在缓冲池中的，这意味着，如果两个字面量值相同，则第二个对象会指向第一个已经存在的对象，而不会新产生，所以==返回的是true。用构造器产生的对象同一般对象。对于字面量来说，多个类共享的是同一个缓冲池。这意味着在另外一个类中创建一个先前类中已有的字面量字符串，则仍旧是同一对象。</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 另外，注意，toUpperCase()、toLowerCase()方法而言，如果大小写形式与原始String没什么差别，方法返回原始对象，==返回true。</p>
<p>&nbsp;<wbr>&nbsp;<wbr> d．对于基本类型而言，系统会自动先归一精度，然后再比较值，若值相同则返回true。</p>
<p>◆<strong>String</strong></p>
<p>&nbsp;<wbr> String类最重要的一点在于&#8220;不变性（immutable）&#8221;。它的意思是一旦String类产生了就不会再改变了，若试图改变它都会产生新的对象。</p>
<p>&nbsp;<wbr> String对象有字面量和构造函数之分。字面量对象是放在缓冲池中的，这意味着，如果两个字面量值相同，则第二个对象会指向第一个已经存在的对象，而不会新产生，所以==返回的是true。用构造器产生的对象同一般对象。对于字面量来说，多个类共享的是同一个缓冲池。这意味着即使在另外一个类中创建一个先前类中已有的字面量字符串，则仍旧是同一对象。</p>
<p>&nbsp;<wbr> 考试中需要注意的是：s=new String(&#8220;abc&#8221;);s+=&#8221;def&#8221;;System.out.println(s);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>s=new String(&#8220;abc&#8221;);s.concat(&#8220;def&#8221;);System.out.prinln(s);</p>
<p>&nbsp;<wbr> 前一程序打印为&#8220;abcdef&#8221;，后一程序打印为&#8220;abc&#8221;。区别是第一个程序又重新赋值给了s。而第二个程序中s.concat(&#8220;def&#8221;)只是产生了一个新的对象但没有赋给谁，但原来的s不变。</p>
<p>&nbsp;<wbr> 另外，对于StringBuffer而言是可变的，对它的任何改变都是实时的。</p>
<p>◆<strong>包装类</strong></p>
<p>&nbsp;<wbr> 包装类是为了方便对基本数据类型操纵而出现的。有了包装类就可以用很多的方法来操纵基本数据类型（没有包装类想直接对基本数据类型操作是不方便的，除非自己编写方法）。</p>
<p>&nbsp;<wbr> 要熟悉包装类应该着种理解下面几点：</p>
<p>&nbsp;<wbr> a．包装类的构造器。一般说来，包装类的构造器参数有两种：<strong>基本数据值</strong>、<strong>字符串</strong></p>
<p><strong>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></strong> <strong>注意：</strong>Boolean包装类构造器当传入字符串时，除了不分大小写的true返回true外，其它字符串一律返回false</p>
<p>&nbsp;<wbr> b．常见的操作方法。例如：转换为本基本类型或其它基本类型的方法</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> eg. byteValue(),intValue()&#8230;;parseByte(String s),parseInt(String s)&#8230;</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> c．valueOf(各基本类型或字符串)的使用。ValueOf(str)是包装类的静态方法，作用等同于构造器。它会解析传入的参数，然后构造一个相同类型的包装类，并返回该包装类。</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 例子：原始类型&#224;字符串&nbsp;<wbr> (new Integer(101)).toString()；String.valueOf(&#8220;101&#8221;)</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 字符串&#224;（包装类）&#224;原始类型 Integer.parseInt(&#8220;string&#8221;)；</p>
<p>(new Integer(&#8220;101&#8221;)).doubleValue()；Integer.valueOf(&#8220;101&#8221;).intValue()</p>
<p>◆<strong>Math</strong><strong>类</strong></p>
<p>&nbsp;<wbr> Math类中都是静态方法。其中最易错的是三个方法：ceil(),floor(),round()</p>
<p>另外还需注意，有许多方法随基本数据类型不同有多个重载版本。eg.abs(),max()</p>
<p>a．ceil()方法。该方法返回类型为double，往单一的正坐标方向取最近的整数</p>
<p>b．floor()方法。该方法返回类型类double，取最靠近其负向的整数。</p>
<p>c．round()方法。它有两个重载版本：double和float，返回分别为long和int</p>
<p>&nbsp;<wbr>&nbsp;<wbr> long round(double a)；int round(float)</p>
<p>&nbsp;<wbr>&nbsp;<wbr> <strong>round()</strong><strong>方法＝Math.floor(a+0.5),这意味着正数5入，负数6入</strong></p>
<p><strong>&nbsp;<wbr>&nbsp;<wbr></strong> eg.System.out.println(Math.ceil(Double.MIN_VALUE))&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> //1.0</p>
<p>System.out.println(Math.floor(-0.1))&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> //-1.0</p>
<p>System.out.println(Math.round(-9.5))&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> //-9</p>
<p>System.out.println(Math.round(-9.6))&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> //-10</p>
<p>System.out.println(Math.round(Double.MIN_VALUE))&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> //0</p>
<p>◆<strong>collection</strong><strong>类</strong></p>
<p>&nbsp;<wbr> collection类提供了持有对象的便利性，并对持有对象的操作便利性。正如其名，收集意为将各种类型的对象收在一起，且数目不限（有点像收集袋）。收集会将放入其中的所有对象均视为Object（向上转型），所以在取出元素对象时，必须显式（即强制转型）指出其类型。</p>
<p>&nbsp;<wbr> 对象收集从整体上分为Collection接口和Map接口。这种分类的标准是：某个元素位置上放置元素对象的个数。显然，Map接口放置的是一对。</p>
<p>&nbsp;<wbr> Collection接口又可扩展为两个基本接口：List接口和Set接口。</p>
<p>&nbsp;<wbr> 依上所述，对象收集可以划分为四个基本的类型：<strong><em>Collection、List、Set、Map</em></strong></p>
<p>&nbsp;<wbr> &#183; Collection 它是一个基类的接口，对元素没有任何的限制，可以重复并且无序。</p>
<p>&nbsp;<wbr> &#183; List&nbsp;<wbr> 从其名就知是有序的列表。它描述的是按顺序将对象放入其中。显然，后放入的元素有可能与先前放入的对象是相同的。所以，List是允许对象重复出现的有序列表。</p>
<p>&nbsp;<wbr> &#183; Set&nbsp;<wbr>&nbsp;<wbr> 其实就是数学上所说的集合，它不允许有重复的元素。其中可以有空集（即null对象）。Set中的元素不要求有序。</p>
<p>&nbsp;<wbr> &#183; Map&nbsp;<wbr>&nbsp;<wbr> 即映射，借助于key和value来描述对象的搜索。key域中要求唯一性（其实就是一个Set），value域可以允许有重复的元素（其实就是一个Collection）。另外注意：常见的HashMap是无序的，而TreeMap是有序的。</p>
<p>◆<strong>标识符</strong></p>
<p>&nbsp;<wbr> a．所有标识符的首字符必须是字母（大小写）、下划线_、美元符号$（或符号￥）</p>
<p>b．接下来的可以是由数字（0-9）及首字符相同类型的字符（字母、_、$），其它任何特殊字符均不可</p>
<p>c．标识符不能使用Java关键字和保留字（50个）。但是注意像java,Integer,sizeof,friendly等都不是Java的关键字</p>
<p>d．标识符大小写是敏感的，但没有长度的限制。</p>
<p>◆<strong>Switch(i)</strong></p>
<p>&nbsp;<wbr> a．switch(i)中的参数最高精度是int（或者short,byte,char），但不可是long，float,double</p>
<p>&nbsp;<wbr> b．default语句可以放置于任何地方（default意为都不匹配case中的值）</p>
<p>&nbsp;<wbr> c．当语句中未加break语句时，则程序会从匹配的地方开始执行（包括匹配default语句），接下来所有的语句都会被执行（而不管匹配否），直到遇到break语句或switch尾部。</p>
<p>◆<strong>垃圾收集</strong></p>
<p>&nbsp;<wbr> a．只要一个对象失去了<strong>所有</strong>的reference，就可以考虑收集到垃圾收集堆了。</p>
<p>&nbsp;<wbr> B．当失去对一个对象的所有引用时，JVM只是考虑垃圾收集，但并不意味着就立刻收回这个对象的内存，甚至根本不收回。JVM仅会在需要更多的内存以继续执行程序时，才会进行垃圾收集。</p>
<p>C．多数情况下，你永远不会知道垃圾收集什么时候会发生。Java将垃圾收集进程作为一个低优先级线程在运行。在Java中垃圾收集是不能被强迫<strong>立即</strong>执行的。调用System.gc()或Runtime.gc()静态方法不能保证垃圾收集器的立即执行，因为，也许存在着更高优先级的线程。</p>
<p>D．如果你想人工调用垃圾收集，并想在收集对象时执行一些你想要的任务，你就可以覆盖一个叫finalize()的方法。java会为每一个对象只调用一次finalize()方法。<strong>finalize()方法必须被申明为protected的，不返回任何值（viod），而且要申明抛出一个Throwable对象，并一定要调用超类的finalize()方法（super.finalize()）。</strong></p>
<p>&nbsp;<wbr>&nbsp;<wbr> eg.protected void finalize() throws Throwable(){</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> super.finalize();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &#8230;&#8230;&#8230;&#8230;;}</p>
<p>◆<strong>is a &amp; has a</strong></p>
<p>&nbsp;<wbr> is a&nbsp;<wbr> 描述的是一个超类和一个子类的关系，也即是<strong>继承</strong>的关系。</p>
<p>&nbsp;<wbr> has a 描述的是一个对象的部分是另一个对象，也即是<strong>组合</strong>的关系（或称为调用）。</p>
<p>◆<strong>内类与匿名类</strong></p>
<p>&nbsp;<wbr> 内类是被包含的类中类，有三个方面需要注意：一般内类、方法内类、静态内类。</p>
<p>&nbsp;<wbr> &#183; 一般内类它可以被当做外类的一个&#8220;实例变量&#8221;来看待。因此，四个接入控制符public、protected、default、private。只是注意：要在外类的non-static函数外产生该内类对象，必须以<strong><em>OuterClassName.InnerClassName</em></strong>的形式指定该内类对象的<strong>类型申明</strong>。<strong>一般内类必须得关联至其外类的某个对象</strong>。</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 一般内类不可拥有static成员。</p>
<p>&#183; 方法内类它属于<strong>范围</strong>型内类，也就是说你无法在方法外来调用内类，从这一点来讲它可视为方法的局部变量。但是，虽然有它的范畴性，毕竟内类还是类，它不会像局部变量那样随着方法的返回就消失了，它仍旧被java视为类。</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> A．方法内类可以直接访问外类的任何成员</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> B．方法内类只能访问该方法中final型局部变量和final型的方法参数</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> C. 方法内类不可有任何<strong>接入控制符</strong>修饰（这一点与局部变量相同）</p>
<p>&nbsp;<wbr> &#183; 静态内类它在产生其对象时不需要存在一个外类对象。它可被视为static函数。</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> static内类可以置于接口中。</p>
<p>&nbsp;<wbr> &#183; 匿 名 类它实际上是<strong>继承</strong>自new类的一个无名类。New传回的reference会被自动向上转型。匿名类不能拥有构造器，但是可以通过其基类默认或带参数的构造器来申明。</p>
<p>匿名类添加任何修饰符（遵循超类的修饰符），也不可实现接口、抛出异常。</p>
<p>◆<strong>断言</strong></p>
<p>&nbsp;<wbr> 断言是Java 1.4中新添加的功能，是Java中的一种新的错误检查机制，它提供了一种在代码中进行正确性检查的机制，但是这项功能可以根据需要关闭。断言包括：<strong>assert</strong>关键字，<strong>AssertionError</strong>类，以及在java.lang.ClassLoader中增加了几个新的有关assert方法。</p>
<p>assert最重要的特点是assert语句可以在<strong>运行时</strong>任意的开启或关闭，默认情况下是关闭的。</p>
<p>断言语句有两种合法的形式：a．<strong>assert expression_r1;</strong> b．<strong>assert expression_r1 : expression_r2;</strong></p>
<p>expression_r1是一条被判断的布尔表达式，必须保证在程序执行过程中它的值一定是真；expression_r2是可选的，用于在expression_r1为假时，传递给抛出的异常AssertionError的构造器，因此expression_r2的类型必须是合法的AssertionError构造器的参数类型。AssertionError除了一个不带参数的缺省构造器外，还有7个带单个参数的构造器，分别为：object（eg.String） &nbsp;<wbr>boolean &nbsp;<wbr>char &nbsp;<wbr>int &nbsp;<wbr>long &nbsp;<wbr>float &nbsp;<wbr>double。第一种形式如果抛出异常，则调用AssertionError的缺省构造器，对于第二种形式，则根据expression_r2值的类型，分别调用7种单参数构造器中的一种。</p>
<p>A．<strong>assert</strong><strong>程序的编译</strong>：javac -source 1.4 TestAssert.java（提示java按1.4版本编译）</p>
<p>B．<strong>assert</strong><strong>程序的运行</strong>：java &#8211;ea TestAssert 或者 java &#8211;ea:TestAssert TestAssert</p>
<p>&nbsp;<wbr>&nbsp;<wbr> 其它的运行参数：java -ea:pkg0... TestAssert；java &#8211;esa；java &#8211;dsa（系统类断言），另外，还可以同时组合用。当一个命令行使用多项 -ea -da 参数时，遵循两个基本的原则：<strong>后面的参数设定会覆盖前面参数的设定，特定具体的参数设定会覆盖一般的参数设定</strong>。</p>
<p>C．<strong>AssertinError</strong><strong>类</strong>是Error的直接子类，因此代表程序出现了严重的错误，这种异常通常是不需要程序员使用catch语句捕捉的。</p>
<p>D．<strong>使用</strong><strong>assert</strong><strong>的准则</strong>：assert语句的作用是保证程序内部的一致性，而不是用户与程序之间的一致性，所以不应用在保证命令行参数的正确性。可以用来保证传递给<strong><em>private</em></strong>方法参数的正确性。因为私有方法只是在类的内部被调用，因而是程序员可以控制的，我们可以预期它的状态是正确和一致的。公有方法则不适用。此外，assert语句可用于检查任何方法结束时状态的正确性，及在方法的开始检查相关的初始状态等等。</p>
<p>assert语句并不构成程序正常运行逻辑的一部分，时刻记住在运行时它们可能不会被执行。</p>
<p>◆<strong>线程</strong></p>
<p>&nbsp;<wbr> 线程是将程序中容易消耗大量cpu且易陷入死循环的片断代码独立出来作为一个线程来运行（也即线程是一个代码块）。</p>
<p>&nbsp;<wbr> 线程一经启动start，就会进入ready状态（实际上就是runnable状态，只是等待分配cpu）。这也说明线程并不会马上就running，其运行具有不确定性。线程启动后，只要不跳出run()方法，则一直都有机会running，它由系统自动在各线程间分配cpu时间来running。要牢记的是：<strong>线程运行与中断具有不确定性，你永远也不知道线程何时会运行，何时会中断。</strong></p>
<p>&nbsp;<wbr> 线程从对象的角度来看，它自身也可以是一个对象。它可视为其它对象中的一个代码块。</p>
<p>&nbsp;<wbr> 在线程的概念中要特别注意几个概念：<strong>单线程</strong>、<strong>多线程</strong>、<strong>多线程的运行</strong>、<strong>多线程间的同步（资源访问）</strong>、<strong>多线程间的通信</strong>。</p>
<p>&nbsp;<wbr> &#183; <strong>单线程</strong> 对于单线程而言，编写其程序是比较简单的，也比较容易理解，因为它并不涉及到synchronized和communication问题。创建单线程的方法有两种，其一、扩展Thread类，即class A extends Thread{public void run(){};&#8230;&#8230;}；其二、实现Runnable接口，class B implements Runnable{Thread t=new Thread(this);public void run(){};&#8230;&#8230;}；</p>
<p>&nbsp;<wbr> &#183; <strong>多线程</strong> 相对于单线程而言，多线程会复杂很多，原因就是它们会涉及到<strong>多线程间的资源访问</strong>和<strong>多线程间通信</strong>问题。这就涉及到下面所说的三个方面：<strong>多线程的运行</strong>、<strong>多线程间的同步（资源访问）</strong>、<strong>多线程间的通信</strong></p>
<p>&nbsp;<wbr> &#183; <strong>多线程的运行</strong> 对于多个可运行runnable的线程来说，<strong>运行与中断具有不确定性，永远也无法知道线程何时会运行，何时会中断</strong>。但是多线程运行也遵循几个原则：如果多个线程具有同样的优先级，则系统会在它们之间切换cpu时间运行；<strong>JVM</strong><strong>基于优先级来决定线程的运行，但是这并不意味着一个低优先级的线程一直不运行</strong>。</p>
<p>&nbsp;<wbr> &#183; <strong>多线程的同步</strong> 被线程可访问的每个对象都有一个仅被一个线程访问控制的锁，锁控制着对对象的同步码的存取。这个可被多个线程访问的对象就是所说的资源共享问题。</p>
<p>A．在程序中，可以通过定义一个synchronized代码块或多个synchronized方法来使得调用的线程获得该对象的控制锁。通过获得对象的锁，该线程就会阻止其它线程对该对象所定义的<strong>同步块</strong>或<strong>同步方法</strong>进行操作（特别注意的是，此时并不能保证其它线程对该对象的非同步变量和非同步方法进行操作）。</p>
<p>B．线程只有在同步块或同步方法返回后才释放锁。</p>
<p>C．synchronized并不能保证程序的运行连续性，而只是保证同一性。也就是说即使在synchronized块或方法中，线程的运行仍旧会有中断的可能性。尽管如此，但它却能确保别的线程不会再访问该对象的其它同步块和方法，因为对象锁并未释放。这一事实说明了&#8220;多线程的运行&#8221;与&#8220;多线程间的同步&#8221;是两个独立的概念。</p>
<p>D．多线程的同步块或方法可以放在任何可被线程访问的对象中（包括线程本身，它实际上也可被其它的线程访问）。</p>
<p>&nbsp;<wbr> &#183; <strong>多线程间的通信</strong> 多线程间的同步消除了一个线程在改变另一个线程的稳定对象状态时发生的并发错误，但是就线程间通信而言，同步不起任何作用，也就是说&#8220;多线程间的通信&#8221;又是一个独立的概念。多线程间的通信通常是靠wait(),notify()两个方法来实现的，有关这两个方法的总结如下：</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 1.wait(),notify()属于<strong>object方法</strong>，并不是线程的方法</p>
<p>2.object.wait()&nbsp;<wbr> 意为：调用我（指该object）的当前线程你得等等，也就是使...（调用我的当前线程）...等待</p>
<p>object.notify()意为：该唤醒其它先前调用过我的且在等待的线程</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 从上述意义可知，wait(),notify()的对象是指线程所要用到的共享对象（当然共享对象也可以是线程对象），但是它的方法动作却是针对调用它的线程。（通常情况下，对象的方法是作用于自己的属性，而很少作用于其它对象。若要作用于其它对象，则用调用object.method()）</p>
<p>3.wait(),notify()必须成对出现，出现的方式可有3种形式。</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> A.｛wait();.... notify();｝</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> B.｛wait();｝... ｛object.notify();｝</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> C.｛notify();｝... ｛object.wait();｝</p>
<p>4.<strong>wait(),notify()</strong><strong>必须出现在synchronized方法或块中，否则会出现异常</strong>。原因是因为wait()会释放对象锁，而锁必然是出现在同步方法或块中。另外，wait()同sleep()一样，<strong>也必须捕捉异常InterruptedException</strong>。</p>
<p>5.wait(),notify()的执行一般与外在的条件有关，只有条件改变了才触发唤醒等待的线程。这种条件的改变通常是以旗标(Tag)的方式出现，也即当某一方法执行完后，应当立即改变旗标值。假若需要让线程交替执行，则还需要加入互斥条件的判断。eg.同步方法1中{if(a)}，则同步方法2中{if(!a)}</p>
<p>6.当执行完notify()时，程序并不会立即去运行调用wait()的线程，而直到释放notify()的对象锁。当释放完锁后，程序重新分配cpu，要注意的是，此时系统并不一定就让wait的线程去运行，而有可能是刚才调用notify()的线程接着继续运行。这一点正说明了线程运行与中断的不确定性。</p>
<p>7.一般说来，notify()是唤醒等待池中等待时间最长的线程；而notifyAll()是唤醒等待池中所有等待线程，然后线程去竞争对象锁。这里说的是一般情况，有时情况并非如此，这是由系统中线程运行与中断的不确定性决定的。</p>
<p>8.wait()，notify()通常情况下需要sleep()的配合，否则屏幕中的运行显式会&#8220;飞速&#8221;。</p>
<p>9.多线程间的通信会出现死锁现象，即wait的线程有可能永远也得不到对象锁。</p>
<p>-------------------------------------------------------------------------------</p>
<p>◆<strong>其他注意问题</strong></p>
<p>☆&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 数组</p>
<p>a．数组在使用之前，必须要保证给其分配内存（系统会用默认值初始化），不可只定义。否则编译通过运行也会出现空指针错误。分配内存只需通过new就可以了。</p>
<p>b．二维数组的第二维可以是变长的，而且可以在定义时不指定具体值。这意味着java中的二维数组不必像矩阵那样要求每一维长度都相同。</p>
<p>☆&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 变量赋值</p>
<p>a．实例变量只可在定义时显式赋值，不可先定义，再赋值（这样的话编译出错）。</p>
<p>b．方法变量既可以在定义时显式赋值，又可以先定义以后再赋值。</p>
<p>c．static变量可以在类的任何地方赋值（若在方法中赋值，实际上是重赋值了）。</p>
<p>d．final变量可以在任何地方赋值，但是一旦赋值，就不允许再次重赋值。</p>
<p>e．static final变量只能在定义处赋值（即：常量）。</p>
<p>☆&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 移位</p>
<p>a．&gt;&gt;&nbsp;<wbr> 首位的拷贝右移位。等同于有符号的除法。</p>
<p>b．&gt;&gt;&gt; 零填充右移位。</p>
<p>c．&lt;&lt;&nbsp;<wbr> 左移位。等同于有符号乘法，但是必须遵循整数的溢出原则。</p>
<p>d．&gt;&gt;32 &gt;&gt;&gt;32<strong>任何移多少位都是移模32的余数</strong>。eg.移32位即不移。</p>
<p>☆&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> byte、char和int</p>
<p>由于char的取值范围和int的正取值范围相同，所以，整型字面量可以直接赋给char。但是要是明确将一个整型（int）变量直接赋给char变量则编译错误。</p>
<p>另外，int i=5;char c=&#8217;a&#8217;;c+=i;编译是通过的。</p>
<p>byte类型在强制转型的情况下，当范围超出时会循环溢出。</p>
<p>☆&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 求模%</p>
<p>求余只管左边的符号，右边不管。</p>
<p>eg. int a=-5;int b=-2;System.out.println(a%b) //-1</p>
<p>&nbsp;<wbr>&nbsp;<wbr> int a=-5;int b=2;System.out.println(a%b) //-1</p>
<p>&nbsp;<wbr>&nbsp;<wbr> int a=5;int b=-2;System.out.println(a%b) //1</p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/balajinima/aggbug/298542.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/balajinima/" target="_blank">李云泽</a> 2009-10-16 11:49 <a href="http://www.blogjava.net/balajinima/articles/298542.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第九部分：集合类框架</title><link>http://www.blogjava.net/balajinima/articles/298540.html</link><dc:creator>李云泽</dc:creator><author>李云泽</author><pubDate>Fri, 16 Oct 2009 03:44:00 GMT</pubDate><guid>http://www.blogjava.net/balajinima/articles/298540.html</guid><wfw:comment>http://www.blogjava.net/balajinima/comments/298540.html</wfw:comment><comments>http://www.blogjava.net/balajinima/articles/298540.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/balajinima/comments/commentRss/298540.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/balajinima/services/trackbacks/298540.html</trackback:ping><description><![CDATA[<p style="text-indent: 2em" align="left">第九部分：集合类框架</p>
<ul style="text-indent: 2em" type="square">
    <li>知道如何在特定的条件下选择适合的集合类/接口。
    <li>能正确地实现hashcode方法。 </li>
</ul>
<h2 style="text-indent: 2em">第一节&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 所有接口和class定义</h2>
<p style="text-indent: 2em">1:Set</p>
<p style="text-indent: 2em">public interface Set extends Collection</p>
<p style="text-indent: 2em">A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element. As implied by its name, this interface models the mathematical set abstraction.</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">2:SortedSet</p>
<p style="text-indent: 2em">public interface SortedSet extends Set.</p>
<p style="text-indent: 2em">A set that further guarantees that its iterator will traverse the set in ascending element order, sorted according to the natural ordering of its elements (see Comparable), or by a Comparator provided at sorted set creation time.</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">3:HashSet</p>
<p style="text-indent: 2em">public class HashSet extends AbstractSet implements Set, Cloneable, Serializable</p>
<p style="text-indent: 2em">This class implements the Set interface, backed by a hash table (actually a HashMap instance). It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time. This class permits the null element.</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">4:TreeSet</p>
<p style="text-indent: 2em">public class TreeSet extends AbstractSet implements SortedSet, Cloneable, Serializable</p>
<p style="text-indent: 2em">This class implements the Set interface, backed by a TreeMap instance. This class guarantees that the sorted set will be in ascending element order, sorted according to the natural order of the elements (see Comparable), or by the comparator provided at set creation time, depending on which constructor is used.</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">5:LinkedHashSet:</p>
<p style="text-indent: 2em">public class LinkedHashSet extends HashSet implements Set, Cloneable, Serializable</p>
<p style="text-indent: 2em">Hash table and linked list implementation of the Set interface, with predictable iteration order. This implementation differs from HashSet in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order). Note that insertion order is not affected if an element is re-inserted into the set. (An element e is reinserted into a set s if s.add(e) is invoked when s.contains(e) would return true immediately prior to the invocation.)</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">5:Map</p>
<p style="text-indent: 2em">public interface Map</p>
<p style="text-indent: 2em">An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value.</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">6:SortedMap</p>
<p style="text-indent: 2em">public interface SortedMap extends Map</p>
<p style="text-indent: 2em">A map that further guarantees that it will be in ascending key order, sorted according to the natural ordering of its keys (see the Comparable interface), or by a comparator provided at sorted map creation time. (This interface is the map analogue of the SortedSet interface.)</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">7:HashMap(允许key和value为NULL)</p>
<p style="text-indent: 2em">public class HashMap extends AbstractMap implements Map, Cloneable, Serializable</p>
<p style="text-indent: 2em">Hash table based implementation of the Map interface. This implementation provides all of the optional map operations, and permits null values and the null key. (The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.) This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">8:TreeMap</p>
<p style="text-indent: 2em">public class TreeMap extends AbstractMap implements SortedMap, Cloneable, Serializable</p>
<p style="text-indent: 2em">Red-Black tree based implementation of the SortedMap interface. This class guarantees that the map will be in ascending key order, sorted according to the natural order for the key's class (see Comparable), or by the comparator provided at creation time, depending on which constructor is used.</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">9:HashTable(不允许key和value为NULL)</p>
<p style="text-indent: 2em">public class Hashtable extends Dictionary implements Map, Cloneable, Serializable.</p>
<p style="text-indent: 2em">This class implements a hashtable, which maps keys to values. Any non-null object can be used as a key or as a value.</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">9:LinkedHashMap</p>
<p style="text-indent: 2em">public class LinkedHashMap extends HashMap</p>
<p style="text-indent: 2em">Hash table and linked list implementation of the Map interface, with predictable iteration order. This implementation differs from HashMap in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order). Note that insertion order is not affected if a key is re-inserted into the map. (A key k is reinserted into a map m if m.put(k, v) is invoked when m.containsKey(k) would return true immediately prior to the invocation.)</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">9:IdentityHashMap</p>
<p style="text-indent: 2em">public class IdentityHashMap extends AbstractMap implements Map, Serializable, Cloneable</p>
<p style="text-indent: 2em">This class implements the Map interface with a hash table, using reference-equality in place of object-equality when comparing keys (and values). In other words, in an IdentityHashMap, two keys k1 and k2 are considered equal if and only if (k1==k2). (In normal Map implementations (like HashMap) two keys k1 and k2 are considered equal if and only if (k1==null ? k2==null : k1.equals(k2)).)</p>
<p style="text-indent: 2em">This class is not a general-purpose Map implementation! While this class implements the Map interface, it intentionally violates Map's general contract, which mandates the use of the equals method when comparing objects. This class is designed for use only in the rare cases wherein reference-equality semantics are required.</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">10:List</p>
<p style="text-indent: 2em">public interface List extends Collection</p>
<p style="text-indent: 2em">An ordered collection (also known as a sequence). The user of this interface has precise control over where in the list each element is inserted. The user can access elements by their integer index (position in the list), and search for elements in the list.</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">Unlike sets, lists typically allow duplicate elements. More formally, lists typically allow pairs of elements e1 and e2 such that e1.equals(e2), and they typically allow multiple null elements if they allow null elements at all.</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">11:ArrayList</p>
<p style="text-indent: 2em">public class ArrayList extends AbstractList implements List, Cloneable, Serializable</p>
<p style="text-indent: 2em">Resizable-array implementation of the List interface. Implements all optional list operations, and permits all elements, including null. In addition to implementing the List interface, this class provides methods to manipulate the size of the array that is used internally to store the list. (This class is roughly equivalent to Vector, except that it is unsynchronized.)</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">12:LinkedList</p>
<p style="text-indent: 2em">public class LinkedList extends AbstractSequentialList implements List, Cloneable, Serializable</p>
<p style="text-indent: 2em">Linked list implementation of the List interface. Implements all optional list operations, and permits all elements (including null). In addition to implementing the List interface, the LinkedList class provides uniformly named methods to get, remove and insert an element at the beginning and end of the list. These operations allow linked lists to be used as a stack, queue, or double-ended queue (deque).</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">13:Vector</p>
<p style="text-indent: 2em">public class Vector extends AbstractList implements List, Cloneable, Serializable</p>
<p style="text-indent: 2em">The Vector class implements a growable array of objects. Like an array, it contains components that can be accessed using an integer index. However, the size of a Vector can grow or shrink as needed to accommodate adding and removing items after the Vector has been created.</p>
<p style="text-indent: 2em">&nbsp;<wbr></p>
<p style="text-indent: 2em">14:Collection</p>
<p style="text-indent: 2em">public interface Collection</p>
<p style="text-indent: 2em">The root interface in the collection hierarchy. A collection represents a group of objects, known as its elements. Some collections allow duplicate elements and others do not. Some are ordered and others unordered. The SDK does not provide any direct implementations of this interface: it provides implementations of more specific subinterfaces like Set and List. This interface is typically used to pass collections around and manipulate them where maximum generality is desired.</p>
<p style="text-indent: 2em">15:Collections</p>
<p style="text-indent: 2em">public class Collections extends Object</p>
<p style="text-indent: 2em">This class consists exclusively of static methods that operate on or return collections. It contains polymorphic algorithms that operate on collections, "wrappers", which return a new collection backed by a specified collection, and a few other odds and ends.</p>
<img src ="http://www.blogjava.net/balajinima/aggbug/298540.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/balajinima/" target="_blank">李云泽</a> 2009-10-16 11:44 <a href="http://www.blogjava.net/balajinima/articles/298540.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第七部分：线程</title><link>http://www.blogjava.net/balajinima/articles/298538.html</link><dc:creator>李云泽</dc:creator><author>李云泽</author><pubDate>Fri, 16 Oct 2009 03:43:00 GMT</pubDate><guid>http://www.blogjava.net/balajinima/articles/298538.html</guid><wfw:comment>http://www.blogjava.net/balajinima/comments/298538.html</wfw:comment><comments>http://www.blogjava.net/balajinima/articles/298538.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/balajinima/comments/commentRss/298538.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/balajinima/services/trackbacks/298538.html</trackback:ping><description><![CDATA[<p align="left">第七部分：线程</p>
<ul type="disc">
    <li>能用java.lang,Thread或java.lang.Runnable两种方法定义，实例化和开始一个新的线程。
    <li>知道哪些情况下可能阻止一个线程的执行。
    <li>能使用synchronized,wait,notify和notifyAll去避免并发访问的问题，以及线程间相互通讯的问题。
    <li>当执行synchronized,wait,notify和notifyAll时，知道线程和对象锁之间的交互作用。 </li>
</ul>
<div>
<h3><a name="_Toc74451196">&#167;1.1.1&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 一</a></h3>
<p>What will happen when you attempt to compile and run the following code?</p>
<p>class MyThread extends Thread</p>
<p>{</p>
<p>public void run()</p>
<p>{</p>
<p>System.out.println("MyThread: run()");</p>
<p>}</p>
<p>public void start()</p>
<p>{</p>
<p>System.out.println("MyThread: start()");</p>
<p>}</p>
<p>}</p>
<p>class MyRunnable implements Runnable</p>
<p>{</p>
<p>public void run()</p>
<p>{</p>
<p>System.out.println("MyRunnable: run()");</p>
<p>}</p>
<p>public void start()</p>
<p>{</p>
<p>System.out.println("MyRunnable: start()");</p>
<p>}</p>
<p>}</p>
<p>public class MyTest</p>
<p>{</p>
<p>public static void main(String args[])</p>
<p>{</p>
<p>MyThread myThread &nbsp;<wbr>= &nbsp;<wbr>new MyThread();</p>
<p>MyRunnable myRunnable = new MyRunnable();</p>
<p>Thread thread &nbsp;<wbr>= &nbsp;<wbr>new Thread(myRunnable);</p>
<p>myThread.start();</p>
<p>thread.start();</p>
<p>}</p>
<p>}</p>
<p>Choices:</p>
<p>a. Prints : MyThread: start() followed by MyRunnable:run()</p>
<p>b. Prints : MyThread: run() followed by MyRunnable:start()</p>
<p>c. Prints : MyThread: start() followed by MyRunnable:start()</p>
<p>d. Prints : MyThread: run() followed by MyRunnable:run()</p>
<p>e. Compile time error</p>
<p>f. None of the above</p>
<p>―――――――――――――――</p>
<p>A is the correct choice. In the above code there is not any compilation error. Thus choice E is incorrect. Inside main() method, objects of MyThread and MyRunnable class are created followed by creation of Thread with object of MyRunnable class. Note that MyThread class extends Thread class and overrides the start() method of the Thread class. Thus on execution of "myThread.start()" statement, the start() method of the MyThread class will be executed and as a result "MyThread:start()" will be printed. Had the start() method not there in MyThread class, the start() method of the Thread class would be called which in turn would call the run() method of the MyThread class. On execution of "thread.start();", the start() method of the Thread class would be called which in turn will call the run() method of the class which is passed to Thread constructor (i.e. MyRunnable class). Thus "MyRunnable:run()" will be printed out. Thus choice A is correct.</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451197">&#167;1.1.2&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 二</a></h3>
<p>What will be the output on compiling/running the following code?</p>
<p>public class MyThread implements Runnable</p>
<p>{</p>
<p>&nbsp;<wbr> String myString = "Yes ";</p>
<p>&nbsp;<wbr> public void run()</p>
<p>&nbsp;<wbr> {</p>
<p>&nbsp;<wbr> &nbsp;<wbr> this.myString = "No ";</p>
<p>&nbsp;<wbr> }</p>
<p>&nbsp;<wbr> public static void main(String[] args)</p>
<p>&nbsp;<wbr> {</p>
<p>&nbsp;<wbr> &nbsp;<wbr> MyThread t = new MyThread();</p>
<p>&nbsp;<wbr> &nbsp;<wbr> new Thread(t).start();</p>
<p>&nbsp;<wbr> &nbsp;<wbr> for (int i=0; i &lt; 10; i++)</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>System.out.print(t.myString);</p>
<p>&nbsp;<wbr> }</p>
<p>}</p>
<div>
<p>Choices:</p>
<p>a. Compilation Error &nbsp;<wbr></p>
<p>b. Prints : Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes and so on.</p>
<p>c. Prints : No No No No No No No No No No and so on.</p>
<p>d. Prints : Yes No Yes No Yes No Yes No Yes No and so on.</p>
<p>e. The Output cannot be determined.</p>
</div>
<p>E is correct. Please note that there will not be any compilation error when the above code is compiled. Also note that calling start() method on a Thread doesn't start the Thread. It only makes a Thread ready to be called. Depending on the operation system and other running threads, the thread on which start is called will get executed. In the above case it is not guaranteed that the thread will be executed(i.e. run() method will be called), always before "for" loop is executed. Thus the output cannot be determined.</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451198">&#167;1.1.3&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 三</a></h3>
<p>Multiple objects of MyClass (given below) are used in a program that uses</p>
<p>multiple Threadsto create new integer count. What will happen when other threads</p>
<p>use the following code?</p>
<p>class MyClass</p>
<p>{</p>
<p>static private int myCount = 0;</p>
<p>int yourNumber;</p>
<p>private static synchronized int nextCount()</p>
<p>{</p>
<p>return ++myCount;</p>
<p>}</p>
<p>public void getYourNumber()</p>
<p>{</p>
<p>yourNumber = nextCount();</p>
<p>}</p>
<p>}</p>
<p>Choices:</p>
<p>a. The code will give compilation error.</p>
<p>b. The code will give runtime error.</p>
<p>c. Each thread will get a unique number.</p>
<p>d. The uniqueness of the number among different Threads can't be guaranteed.</p>
<p>―――――――――――――</p>
<p>C is correct. The use of synchronized ensures that the number generated will not be duplicated, no matter how many Threads are trying to create the number. Thus D is incorrect. A and B are incorrect as the above code will not give any compiletime or runtime error.</p>
<h3><a name="_Toc74451199">&#167;1.1.4&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 四</a></h3>
<p>What will happen when you attempt to compile and run the following code?</p>
<p>public class MyThread extends Thread</p>
<p>{</p>
<p>String myName;</p>
<p>MyThread(String name)</p>
<p>{</p>
<p>myName = name;</p>
<p>}</p>
<p>public void run()</p>
<p>{</p>
<p>for(int i=0; i&lt;100;i++)</p>
<p>{</p>
<p>System.out.println(myName);</p>
<p>}</p>
<p>}</p>
<p>public static void main(String args[])</p>
<p>{</p>
<p>try</p>
<p>{</p>
<p>MyThread mt1 = new MyThread("mt1");</p>
<p>MyThread mt2 = new MyThread("mt2");</p>
<p>mt1.start();</p>
<p>// XXX</p>
<p>mt2.start();</p>
<p>}</p>
<p>catch(InterruptedException ex)</p>
<p>{</p>
<p>}</p>
<p>}</p>
<p>}</p>
<p>Choices:</p>
<p>a.The above code in its current condition will not compile.</p>
<p>b. In order to make the MyThread class prints "mt1" (100 times) followed by</p>
<p>"mt2" (100 times), mt1.join(); can be placed at //XXX position.</p>
<p>c. In order to make the MyThread class prints "mt1" (100 times) followed by</p>
<p>"mt2" (100 times), mt1.sleep(100); can be placed at //XXX position.</p>
<p>d. In order to make the MyThread class prints "mt1" (100 times) followed by</p>
<p>"mt2" (100 times), mt1.run(); can be placed at //XXX position.</p>
<p>e. In order to make the MyThread class prints "mt1" (100 times) followed by</p>
<p>"mt2" (100 times), there is no need to write any code.</p>
<p>――――――――――――――</p>
<p>A and B are correct. In its current condition, the above code will not compile as "InterruptedException" is never thrown in the try block. The compiler will give following exception: "Exception java.lang.InterruptedException is never thrown in the body of the corresponding try statement." Note that calling start() method on a Thread doesn't start the Thread. It only makes a Thread ready to be called. Depending on the operating system and other running threads, the thread on which start is called will get executed. After making the above code to compile (by changing the InterruptedException to some other type like Exception), the output can't be predicted (the order in which mt1 and mt2 will be printed can't be guaranteed). In order to make the MyThread class prints "mt1" (100 times) followed by "mt2" (100 times), mt1.join() can be placed at //XXX position. The join() method waits for the Thread on which it is called to die. Thus on calling join() on mt1, it is assured that mt2 will not be executed before mt1 is completed. Also note that the join() method throws InterruptedException, which will cause the above program to compile successfully. Thus choice A and B are correct.</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451200">&#167;1.1.5&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 五</a></h3>
<p>What will happen when you attempt to compile and run the following code?</p>
<p>public class MyThread extends Thread{</p>
<p>String myName;</p>
<p>MyThread(String name){</p>
<p>myName = name;</p>
<p>}</p>
<p>public void run(){</p>
<p>for(int i=0; i&lt;100;i++){</p>
<p>System.out.println(myName);</p>
<p>}</p>
<p>}</p>
<p>public static void main(String args[]){</p>
<p>try{</p>
<p>MyThread mt1 = new MyThread("mt1");</p>
<p>MyThread mt2 = new MyThread("mt2");</p>
<p>mt1.start();</p>
<p>// XXX</p>
<p>mt2.start();</p>
<p>}catch(InterruptedException ex){}</p>
<p>}</p>
<p>}</p>
<p>A. compile error</p>
<p>B. mt1.join();</p>
<p>C. mt1.sleep(100);</p>
<p>D. mt1.run()</p>
<p>E. nothing need</p>
<p>&nbsp;<wbr></p>
<p>Choice A and B are correct. In its current condition, the above code will not compile as "InterruptedException" is never thrown in the try block. The compiler will give following exception: "Exception java.lang.InterruptedException is never thrown in the body of the corresponding try statement."</p>
<p>Note that calling start() method on a Thread doesn't start the Thread. It only makes a Thread ready to be called. Depending on the operating system and other running threads, the thread on which start is called will get executed. After making the above code to compile (by changing the InterruptedException to some other type like Exception), the output can't be predicted (the order in which mt1 and mt2 will be printed can't be guaranteed). In order to make the MyThread class prints "mt1" (100 times) followed by "mt2" (100 times), mt1.join() can be placed at //XXX position. The join() method waits for the Thread on which it is called to die. Thus on calling join() on mt1, it is assured that mt2 will not be executed before mt1 is completed. Also note that the join() method throws InterruptedException, which will cause the above program to compile successfully. Thus choice A and B are correct.</p>
<h3><a name="_Toc74451201">&#167;1.1.6&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 六</a></h3>
<p>Multiple objects of MyClass (given below) are used in a program that uses multiple Threads to create new integer count. What will happen when other threads use the following code?</p>
<p>class MyClass{</p>
<p>static private int myCount = 0;</p>
<p>int yourNumber;</p>
<p>private static synchronized int nextCount(){</p>
<p>return ++myCount;&nbsp;<wbr>&nbsp;<wbr> //myCount为static</p>
<p>}</p>
<p>public void getYourNumber(){</p>
<p>yourNumber = nextCount();</p>
<p>}</p>
<p>}</p>
<p>A. the code ill give ompilation error</p>
<p>B. the code ill give runtime error</p>
<p>C. each thread will get a unique number</p>
<p>D. the uniqueness of the number different Threads can&#8217;t be guaranteed.</p>
<p>&nbsp;<wbr></p>
<p>C is correct. The use of synchronized ensures that the number generated will not be duplicated, no matter how many Threads are trying to create the number. Thus D is incorrect. A and B are incorrect as the above code will not give any compiletime or runtime error.</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451202">&#167;1.1.7&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 七</a></h3>
<p>What will be the output on compiling/running the following code?</p>
<p>public class MyThread implements Runnable {</p>
<p>&nbsp;<wbr> String myString = "Yes ";</p>
<p>&nbsp;<wbr> public void run() {</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> this.myString = "No ";</p>
<p>&nbsp;<wbr> }</p>
<p>&nbsp;<wbr> public static void main(String[] args)&nbsp;<wbr> {</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> MyThread t = new MyThread();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> new Thread(t).start();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> for (int i=0; i &lt; 10; i++)</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.print(t.myString);</p>
<p>&nbsp;<wbr> }</p>
<p>}</p>
<p>A. compile error</p>
<p>B. prints: yes yes yes yes yes yes and so on</p>
<p>C. prints: no no no no no no no no and so on</p>
<p>D. prints: yes no yes no ye no ye no and so on</p>
<p>E. the output cannot be determinated</p>
<p>&nbsp;<wbr></p>
<p>E is correct. Please note that there will not be any compilation error when the above code is compiled. Also note that calling start() method on a Thread doesn't start the Thread. It only makes a Thread ready to be called. Depending on the operation system and other running threads, the thread on which start is called will get executed. In the above case it is not guaranteed that the thread will be executed(i.e. run() method will be called), always before "for" loop is executed. Thus the output cannot be determined.</p>
<h3><a name="_Toc74451203">&#167;1.1.8&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 八</a></h3>
<p>Which statements about thread are true?</p>
<p>　　A. Once a thread is created, it can star running immediately.</p>
<p>&nbsp;<wbr></p>
<p>　　B. To use the start() method makes a thread runnable, but it does not</p>
<p>necessarily start immediately.</p>
<p>&nbsp;<wbr></p>
<p>　　C. When a thread stops running because of pre-emptive, it is placed at</p>
<p>the front end of the runnable queue.</p>
<p>&nbsp;<wbr></p>
<p>　　D. A thread may cease to be ready for a variety of reasons.</p>
<p>&nbsp;<wbr></p>
<p>　　(bd)</p>
<p>&nbsp;<wbr></p>
<p>　　题目：有关线程的哪些叙述是对的。</p>
<p>&nbsp;<wbr></p>
<p>　　A. 一旦一个线程被创建，它就立即开始运行。</p>
<p>&nbsp;<wbr></p>
<p>　　B. 使用start()方法可以使一个线程成为可运行的，但是它不一定立即开始运行。</p>
<p>&nbsp;<wbr></p>
<p>　　C. 当一个线程因为抢先机制而停止运行，它被放在可运行队列的前面。</p>
<p>&nbsp;<wbr></p>
<p>　　D. 一个线程可能因为不同的原因停止（cease）并进入就绪状态。</p>
<p>&nbsp;<wbr></p>
<p>　　一个新创建的线程并不是自动的开始运行的，必须调用它的start()方法使之将线程放入</p>
<p>可运行态（runnable</p>
<p>state），这只是意味着该线程可为JVM的线程调度程序调度而不是意味着它可以立即运行。</p>
<p>线程的调度是抢先式的，而不是分时间片式的。具有比当前运行线程高优先级的线程可以使当</p>
<p>前线程停止运行而进入就绪状态，不同优先级的线程间是抢先式的，而同级线程间是轮转式的</p>
<p>。一个线程停止运行可以是因为不同原因，可能是因为更高优先级线程的抢占，也可能是因为</p>
<p>调用sleep()方法，而即使是因为抢先而停止也不一定就进入可运行队列的前面，因为同级线</p>
<p>程是轮换式的，它的运行可能就是因为轮换，而它因抢占而停止后只能在轮换队列中排队而不</p>
<p>能排在前面。</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451204">&#167;1.1.9&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 九</a></h3>
<p>Which two CANNOT directly cause a thread to stop executing? (Choose Two)</p>
<p>&nbsp;<wbr></p>
<p>A.Existing from a synchronized block</p>
<p>B.Calling the wait method on an object</p>
<p>C.Calling notify method on an object</p>
<p>D.Calling read method on an InputStream object</p>
<p>E.Calling the SetPriority method on a Thread object</p>
<p>Answer：AC。同55题</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451205">&#167;1.1.10 十</a></h3>
<p>&nbsp;<wbr>public class SyncTest{</p>
<p>&nbsp;<wbr>public static void main(String[] args)&nbsp;<wbr> {</p>
<p>&nbsp;<wbr>final StringBuffer s1= new StringBuffer();</p>
<p>&nbsp;<wbr>final StringBuffer s2= new StringBuffer();</p>
<p>&nbsp;<wbr>new Thread ()&nbsp;<wbr>&nbsp;<wbr> {</p>
<p>&nbsp;<wbr>&nbsp;<wbr> public void run() {</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> synchronized(s1) {</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> s2.append(&#8220;A&#8221;);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> synchronized(s2) {</p>
<p>&nbsp;<wbr>&nbsp;<wbr> s2.append(&#8220;B&#8221;);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.print(s1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.print(s2);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p>&nbsp;<wbr>&nbsp;<wbr> }&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>}.start();</p>
<p>&nbsp;<wbr>new Thread() {</p>
<p>&nbsp;<wbr>&nbsp;<wbr> public void run() {</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> synchronized(s2) {</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> s2.append(&#8220;C&#8221;);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> synchronized(s1) {</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> s1.append(&#8220;D&#8221;);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.print(s2);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.print(s1);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }.start();</p>
<p>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p>&nbsp;<wbr>}</p>
<p>Which two statements are true? (Choose Two)</p>
<p>A. The program prints &#8220;ABBCAD&#8221;</p>
<p>B. The program prints &#8220;CDDACB&#8221;</p>
<p>C. The program prints &#8220;ADCBADBC&#8221;</p>
<p>D. The output is a non-deterministic point because of a possible deadlock condition</p>
<p>E. The output is dependent on the threading model of the system the program is running on.</p>
<p>Answer：DE</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451206">&#167;1.1.11 十一</a></h3>
<p>What will happen when you attempt to compile and run the following code?</p>
<p>public class Test{&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr> int i = 0;&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr> public static void main(String argv[]) {&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Test t = new Test();&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> t.myMethod();&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr> }&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr> public void myMethod(){&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> while(true) {&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> try {&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>wait();&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }catch (InterruptedException e) {}&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> i++;&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p>}</p>
<p>A. Compile time error, no matching notify within the method.</p>
<p>B. Compile and run but an infinite looping of the while method.</p>
<p>C. Compilation and run without any output.</p>
<p>E. Runtime Exception "IllegalMonitorStatException".</p>
<p>Answer: E</p>
<p>Note: The wait/notify protocol can only be used within code that is synchronized. In this case calling code does not have a lock on the object(not synchronized) and will thus cause an Exception at runtime.</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451207">&#167;1.1.12 十二</a></h3>
<p>1.10 What is the result of compiling and executing the following code?</p>
<p>public class ThreadTest extends Thread {&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> public void run() {&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println("In run");&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> yield();&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println("Leaving run");&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> public static void main(String args []) {&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> (new ThreadTest()).start();&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p>}</p>
<p>A. The code fails to compile in the main() method.</p>
<p>B. The code fails to compile in the run() method.</p>
<p>C. Only the text "In run" will be displayed.</p>
<p>D. The text "In run" followed by "Leaving run" will be displayed.</p>
<p>E. The code compiles correctly, but nothing is displayed.</p>
<p>Answer: D</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451208">&#167;1.1.13 十三</a></h3>
<p>Which of the following will definitely stop a thread from executing?A. wait()B. notify()C. yield()D. suspend()E. sleep()Answer: ACDE</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451209">&#167;1.1.14 十四</a></h3>
<p>Which of the following will definitely stop a thread from executing?</p>
<p>A. wait()</p>
<p>B. notify()</p>
<p>C. yield()</p>
<p>D. suspend()</p>
<p>E. sleep()</p>
<p>Answer: ACDE</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451210">&#167;1.1.15 十五</a></h3>
<p>&nbsp;<wbr>Which of the following statements about threading are true?</p>
<p>A. You can only obtain a mutually exclusive lock on methods in a class that extends Thread or implements runnable.</p>
<p>B. You can obtain a mutually exclusive lock on any object.</p>
<p>C. You can't obtain a mutually exclusive lock on any object.</p>
<p>D. Thread scheduling algorithms are platform dependent.</p>
<p>Answer: BD</p>
<p>8:</p>
<p>Consider the following statement:&nbsp;<wbr>&nbsp;<wbr></p>
<p>Thread myThread = new Thread();</p>
<p>Which of the following statements are true regarding myThread?</p>
<p>A. The thread myThread is now in a runnable state.</p>
<p>B. The thread myThread has a priority of 5.</p>
<p>C. On calling the start() method on myThread, the run method in the Thread class will be executed.</p>
<p>D. On calling the start() method on myThread, the run method in the calling class will be executed.</p>
<p>Answer: C</p>
<p>Note: the priority of myThread will be inherited from the Thread that called the constructor.</p>
<h3><a name="_Toc74451211">&#167;1.1.16 十六</a></h3>
<p>What is the effect of issuing a wait() method on an object？（Mutiple）</p>
<p>1) If a notify() method has already been sent to that object then it has no effect</p>
<p>2) The object issuing the call to wait() will halt until another object sends a notify() or notifyAll() method</p>
<p>3) An exception will be raised</p>
<p>4) The object issuing the call to wait() will be automatically synchronized with any other objects using the receiving object.</p>
<p>ANSWER 1)</p>
<p>10:</p>
<p>Pick all the true statements below.</p>
<p>1) If a thread wants to call wait() on an object, the thread must own that object's lock.</p>
<p>2) There is a method that you can call on an instance of the Thread class that puts the instance to sleep for a specified&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> number of milliseconds.</p>
<p>3) At the moment when a thread is notified, it automatically gets the lock of the object for which it was waiting.</p>
<p>ANSWER 1</p>
<p>&nbsp;<wbr></p>
</div>
<img src ="http://www.blogjava.net/balajinima/aggbug/298538.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/balajinima/" target="_blank">李云泽</a> 2009-10-16 11:43 <a href="http://www.blogjava.net/balajinima/articles/298538.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第八部分：在java.lang包中的基础类</title><link>http://www.blogjava.net/balajinima/articles/298539.html</link><dc:creator>李云泽</dc:creator><author>李云泽</author><pubDate>Fri, 16 Oct 2009 03:43:00 GMT</pubDate><guid>http://www.blogjava.net/balajinima/articles/298539.html</guid><wfw:comment>http://www.blogjava.net/balajinima/comments/298539.html</wfw:comment><comments>http://www.blogjava.net/balajinima/articles/298539.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/balajinima/comments/commentRss/298539.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/balajinima/services/trackbacks/298539.html</trackback:ping><description><![CDATA[<p align="left">第八部分：在java.lang包中的基础类</p>
<ul type="disc">
    <li>能够应用Math类中的abs,ceil,floor,max,min,random,round,sin,cos,tan,sqrt方法。
    <li>正确理解String类不可改变的意义。
    <li>当执行一段程序，中间包含有wrapper类的一个实例，知道它运行的前提条件运行结果。能用下面wrapper类（例如Integer,Double,等等）的方法来写程序： </li>
</ul>
<p align="left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> doublevalue</p>
<p align="left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> floatvalue</p>
<p align="left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> intvalue</p>
<p align="left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> longvalue</p>
<p align="left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> parseXxx</p>
<p align="left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> getXxx</p>
<p align="left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> toString</p>
<p align="left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> toHexString</p>
<img src ="http://www.blogjava.net/balajinima/aggbug/298539.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/balajinima/" target="_blank">李云泽</a> 2009-10-16 11:43 <a href="http://www.blogjava.net/balajinima/articles/298539.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第六部分：覆盖，重载，运行时期类型及其面向对象</title><link>http://www.blogjava.net/balajinima/articles/298537.html</link><dc:creator>李云泽</dc:creator><author>李云泽</author><pubDate>Fri, 16 Oct 2009 03:42:00 GMT</pubDate><guid>http://www.blogjava.net/balajinima/articles/298537.html</guid><wfw:comment>http://www.blogjava.net/balajinima/comments/298537.html</wfw:comment><comments>http://www.blogjava.net/balajinima/articles/298537.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/balajinima/comments/commentRss/298537.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/balajinima/services/trackbacks/298537.html</trackback:ping><description><![CDATA[<p align="left">第六部分：覆盖，重载，运行时期类型及其面向对象</p>
<ul type="disc">
    <li>知道面向对象设计中封装的好处以及如何实现，能知道is&nbsp;<wbr>a和has&nbsp;<wbr>a的意义。
    <li>能正确使用覆盖和重载的方法，能正确调用父类或重载的构造方法(constructor)，知道调用这些方法后的结果。
    <li>能正确实例化类或内部类 </li>
</ul>
<div>
<h3><a name="_Toc74451188">&#167;1.1.1&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 一</a></h3>
<p>3. What will happen when you attempt to compile and run the following code?</p>
<p>class MyParent</p>
<p>{</p>
<p>int x, y;</p>
<p>MyParent(int x, int y)</p>
<p>{</p>
<p>this.x = x;</p>
<p>this.y = y;</p>
<p>}</p>
<p>public int addMe(int x, int y)</p>
<p>{</p>
<p>return this.x + x + y + this.y;</p>
<p>}</p>
<p>public int addMe(MyParent myPar)</p>
<p>{</p>
<p>return addMe(myPar.x, myPar.y);</p>
<p>}</p>
<p>}</p>
<p>class MyChild extends MyParent</p>
<p>{</p>
<p>int z;</p>
<p>MyChild (int x, int y, int z)</p>
<p>{</p>
<p>super(x,y);</p>
<p>this.z = z;</p>
<p>}</p>
<p>public int addMe(int x, int y, int z)</p>
<p>{</p>
<p>return this.x + x + this.y + y + this.z + z;</p>
<p>}</p>
<p>public int addMe(MyChild myChi)</p>
<p>{</p>
<p>return addMe(myChi.x, myChi.y, myChi.z);</p>
<p>}</p>
<p>public int addMe(int x, int y)</p>
<p>{</p>
<p>return this.x + x + this.y + y;</p>
<p>}</p>
<p>}</p>
<p>public class MySomeOne</p>
<p>{</p>
<p>public static void main(String args[])</p>
<p>{</p>
<p>MyChild myChi = new MyChild(10, 20, 30);</p>
<p>MyParent myPar = new MyParent(10, 20);</p>
<p>int x = myChi.addMe(10, 20, 30);</p>
<p>int y = myChi.addMe(myChi);</p>
<p>int z = myPar.addMe(myPar);</p>
<p>System.out.println(x + y + z);</p>
<p>}</p>
<p>}</p>
<p>&nbsp;<wbr></p>
<p>Choices:</p>
<p>a. 300</p>
<p>b. 240</p>
<p>c. 120</p>
<p>d. 180</p>
<p>e. Compilation error</p>
<p>f. None of the above</p>
<p>――――――――――――</p>
<p>A is the correct choice. In the code, MyChild class overrides the addMe(int x, int y) method of the MyParent class. And in both the MyChild and MyParent class, addMe() method is overloaded. There is no compilation error anywhere in the above code. On execution, first, the object of MyChild class will be constructed. Please note that there is a super() call from the constructor of MyChild class, which will call the constructor of MyParent class. This will cause the value of z variable of MyChild class to be 30 and x, y variables of MyParent class will become 10 and 20 respectively. The next statement will again call the constructor of MyParent class with same x and y values. This is followed by execution of addMe() method of MyChild class with x as 10, y as 20 and z as 30. Also x and y are inherited by MyChild class from the MyParent class. Thus in the addMe() method of the MyChild class, the value of this.x will be 10, this.y will be 20 and this.z will be 30. The return value of this method will be "10 + 10 + 20 + 20 + 30 + 30", which is equal to 120. Thus x will become 120. This is followed by the invocation of the other addMe() method which takes object reference of the MyChild class. From this method, the method which was called earlier is invoked. This call is exactly the same as the earlier one. Thus the value of y will also be 120 like x. Now the addMe() method of MyParent class is invoked. This method invokes another addMe() method of the same class. Its equivalent to the invocation of addMe(int x, int y) method with x as 10 and y as 20. Also the value of instance variables x and y of My Parent class is 10 and 20 respectively. The value of z will be evaluated to "10 + 10 + 20 + 20", which is equal to 60. Thus the value of x, y and z after all the invocations will be 120, 120 and 60 respectively. As a result of this finally, "120 + 120 + 60" which is equal to 300 will be printed. Thus A is the correct choice.</p>
<p align="left">&nbsp;<wbr></p>
<h3><a name="_Toc74451189">&#167;1.1.2&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 二</a></h3>
<p>Given the code below, and making no other changes, which access modifiers</p>
<p>(public, protected or private) can legally be placed before myMethod() on line 3?</p>
<p>If line 3 is left as it is, which keywords can legally be placed before myMethod</p>
<p>on line 8?</p>
<p>1.class HumptyDumpty</p>
<p>2.{</p>
<p>3.void myMethod() {}</p>
<p>4.}</p>
<p>5.</p>
<p>6.class HankyPanky extends HumptyDumpty</p>
<p>7.{</p>
<p>8.void myMethod() {}</p>
<p>9.}</p>
<div>
<p>Choices:</p>
<p>a. private or nothing(i.e. leaving it as it is) on line 3.</p>
<p>Nothing(i.e. leaving it as it is) or protected or public</p>
<p>on line 8.</p>
<p>b. public or protected on line 3. private or nothing(i.e. leaving it</p>
<p>as it is) on line 8.</p>
<p>c. nothing(i.e. leaving it as it is) or protected or public on</p>
<p>line 3. private or nothing(i.e. leaving it as it is) on line 8.</p>
<p>d. None of the above.</p>
</div>
<p>A is correct. The basic principle is that a method cannot be overridden to be more private. Since the method is being overridden to be friendly(default modifier) it can only be private or friendly in the superclass. Secondly if the method in superclass is left as it is(i.e. friendly access) the method in subclass can be friendly, protected or public.</p>
<h3><a name="_Toc74451190">&#167;1.1.3&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 三</a></h3>
<p>What results from the following code?</p>
<p>1.class MyClass</p>
<p>2.{</p>
<p>3.void myMethod(int i) {System.out.println("int version");}</p>
<p>4.void myMethod(String s) {System.out.println("String version");}</p>
<p>5.public static void main(String args[])</p>
<p>6.{</p>
<p>7.MyClass obj = new MyClass();</p>
<p>8.char ch = 'c';</p>
<p>9.obj.myMethod(ch);</p>
<p>10.}</p>
<p>11.}</p>
<p>Choices:</p>
<p>a. Line 4 will not compile as void methods can't be overridden.</p>
<p>b. An exception at line 9.</p>
<p>c. Line 9 will not compile as there is no version of myMethod which takes a char as argument.</p>
<p>d. The code compiles and produces output: int version.</p>
<p>e. The code compiles and produces output: String version.</p>
<p>――――――――――</p>
<p>D is correct. A is incorrect as void methods can be overridden without any problem. B is incorrect as char ch declaration is valid. C is incorrect as char type in java is internally stored as integer and there is a method which takes int as an input. D is correct, on line 9 char ch is widened to an int and passed to int version of the myMethod(). E is incorrect as int version of myMethod() is called.</p>
<h3><a name="_Toc74451191">&#167;1.1.4&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 四</a></h3>
<p>What is displayed when the following is executed?</p>
<p>class Parent</p>
<p>{</p>
<p>private void method1()</p>
<p>{</p>
<p>System.out.println("Parent's method1()");</p>
<p>}</p>
<p>public void method2()</p>
<p>{</p>
<p>System.out.println("Parent's method2()");</p>
<p>method1();</p>
<p>}</p>
<p>}</p>
<p>class Child extends Parent</p>
<p>{</p>
<p>public void method1()</p>
<p>{</p>
<p>System.out.println("Child's method1()");</p>
<p>}</p>
<p>public static void main(String args[])</p>
<p>{</p>
<p>Parent p = new Child();</p>
<p>p.method2();</p>
<p>}</p>
<p>}</p>
<p>Choices:</p>
<p>a. Compile time error</p>
<p>b. Run time error</p>
<p>c. prints : Parent's method2()</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> Parent's method1()</p>
<p>d. prints : Parent's method2()</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> Child's method1()</p>
<p align="left">―――――――</p>
<p>C is correct. The code will compile without any error and also will not give any run time error. The variable p refers to the Child class object. The statement p.method2() on execution will first look for method2() in Child class. Since there is no method2() in child class, the method2() of Parent class will be invoked and thus "Parent's method2()" will be printed. Now from the method2() , there is a call to method1(). Please note that method1() of Parent class is private, because of which the same method (method1() of Parent class) will be invoked. Had this method(method1() of Parent class) been public/protected/friendly (default), Child's class method1() would be called. Thus C is correct answer.</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451192">&#167;1.1.5&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 五</a></h3>
<p>What is displayed when the following is executed?</p>
<p>class Parent{</p>
<p>private void method1(){</p>
<p>System.out.println("Parent's method1()");</p>
<p>}</p>
<p>public void method2(){</p>
<p>System.out.println("Parent's method2()");</p>
<p>method1();</p>
<p>}</p>
<p>}</p>
<p>class Child extends Parent{</p>
<p>public void method1(){</p>
<p>System.out.println("Child's method1()");</p>
<p>}</p>
<p>public static void main(String args[]){</p>
<p>Parent p = new Child();</p>
<p>p.method2();</p>
<p>}</p>
<p>}</p>
<p>&nbsp;<wbr></p>
<p>A. compile time error</p>
<p>B. run time error</p>
<p>C. prints: parent&#8217;s method2()&nbsp;<wbr> parent&#8217;s method1()</p>
<p>D. prints: parent&#8217;s method2()&nbsp;<wbr> child&#8217;s method1()</p>
<p>&nbsp;<wbr></p>
<p>C is correct. The code will compile without any error and also will not give any run time error. The variable p refers to the Child class object. The statement p.method2() on execution will first look for method2() in Child class. Since there is no method2() in child class, the method2() of Parent class will be invoked and thus "Parent's method2()" will be printed. Now from the method2() , there is a call to method1(). Please note that method1() of Parent class is private, because of which the same method (method1() of Parent class) will be invoked. Had this method(method1() of Parent class) been public/protected/friendly (default), Child's class method1() would be called. Thus C is correct answer.</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451193">&#167;1.1.6&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 六</a></h3>
<p>　　1) class Person {</p>
<p>&nbsp;<wbr></p>
<p>　　2) public void printValue(int i, int j) { }</p>
<p>&nbsp;<wbr></p>
<p>　　3) public void printValue(int i){ }</p>
<p>&nbsp;<wbr></p>
<p>　　4) }</p>
<p>&nbsp;<wbr></p>
<p>　　5) public class Teacher extends Person {</p>
<p>&nbsp;<wbr></p>
<p>　　6) public void printValue() { }</p>
<p>&nbsp;<wbr></p>
<p>　　7) public void printValue(int i) {}</p>
<p>&nbsp;<wbr></p>
<p>　　8) public static void main(String args[]){</p>
<p>&nbsp;<wbr></p>
<p>　　9) Person t = new Teacher();</p>
<p>&nbsp;<wbr></p>
<p>　　10) t.printValue(10);</p>
<p>&nbsp;<wbr></p>
<p>　　11) }</p>
<p>&nbsp;<wbr></p>
<p>　　12) }</p>
<p>&nbsp;<wbr></p>
<p>　　Which method will the statement on line 10 call?</p>
<p>　　A. on line 2</p>
<p>&nbsp;<wbr></p>
<p>　　B. on line 3</p>
<p>&nbsp;<wbr></p>
<p>　　C. on line 6</p>
<p>&nbsp;<wbr></p>
<p>　　D. on line 7</p>
<p>　　翻译</p>
<p>　　第十行的声明将调用哪些方法。</p>
<p>&nbsp;<wbr></p>
<p>　　答案　D</p>
<p>&nbsp;<wbr></p>
<p>　　解析　变量t是一个Person对象，但是它是用Teacher实例化的，这个问题涉及到java的</p>
<p>编译时多态和运行时多态的问题，就编译时多态来说，t实际上是一个Person类，这涉及到类</p>
<p>型的自动转换（将一个子类的实例赋值给一个父类的变量是不用进行强制类型转换，反之则需</p>
<p>要进行强制类型转换，而且被赋值的变量实际上应该是一个子类的对象），如果对t调用了子</p>
<p>类中新增的方法则造成编译时错误编译将不能通过，而在运行时，运行时系统将根据t实际指</p>
<p>向的类型调用对应的方法，对于本例来说，t.print(10)将调用t实际指向的Teacher类的对应</p>
<p>方法。在java中，可以用一个子类的实例实例化父类的一个变量，而变量在编译时是一个父类</p>
<p>实例，在运行时可能是一个子类实例。</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451194">&#167;1.1.7&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 七</a></h3>
<p>35、public class Parent {</p>
<p>　　public int addValue( int a, int b) {</p>
<p>　　int s;</p>
<p>　　s = a+b;</p>
<p>　　return s;</p>
<p>　　}</p>
<p>　　}</p>
<p>　　class Child extends Parent {</p>
<p>&nbsp;<wbr></p>
<p>　　}</p>
<p>　　Which methods can be added into class Child?</p>
<p>　　A. int addValue( int a, int b ){// do something...}</p>
<p>&nbsp;<wbr></p>
<p>　　B. public void addValue (){// do something...}</p>
<p>&nbsp;<wbr></p>
<p>　　C. public int addValue( int a ){// do something...}</p>
<p>&nbsp;<wbr></p>
<p>　　D. public int addValue( int a, int b )throws MyException {//do</p>
<p>something...}</p>
<p>&nbsp;<wbr></p>
<p>　　(bc)</p>
<p>&nbsp;<wbr></p>
<p>　　题目：哪些方法可以加入类Child中。</p>
<p>&nbsp;<wbr></p>
<p>　　此题涉及方法重载（overload），方法重写（override）以及类派生时方法重写的规则</p>
<p>。方法重载的规则是：一、参数列表必须不同，个数的不同完全可以，如果个数相同则参数类</p>
<p>型的不同不能引起歧意，例如int</p>
<p>和long,float和double就不能作为唯一的类型不同；二、返回值可以不同，但是不能是重载</p>
<p>时唯一的不同点（这点和c++中不同，c++中返回类型必须一致）。方法重写发生在类继承时，</p>
<p>子类可以重写一个父类中已有的方法，必须在返回类型和参数列表一样时才能说是重写，否则</p>
<p>就是重载，java中方法重写的一个重要而且容易被忽略的规则是重写的方法的访问权限不能比</p>
<p>被重写的方法的访问权限低！重写的另一个规则是重写的方法不能比被重写的方法抛弃(thro</p>
<p>ws)更多种类的异常，其抛弃的异常只能少，或者是其子类，不能以抛弃异常的个数来判断种</p>
<p>类，而应该是异常类层次结果上的种类。此题中答案a的错误就是重写的访问权限比被重写的</p>
<p>方法的低，而b,c都属于重载，d的错误在于比被重写的方法抛弃了更多种类的异常。</p>
</div>
<img src ="http://www.blogjava.net/balajinima/aggbug/298537.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/balajinima/" target="_blank">李云泽</a> 2009-10-16 11:42 <a href="http://www.blogjava.net/balajinima/articles/298537.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第五部分：操作与赋值</title><link>http://www.blogjava.net/balajinima/articles/298536.html</link><dc:creator>李云泽</dc:creator><author>李云泽</author><pubDate>Fri, 16 Oct 2009 03:41:00 GMT</pubDate><guid>http://www.blogjava.net/balajinima/articles/298536.html</guid><wfw:comment>http://www.blogjava.net/balajinima/comments/298536.html</wfw:comment><comments>http://www.blogjava.net/balajinima/articles/298536.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/balajinima/comments/commentRss/298536.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/balajinima/services/trackbacks/298536.html</trackback:ping><description><![CDATA[<p align="left">第五部分：操作与赋值</p>
<ul type="disc">
    <li>能知道各种操作符（包括赋值操作符和intanceof操作符）应用于不同类型的结果。
    <li>知道String，Boolean和类使用equals()方法后的结果。
    <li>知道当对已经知道值的变量进行&amp;,|,&amp;&amp;,||操作时，哪些操作数被运算了，表达式最终的结果是怎样的。
    <li>知道对象和原始类型数据传入方法后，在方法内部进行赋值或其它修改操作的结果。 </li>
</ul>
<div>
<h3>&#167;1.1.1&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 一</h3>
<p>Which of the following lines will print false?</p>
<p>1.public class MyClass</p>
<p>2.{</p>
<p>3.static String s1 = "I am unique!";</p>
<p>4.public static void main(String args[])</p>
<p>5.{</p>
<p>6.String s2 = "I am unique!";</p>
<p>7.String s3 = new String(s1);</p>
<p>8.System.out.println(s1 == s2);</p>
<p>9.System.out.println(s1.equals(s2));</p>
<p>10.System.out.println(s3 == s1);</p>
<p>11.System.out.println(s3.equals(s1));</p>
<p>12.System.out.println(TestClass.s4 == s1);</p>
<p>13.}</p>
<p>14.}</p>
<p>15.</p>
<p>16.class TestClass</p>
<p>17.{</p>
<p>18.static String s4 = "I am unique!";</p>
<p>19.}</p>
<p>Choices:</p>
<p>a. Lines 10 and 12</p>
<p>b. Line 12 only</p>
<p>c. Line 8 and 10</p>
<p>d. None of these</p>
<p align="left">――――――――――</p>
<p align="left">D is correct. Only line 10 will print false. Strings are immutable objects. That is, a string is read only once the string has been created and initialized, and Java optimizes handling of string literals; only one anonymous string object is shared by all string literals with the same contents. Hence in the above code the strings s1, s2 and s4 refer to the same anonymous string object, initialized with the character string: "I am unique!". Thus s1 == s2 and TestClass.s4 will both return true and obviously s1.equals(s2) will return true. But creating string objects using the constructor String(String s) creates a new string, hence s3 == s1 will return false even though s3.equals(s1) will return true because s1 and s3 are referring to two different string objects whose contents are same.</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451179">&#167;1.1.2&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 二</a></h3>
<p>What is displayed when the following code is compiled and executed?</p>
<p>String s1 = new String("Test");</p>
<p>String s2 = new String("Test");</p>
<p>if (s1==s2)</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>System.out.println("Same");</p>
<p>if (s1.equals(s2))</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>System.out.println("Equals");</p>
<p>Choices:</p>
<p>a. Same</p>
<p>Equals</p>
<p>b. Equals</p>
<p>c. Same</p>
<p>d. The code compiles, but nothing is displayed upon execution.</p>
<p>e. The code fails to compile.</p>
<div>
<p align="left">&nbsp;<wbr></p>
</div>
<p align="left">B is correct. Here s1 and s2 are two different object references, referring to different objects in memory. Please note that operator == checks for the memory address of two object references being compared and not their value. The "equals()" method of String class compares the values of two Strings. Thus s1==s2 will return "false" while s1.equals(s2) will return "true". Thus only "Equals" will be printed.</p>
<h3>&#167;1.1.3&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 三</h3>
<p>Given the following code, what will be the output?</p>
<p>class Value</p>
<p>{</p>
<p>public int i = 15;</p>
<p>}</p>
<p>public class Test</p>
<p>{</p>
<p>public static void main(String argv[])</p>
<p>{</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> Test t = new Test();</p>
<p>t.first();</p>
<p>&nbsp;<wbr> &nbsp;<wbr>}</p>
<p>public void first()</p>
<p>{</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> int i = 5;</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> Value v = new Value();</p>
<p>v.i = 25;</p>
<p>second(v, i);</p>
<p>&nbsp;<wbr> &nbsp;<wbr> System.out.println(v.i);</p>
<p>}</p>
<p>public void second(Value v, int i)</p>
<p>{</p>
<p>i = 0;</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> v.i = 20;</p>
<p>Value val = new Value();</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> v = &nbsp;<wbr>val;</p>
<p>&nbsp;<wbr> &nbsp;<wbr> System.out.println(v.i + " " + i);</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr></p>
<p>}</p>
<p>}</p>
<p>Choices:</p>
<p>a. 15 0</p>
<p>&nbsp;<wbr> &nbsp;<wbr>20</p>
<p>b. 15 0</p>
<p>&nbsp;<wbr> &nbsp;<wbr>15</p>
<p>c. 20 0</p>
<p>&nbsp;<wbr> 20</p>
<p>d. 0 15</p>
<p>&nbsp;<wbr> 20</p>
<p align="left">―――――――――――――――</p>
<p align="left">A is correct. When we pass references in Java what actually gets passed is the value of that reference (i.e. memory address of the object being referenced and not the actual object referenced by that reference) and it gets passed as value (i.e a copy of the reference is made). Now when we make changes to the object referenced by that reference it reflects on that object even outside of the method being called but any changes made to the reference itself is not reflected on that reference outside of the method which is called. In the example above when the reference v is passed from method first() to second() the value of v is passed. When we assign the value val to v it is valid only inside the method second() and thus inside the method second() what gets printed is 15 (initial value of i in the object referenced by val), then a blank space and then 0 (value of local variable i). After this when we return to the method first() v actually refers to the same object to which it was referring before the method second() was called, but one thing should be noted here that the value of i in that object (referred by v inside the method first()) was changed to 20 in the method second() and this change does reflect even outside the method second(), hence 20 gets printed in the method first(). Thus overall output of the code in consideration is 15 0 20</p>
<p>&nbsp;<wbr></p>
<h3>&#167;1.1.4&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 四</h3>
<p>&nbsp;<wbr>What will happen when you attempt to compile and run the following code?</p>
<p>interface MyInterface</p>
<p>{</p>
<p>}</p>
<p>public class MyInstanceTest implements MyInterface</p>
<p>{</p>
<p>static String s;</p>
<p>public static void main(String args[])</p>
<p>{</p>
<p>MyInstanceTest t = new MyInstanceTest();</p>
<p>if(t instanceof MyInterface)</p>
<p>{</p>
<p>System.out.println("I am true interface");</p>
<p>}</p>
<p>else</p>
<p>{</p>
<p>System.out.println("I am false interface");</p>
<p>}</p>
<p>if(s instanceof String)</p>
<p>{</p>
<p>System.out.println("I am true String");</p>
<p>}</p>
<p>else</p>
<p>{</p>
<p>System.out.println("I am false String");</p>
<p>}</p>
<p>}</p>
<p>}</p>
<p>Choices:</p>
<p>a. Compiletime error</p>
<p>b. Runtime error</p>
<p>c. Prints : "I am true interface" followed by " I am true String"</p>
<p>d. Prints : "I am false interface" followed by " I am false String"</p>
<p>e. Prints : "I am true interface" followed by " I am false String"</p>
<p>f. Prints : "I am false interface" followed by " I am true String"</p>
<p>――――――――――――</p>
<p>E is the correct choice. The "instanceof" operator tests the class of an object at runtime. It returns true if the class of the left-hand argument is the same as, or is some subclass of, the class specified by the right-hand operand. The right-hand operand may equally well be an interface. In such a case, the test determines if the object at left-hand argument implements the specified interface. In the above case there will not be any compiletime or runtime error. The result of "t instance of MyInterface" will be true as "t" is the object of MyInstanceTest class which implements the MyInstance interface. But the result of "s instanceof String" will be false as "s" refers to null. Thus the output of the above program will be : "I am true interface" followed by " I am false String". Thus choice E is correct and others are incorrect.</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<h3>&#167;1.1.5&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>五</h3>
<p>What will happen when you attempt to compile and run the following code snippet?</p>
<p>String str = "Java";</p>
<p>StringBuffer buffer = new StringBuffer(str);</p>
<p>if(str.equals(buffer)){</p>
<p>System.out.println("Both are equal");</p>
<p>}else{</p>
<p>System.out.println("Both are not equal");</p>
<p>}</p>
<p>A. it will print &#8211; both are not equal</p>
<p>B. it will print &#8211; both are equal</p>
<p>C. compile time error</p>
<p>D. Runtime error</p>
<p>&nbsp;<wbr></p>
<p>A is the correct choice. The equals method overridden in String class returns true if and only if the argument is not null and is a String object that represents the same sequence of characters as this String object. Hence, though the contents of both str and buffer contain "Java", the str.equals(buffer) call results in false.</p>
<p>The equals method of Object class is of form -public boolean equals(Object anObject). Hence, comparing objects of different classes will never result in compile time or runtime error.</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451183">&#167;1.1.6&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 六</a></h3>
<p>10. Which of the following statements are true?</p>
<p>　　A. The equals() method determines if reference values refer to the same</p>
<p>object.</p>
<p>&nbsp;<wbr></p>
<p>　　B. The == operator determines if the contents and type of two separate</p>
<p>objects match.</p>
<p>&nbsp;<wbr></p>
<p>　　C. The equals() method returns true only when the contents of two</p>
<p>objects match.</p>
<p>&nbsp;<wbr></p>
<p>　　D. The class File overrides equals() to return true if the contents and</p>
<p>type of two separate objects match.</p>
<p>　　翻译</p>
<p>　　下面的哪些叙述为真。</p>
<p>　　A. equals()方法判定引用值是否指向同一对象。</p>
<p>&nbsp;<wbr></p>
<p>　　B. == 操作符判定两个分立的对象的内容和类型是否一致。</p>
<p>&nbsp;<wbr></p>
<p>　　C. equals()方法只有在两个对象的内容一致时返回true。</p>
<p>&nbsp;<wbr></p>
<p>　　D. 类File重写方法equals()在两个分立的对象的内容和类型一致时返回true。</p>
<p>&nbsp;<wbr></p>
<p>　　答案　A,D</p>
<p>　</p>
<p>　　解析　严格来说这个问题的答案是不确定的，因为equals()方法是可以被重载的，但是</p>
<p>按照java语言的本意来说：如果没有重写（override）新类的equals()，则该方法和</p>
<p>==</p>
<p>操作符一样在两个变量指向同一对象时返回真，但是java推荐的是使用equals()方法来判断</p>
<p>两个对象的内容是否一样，就像String类的equals()方法所做的那样：判定两个String对象的</p>
<p>内容是否相同，而==操作符返回true的唯一条件是两个变量指向同一对象。从这个意义上来说</p>
<p>选择给定的答案。从更严格的意义来说正确答案应该只有d。</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451184">&#167;1.1.7&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 七</a></h3>
<p>Use the operators "&lt;&lt;", "&gt;&gt;", which statements are true?</p>
<p>　　A. 0000 0100 0000 0000 0000 0000 0000 0000&lt;&lt;5 gives</p>
<p>&nbsp;<wbr>&nbsp;<wbr> 　　1000 0000 0000 0000 0000 0000 0000 0000</p>
<p>&nbsp;<wbr></p>
<p>　　B. 0000 0100 0000 0000 0000 0000 0000 0000&lt;&lt;5 gives</p>
<p>&nbsp;<wbr>&nbsp;<wbr> 　　1111 1100 0000 0000 0000 0000 0000 0000</p>
<p>&nbsp;<wbr></p>
<p>　　C. 1100 0000 0000 0000 0000 0000 0000 0000&gt;&gt;5 gives</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 　1111 1110 0000 0000 0000 0000 0000 0000</p>
<p>&nbsp;<wbr></p>
<p>　　D. 1100 0000 0000 0000 0000 0000 0000 0000&gt;&gt;5 gives</p>
<p>&nbsp;<wbr>&nbsp;<wbr> 　　0000 0110 0000 0000 0000 0000 0000 0000</p>
<p>　　翻译</p>
<p>　　使用"&lt;&lt;"和 "&gt;&gt;"操作符的哪些陈述是对的。</p>
<p>&nbsp;<wbr></p>
<p>　　答案　A,C</p>
<p>　　</p>
<p>　　解析　Java的移位操作符一共有三种，分别是&#8221;&gt;&gt;&#8221;,&#8221;&gt;&gt;&gt;&#8221;,&#8221;&lt;&lt;&#8221;,执行的操作分别</p>
<p>是有符号右移，无符号右移，左移，有符号右移的意思是说移入的最高位和原最高符号位相同</p>
<p>，无符号右移是移入位始终补零，左移时最低位始终补零，最高位被舍弃。移位操作符另一个</p>
<p>非常值得注意的特点是其右操作数是取模运算的，意思是说对于一个int型数据而言，对它移</p>
<p>位32位的结果是保持不变而非变成零，即：a&gt;&gt;32的结果是a而不是0，同理，对long型数是对</p>
<p>右操作数取64的模，a&gt;&gt;64==a；还有一点需要注意的是移位操作符&#8221;&gt;&gt;&gt;&#8221;只对int型和long型</p>
<p>有效，对byte或者short的操作将导致自动类型转换，而且是带符号的。</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451185">&#167;1.1.8&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 八</a></h3>
<p>　　String s= "hello";</p>
<p>　　String t = "hello";</p>
<p>　　char c[] = {'h','e','l','l','o'} ;</p>
<p>　　Which return true?</p>
<p>　　A. s.equals(t);</p>
<p>&nbsp;<wbr></p>
<p>　　B. t.equals(c);</p>
<p>&nbsp;<wbr></p>
<p>　　C. s==t;</p>
<p>&nbsp;<wbr></p>
<p>　　D. t.equals(new String("hello"));</p>
<p>&nbsp;<wbr></p>
<p>　　E. t==c.</p>
<p>&nbsp;<wbr></p>
<p>　　(acd)</p>
<p>&nbsp;<wbr></p>
<p>　　题目：哪些返回true。</p>
<p>&nbsp;<wbr></p>
<p>　　这个在前面第10题的equals()方法和==操作符的讨论中论述过。==操作符比较的是操作</p>
<p>符两端的操作数是否是同一个对象，而String的equals()方法比较的是两个String对象的内容</p>
<p>是否一样，其参数是一个String对象时才有可能返回true，其它对象都返回假。需要指出的是</p>
<p>由于s和t并非使用new创建的，他们指向内存池中的同一个字符串常量，因此其地址实际上是</p>
<p>相同的（这个可以从反编译一个简单的测试程序的结果得到，限于篇幅不列出测试代码和反编</p>
<p>译的分析），因此答案c也是正确的。</p>
<h3><a name="_Toc74451186">&#167;1.1.9&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 九</a></h3>
<p>Class Teacher and Student are subclass of class Person.</p>
<p>　　Person p;</p>
<p>　　Teacher t;</p>
<p>　　Student s;</p>
<p>　　p, t and s are all non-null.</p>
<p>　　if(t instanceof Person) { s = (Student)t; }</p>
<p>　　What is the result of this sentence?</p>
<p>　　A. It will construct a Student object.</p>
<p>&nbsp;<wbr></p>
<p>　　B. The expression_r is legal.</p>
<p>&nbsp;<wbr></p>
<p>　　C. It is illegal at compilation.</p>
<p>&nbsp;<wbr></p>
<p>　　D. It is legal at compilation but possible illegal at runtime.</p>
<p>&nbsp;<wbr></p>
<p>　　(c)</p>
<p>&nbsp;<wbr></p>
<p>　　题目：类Teacher和Student都是类Person的子类</p>
<p>　　&#8230;</p>
<p>　　p,t和s都是非空值</p>
<p>　　&#8230;</p>
<p>　　这个语句导致的结果是什么</p>
<p>&nbsp;<wbr></p>
<p>　　A. 将构造一个Student对象。</p>
<p>&nbsp;<wbr></p>
<p>　　B. 表达式合法。</p>
<p>&nbsp;<wbr></p>
<p>　　C. 编译时非法。</p>
<p>&nbsp;<wbr></p>
<p>　　D. 编译时合法而在运行时可能非法。</p>
<p>&nbsp;<wbr></p>
<p>　　instanceof操作符的作用是判断一个变量是否是右操作数指出的类的一个对象，由于ja</p>
<p>va语言的多态性使得可以用一个子类的实例赋值给一个父类的变量，而在一些情况下需要判断</p>
<p>变量到底是一个什么类型的对象，这时就可以使用instanceof了。当左操作数是右操作数指出</p>
<p>的类的实例或者是子类的实例时都返回真，如果是将一个子类的实例赋值给一个父类的变量，</p>
<p>用instanceof判断该变量是否是子类的一个实例时也将返回真。此题中的if语句的判断没有问</p>
<p>题，而且将返回真，但是后面的类型转换是非法的，因为t是一个Teacher对象，它不能被强制</p>
<p>转换为一个Student对象，即使这两个类有共同的父类。如果是将t转换为一个Person对象则可</p>
<p>以，而且不需要强制转换。这个错误在编译时就可以发现，因此编译不能通过。</p>
<p>&nbsp;<wbr></p>
</div>
<img src ="http://www.blogjava.net/balajinima/aggbug/298536.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/balajinima/" target="_blank">李云泽</a> 2009-10-16 11:41 <a href="http://www.blogjava.net/balajinima/articles/298536.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第四部分：语言基础</title><link>http://www.blogjava.net/balajinima/articles/298535.html</link><dc:creator>李云泽</dc:creator><author>李云泽</author><pubDate>Fri, 16 Oct 2009 03:40:00 GMT</pubDate><guid>http://www.blogjava.net/balajinima/articles/298535.html</guid><wfw:comment>http://www.blogjava.net/balajinima/comments/298535.html</wfw:comment><comments>http://www.blogjava.net/balajinima/articles/298535.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/balajinima/comments/commentRss/298535.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/balajinima/services/trackbacks/298535.html</trackback:ping><description><![CDATA[<p align="left">第四部分：语言基础</p>
<ul type="disc">
    <li>能正确声明包、import、类（包括内部类）、接口、方法（包括用于开始一个类的执行的main方法）、变量，并正确使用修饰符。
    <li>能够正确使用实现了接口的类，包括java.lang.Runnable接口或题目中指定的接口。
    <li>知道命令行参数是如何传递给类的main方法的。
    <li>知道哪些是JAVA的合法keyword。注意：考试中不会出现要你解释keyword和各种常数这种深奥的问题。
    <li>明白如果没有显式地赋值，各种变量或者数组的默认值是什么。
    <li>掌握所有原始数据类型的取值范围，如何声明各种数据类型。 </li>
</ul>
<div>
<h3><a name="_Toc74451167">&#167;1.1.1&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 一</a></h3>
<p>1. What will happen when you attempt to compile and run the following code?</p>
<p>public class Static</p>
<p>{</p>
<p>static</p>
<p>{</p>
<p>int x = 5;</p>
<p>}</p>
<p>static int x,y;</p>
<p>public static void main(String args[])</p>
<p>{</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>x--;</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>myMethod();</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>System.out.println(x + y + ++x);</p>
<p>}</p>
<p>public static void myMethod()</p>
<p>{</p>
<p>y = x++ + ++x;</p>
<p>}</p>
<p>}</p>
<p>Choices:</p>
<p>a. Compiletime error</p>
<p>b. prints : 1</p>
<p>c. prints : 2</p>
<p>d. prints : 3</p>
<p>e. prints : 7</p>
<p>f. prints : 8</p>
<p>――――――――――――――――――――</p>
<p>1) D is the correct choice. The above code will not give any compilation error. Note that "Static" is a valid class name. Thus choice A is incorrect. In the above code, on execution, first the static variables (x and y) will be initialized to 0. Then static block will be called and finally main() method will be called. The execution of static block will have no effect on the output as it declares a new variable (int x). The first statement inside main (x--) will result in x to be -1. After that myMethod() will be executed. The statement "y = x++ + ++x;" will be evaluated to y = -1 + 1 and x will become 1. In case the statement be "y =++x + ++x", it would be evaluated to y = 0 + 1 and x would become 1. Finally when System.out is executed "x + y + ++x" will be evaluated to "1 + 0 + 2" which result in 3 as the output. Thus choice D is correct.</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451168">&#167;1.1.2&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 二</a></h3>
<p>Considering the following code, Which variables may be referenced correctly at line 12?</p>
<p>1.public class Outer</p>
<p>2.{</p>
<p>3.public int a = 1;</p>
<p>4.private int b = 2;</p>
<p>5.public void method(final int c)</p>
<p>6.{</p>
<p>7.int d = 3;</p>
<p>8.class Inner</p>
<p>9.{</p>
<p>10.private void iMethod(int e)</p>
<p>11. {</p>
<p>12.</p>
<p>13.}</p>
<p>14.}</p>
<p>15.}</p>
<p>16.}</p>
<p>Choices:</p>
<p>a. a</p>
<p>b. b</p>
<p>c. c</p>
<p>d. d</p>
<p>e. e</p>
<p>A, B, C and E are correct. Since Inner is not a static inner class, it has a reference to an enclosing object, and all the variables of that object are accessible. Therefore A and B are correct, even if b is private. Variables in the enclosing method are only accessible when they are marked as final hence c is accessible but not d. E is obviously correct as it is a parameter to the method containing line 12 itself.</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451169">&#167;1.1.3&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 三</a></h3>
<p>What will be the result of executing the following code?</p>
<p>// Filename; SuperclassX.java</p>
<p>package packageX;</p>
<p>public class SuperclassX</p>
<p>{</p>
<p>protected void superclassMethodX()</p>
<p>{</p>
<p>}</p>
<p>int superclassVarX;</p>
<p>}</p>
<p>&nbsp;<wbr></p>
<p>// Filename SubclassY.java</p>
<p>1.package packageX.packageY;</p>
<p>2.</p>
<p>3.public class SubclassY extends SuperclassX</p>
<p>4.{</p>
<p>5.SuperclassX objX = new SubclassY();</p>
<p>6.SubclassY objY = new SubclassY();</p>
<p>7.void subclassMethodY()</p>
<p>8.{</p>
<p>9.objY.superclassMethodX();</p>
<p>10.int i;</p>
<p>11.i = objY.superclassVarX;</p>
<p>12.}</p>
<p>13.}</p>
<p>Choices:</p>
<p>a.Compilation error at line 5</p>
<p>b. Compilation error at line 9</p>
<p>c. Runtime exception at line 11</p>
<p>d. None of these</p>
<p>――――――――</p>
<p>D is correct. When no access modifier is specified for a member, it is only accessible by another class in the package where its class is defined. Even if its class is visible in another package, the member is not accessible there. In the question above the variable superclassVarX has no access modifier specified and hence it cannot be accessed in the packageY even though the class SuperclassX is visible and the protected method superclassMethodX() can be accessed. Thus the compiler will raise an error at line 11.</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451170">&#167;1.1.4&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 四</a></h3>
<p>&nbsp;<wbr>Consider the class hierarchy shown below:</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>--------------------------------------------------------------------</p>
<p>class FourWheeler implements DrivingUtilities</p>
<p>class Car extends FourWheeler</p>
<p>class Truck extends FourWheeler</p>
<p>class Bus extends FourWheeler</p>
<p>class Crane extends FourWheeler</p>
<p>----------------------------------------------------------------------</p>
<p>&nbsp;<wbr> &nbsp;<wbr></p>
<p>Consider the following code below:</p>
<p>1.DrivingUtilities du;</p>
<p>2.FourWheeler fw;</p>
<p>3.Truck myTruck = new Truck();</p>
<p>4.du = (DrivingUtilities)myTruck;</p>
<p>5.fw = new Crane();</p>
<p>6.fw = du;</p>
<p>Which of the statements below are true?</p>
<p>Choices:</p>
<p>a. Line 4 will not compile because an interface cannot refer to an object.</p>
<p>b. The code will compile and run.</p>
<p>c. The code will not compile without an explicit cast at line 6, because going</p>
<p>down the hierarchy without casting is not allowed.</p>
<p>d.The code at line 4 will compile even without the explicit cast.</p>
<p>e.The code will compile if we put an explicit cast at line 6 but will throw an exception at runtime.</p>
<p>―――――――――――</p>
<p>C and D are correct. A and B are obviously wrong because there is nothing wrong in an interface referring to an object. C is correct because an explicit cast is needed to go down the hierarchy. D is correct because no explicit cast is needed at line 4, because we are going up the hierarchy. E is incorrect because if we put an explicit cast at line 6, the code will compile and run perfectly fine, no exception will be thrown because the runtime class of du (that is Truck) can be converted to type FourWheeler without any problem.</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451171">&#167;1.1.5&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 五</a></h3>
<p>What will be printed when you execute the following code?</p>
<p>class X</p>
<p>{</p>
<p>Y b = new Y();</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>X()</p>
<p>{</p>
<p>System.out.print("X");</p>
<p>}</p>
<p>}</p>
<p>class Y</p>
<p>{</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>Y()</p>
<p>{</p>
<p>System.out.print("Y");</p>
<p>}</p>
<p>}</p>
<p>public class Z extends X</p>
<p>{</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>Y y = new Y();</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>Z()</p>
<p>{</p>
<p>System.out.print("Z");</p>
<p>}</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>public static void main(String[] args)</p>
<p>{</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>new Z();</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>}</p>
<p>}</p>
<p>Choices:</p>
<p>a. Z</p>
<p>b. YZ</p>
<p>c. XYZ</p>
<p>d. YXYZ</p>
<p>―――――――――</p>
<p align="left">D is correct. A difficult but a fundamental question, please observe carefully. Before any object is constructed the object of the parent class is constructed(as there is a default call to the parent's constructor from the constructor of the child class via the super() statement). Also note that when an object is constructed the variables are initialized first and then the constructor is executed. So when new Z() is executed , the object of class X will be constructed, which means Y b = new Y() will be executed and "Y" will be printed as a result. After that constructor of X will be called which implies "X" will be printed. Now the object of Z will be constructed and thus Y y = new Y() will be executed and Y will be printed and finally the constructor Z() will be called and thus "Z" will be printed. Thus YXYZ will be printed.</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451172">&#167;1.1.6&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 六</a></h3>
<p>What will happen when you attempt to compile and run the following code?</p>
<p>class Base</p>
<p>{</p>
<p>int i = 99;</p>
<p>public void amethod()</p>
<p>{</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>System.out.println("Base.amethod()");</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>}</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>Base()</p>
<p>{</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>amethod();</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>}</p>
<p>}</p>
<p>public class Derived extends Base</p>
<p>{</p>
<p>int i = -1;</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr></p>
<p>public static void main(String argv[])</p>
<p>{</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>Base b = new Derived();</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>System.out.println(b.i);</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>b.amethod();</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>}</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>public void amethod()</p>
<p>{</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>System.out.println("Derived.amethod()");</p>
<p>&nbsp;<wbr> &nbsp;<wbr> &nbsp;<wbr>}</p>
<p>}</p>
<p>Choices:</p>
<p>a. Derived.amethod()</p>
<p>-1</p>
<p>Derived.amethod()</p>
<p>b. Derived.amethod()</p>
<p>99</p>
<p>c.Derived.amethod()</p>
<p>99</p>
<p>d. Derived.amethod()</p>
<p>e.Compile time error</p>
<p align="left">――――――――</p>
<p align="left">B is correct. The reason is that this code creates an instance of the Derived class but assigns it to a reference of a the Base class. In this situation a reference to any of the fields such as i will refer to the value in the Base class, but a call to a method will refer to the method in the class type rather than its reference handle. But note that if the amethod() was not present in the base class then compilation error would be reported as at compile time, when compiler sees the statement like b.amethod(), it checks if the method is present in the base class or not. Only at the run time it decides to call the method from the derived class.</p>
<p align="left">&nbsp;<wbr></p>
<h3><a name="_Toc74451173">&#167;1.1.7&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 七</a></h3>
<p>Given the following code fragment:</p>
<p>&nbsp;<wbr></p>
<p>　　1) public void create() {</p>
<p>&nbsp;<wbr></p>
<p>　　2) Vector myVect;</p>
<p>&nbsp;<wbr></p>
<p>　　3) myVect = new Vector();</p>
<p>&nbsp;<wbr></p>
<p>　　4) }</p>
<p>&nbsp;<wbr></p>
<p>　　Which of the following statements are true?</p>
<p>　　A. The declaration on line 2 does not allocate memory space for the</p>
<p>variable myVect.</p>
<p>&nbsp;<wbr></p>
<p>　　B. The declaration on line 2 allocates memory space for a reference to a</p>
<p>Vector object.</p>
<p>&nbsp;<wbr></p>
<p>　　C. The statement on line 2 creates an object of class Vector.</p>
<p>&nbsp;<wbr></p>
<p>　　D. The statement on line 3 creates an object of class Vector.</p>
<p>&nbsp;<wbr></p>
<p>　　E. The statement on line 3 allocates memory space for an object of class</p>
<p>Vector</p>
<p>　　翻译</p>
<p>　　给出下面的代码片断。。。下面的哪些陈述为true(真)?</p>
<p>　　A. 第二行的声明不会为变量myVect分配内存空间。</p>
<p>　　B. 第二行的声明分配一个到Vector对象的引用的内存空间。</p>
<p>　　C. 第二行语句创建一个Vector类对象。</p>
<p>　　D. 第三行语句创建一个Vector类对象。</p>
<p>　　E. 第三行语句为一个Vector类对象分配内存空间。</p>
<p>&nbsp;<wbr></p>
<p>　　答案　A,D,E</p>
<p>&nbsp;<wbr></p>
<p>　　解析</p>
<p>　　SL-275中指出：要为一个新对象分配空间必须执行new</p>
<p>Xxx()调用，new调用执行以下的操作：</p>
<p>&nbsp;<wbr></p>
<p>　　1．为新对象分配空间并将其成员初始化为0或者null。</p>
<p>　</p>
<p>&nbsp;<wbr> 　2．执行类体中的初始化。（例如在类中有一个成员声明int a=10;在第一步后a=0</p>
<p>，执行到第二步后a=10）</p>
<p>&nbsp;<wbr></p>
<p>　　3．执行构造函数。</p>
<p>&nbsp;<wbr></p>
<p>　　4．变量被分配为一个到内存堆中的新对象的引用。</p>
<h3><a name="_Toc74451174">&#167;1.1.8&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 八</a></h3>
<p>Which of the following statements about variables and their scopes</p>
<p>are true?</p>
<p>&nbsp;<wbr></p>
<p>　　A. Instance variables are member variables of a class.</p>
<p>&nbsp;<wbr></p>
<p>　　B. Instance variables are declared with the static keyword.</p>
<p>&nbsp;<wbr></p>
<p>　　C. Local variables defined inside a method are created when the method</p>
<p>is executed.</p>
<p>&nbsp;<wbr></p>
<p>　　D. Local variables must be initialized before they are used.</p>
<p>&nbsp;<wbr></p>
<p>　　(acd)</p>
<p>&nbsp;<wbr></p>
<p>　　题目：下面关于变量及其范围的陈述哪些是对的。</p>
<p>&nbsp;<wbr></p>
<p>　　A. 实例变量是类的成员变量。</p>
<p>&nbsp;<wbr></p>
<p>　　B. 实例变量用关键字static声明。</p>
<p>&nbsp;<wbr></p>
<p>　　C. 在方法中定义的局部变量在该方法被执行时创建</p>
<p>&nbsp;<wbr></p>
<p>　　D. 局部变量在使用前必须被初始化。</p>
<p>&nbsp;<wbr></p>
<p>　　类中有几种变量，分别是：局部变量（英文可以为：local\automatic\temporary\stac</p>
<p>k</p>
<p>variable）是定义在方法里的变量；实例变量（英文为：instance</p>
<p>variable）是在方法外而在类声明内定义的变量，有时也叫成员变量；类变量（英文为：cl</p>
<p>ass</p>
<p>variable）是用关键字static声明的实例变量，他们的生存期分别是：局部变量在定义该变</p>
<p>量的方法被调用时被创建，而在该方法退出后被撤销；实例变量在使用new</p>
<p>Xxxx()创建该类的实例时被创建，而其生存期和该类的实例对象的生存期相同；类变量在该</p>
<p>类被加载时被创建，不一定要用new</p>
<p>Xxxx()创建，所有该类的实例对象共享该类变量，其生存期是类的生存期。任何变量在使用</p>
<p>前都必须初始化,但是需要指出的是局部变量必须显式初始化，而实例变量不必，原始类型的</p>
<p>实例变量在该类的构造方法被调用时为它分配的缺省的值，整型是0，布尔型是false，而浮点</p>
<p>型是0.0f，引用类型（类类型）的实例变量的缺省值是null（没有进行实际的初始化，对它的</p>
<p>使用将引起NullPointException），类变量的规则和实例变量一样，不同的是类变量的初始化</p>
<p>是在类被加载时。</p>
<h3><a name="_Toc74451175">&#167;1.1.9&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 九</a></h3>
<p>　　public class Parent {</p>
<p>　　int change() {&#8230;}</p>
<p>　　}</p>
<p>　　class Child extends Parent {</p>
<p>&nbsp;<wbr></p>
<p>　　}</p>
<p>　　Which methods can be added into class Child?</p>
<p>　　A. public int change(){}</p>
<p>&nbsp;<wbr></p>
<p>　　B. int chang(int i){}</p>
<p>&nbsp;<wbr></p>
<p>　　C. private int change(){}</p>
<p>&nbsp;<wbr></p>
<p>　　D. abstract int chang(){}</p>
<p>&nbsp;<wbr></p>
<p>　　(ab)</p>
<p>&nbsp;<wbr></p>
<p>　　题目：哪些方法可被加入类Child。</p>
<p>&nbsp;<wbr></p>
<p>　　需要注意的是答案D的内容，子类可以重写父类的方法并将之声明为抽象方法，但是这引发的问题是类必须声明为抽象类，否则编译不能通过，而且抽象方法不能有方法体，也就是方法声明后面不能带上那两个大括号（{}），这些D都不能满足。</p>
</div>
<img src ="http://www.blogjava.net/balajinima/aggbug/298535.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/balajinima/" target="_blank">李云泽</a> 2009-10-16 11:40 <a href="http://www.blogjava.net/balajinima/articles/298535.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第三部分：垃圾收集</title><link>http://www.blogjava.net/balajinima/articles/298534.html</link><dc:creator>李云泽</dc:creator><author>李云泽</author><pubDate>Fri, 16 Oct 2009 03:39:00 GMT</pubDate><guid>http://www.blogjava.net/balajinima/articles/298534.html</guid><wfw:comment>http://www.blogjava.net/balajinima/comments/298534.html</wfw:comment><comments>http://www.blogjava.net/balajinima/articles/298534.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/balajinima/comments/commentRss/298534.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/balajinima/services/trackbacks/298534.html</trackback:ping><description><![CDATA[<p align="left">第三部分：垃圾收集</p>
<ul type="disc">
    <li>了解垃圾收集机制能保证执行什么。
    <li>能通过代码操作一个对象，使它能被垃圾收集器收集。
    <li>知道在程序的哪一行，垃圾收集器能合法地收集某个对象。 </li>
</ul>
<h2>第一节&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 垃圾收集解析</h2>
<p>&nbsp;<wbr>垃圾收集器是Java语言区别于其他程序设计语言的一大特色。它把程序员从手工回收内存空间的繁重工作中解脱了出来。在SUN公司的Java程序员（Java Programmer）认证考试中，垃圾收集器是必考的内容，一般最多可以占总分值的6%左右。但是由于SUN公司的Java Programming Language SL-275 课程的标准教材中，对有关垃圾收集器的内容只做了非常简单的介绍，而另外的一些关于Java技术的书籍，比如《Java 2 核心技术》（Core Java 2）、《Java编程思想》（Thinking in Java）、《精通Java 2》等等，里面关于垃圾收集器的内容也几乎没有，或者只是简单地提两句，所以很多参加Java Programmer认证考试的中国考生，在垃圾收集器这一部分的得分都为0分（笔者曾认识一位SUN公司授权的中国Java培训班的老师，其考试总分为89%，但垃圾收集器的部分竟然也为0分）。鉴于此，笔者总结了这个垃圾收集器的专题，希望对广大Java技术的爱好者和准备认证考试的考生们有所帮助。</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 我们知道，许多程序设计语言都允许在程序运行期动态地分配内存空间。分配内存的方式多种多样，取决于该种语言的语法结构。但不论是哪一种语言的内存分配方式，最后都要返回所分配的内存块的起始地址，即返回一个指针到内存块的首地址。</p>
<p>当已经分配的内存空间不再需要时，换句话说当指向该内存块的句柄超出了使用范围的时候，该程序或其运行环境就应该回收该内存空间，以节省宝贵的内存资源。</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 在C，C++或其他程序设计语言中，无论是对象还是动态配置的资源或内存，都必须由程序员自行声明产生和回收，否则其中的资源将消耗，造成资源的浪费甚至死机。但手工回收内存往往是一项复杂而艰巨的工作。因为要预先确定占用的内存空间是否应该被回收是非常困难的！如果一段程序不能回收内存空间，而且在程序运行时系统中又没有了可以分配的内存空间时，这段程序就只能崩溃。通常，我们把分配出去后，却无法回收的内存空间称为"内存渗漏体（Memory Leaks）"。</p>
<p>以上这种程序设计的潜在危险性在Java这样以严谨、安全著称的语言中是不允许的。但是Java语言既不能限制程序员编写程序的自由性，又不能把声明对象的部分去除（否则就不是面向对象的程序语言了），那么最好的解决办法就是从Java程序语言本身的特性入手。于是，Java技术提供了一个系统级的线程（Thread），即垃圾收集器线程（Garbage Collection Thread），来跟踪每一块分配出去的内存空间，当Java 虚拟机（Java Virtual Machine）处于空闲循环时，垃圾收集器线程会自动检查每一快分配出去的内存空间，然后自动回收每一快可以回收的无用的内存块。</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 垃圾收集器线程是一种低优先级的线程，在一个Java程序的生命周期中，它只有在内存空闲的时候才有机会运行。它有效地防止了内存渗漏体的出现，并极大可能地节省了宝贵的内存资源。但是，通过Java虚拟机来执行垃圾收集器的方案可以是多种多样的。</p>
<p>下面介绍垃圾收集器的特点和它的执行机制：</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 垃圾收集器系统有自己的一套方案来判断哪个内存块是应该被回收的，哪个是不符合要求暂不回收的。垃圾收集器在一个Java程序中的执行是自动的，不能强制执行，即使程序员能明确地判断出有一块内存已经无用了，是应该回收的，程序员也不能强制垃圾收集器回收该内存块。程序员唯一能做的就是通过调用System. gc 方法来"建议"执行垃圾收集器，但其是否可以执行，什么时候执行却都是不可知的。这也是垃圾收集器的最主要的缺点。当然相对于它给程序员带来的巨大方便性而言，这个缺点是瑕不掩瑜的。</p>
<p>垃圾收集器的主要特点有：</p>
<p>1．垃圾收集器的工作目标是回收已经无用的对象的内存空间，从而避免内存渗漏体的产生，节省内存资源，避免程序代码的崩溃。</p>
<p>2．垃圾收集器判断一个对象的内存空间是否无用的标准是：如果该对象不能再被程序中任何一个"活动的部分"所引用，此时我们就说，该对象的内存空间已经无用。所谓"活动的部分"，是指程序中某部分参与程序的调用，正在执行过程中，尚未执行完毕。</p>
<p>3．垃圾收集器线程虽然是作为低优先级的线程运行，但在系统可用内存量过低的时候，它可能会突发地执行来挽救内存资源。当然其执行与否也是不可预知的。</p>
<p>4．垃圾收集器不可以被强制执行，但程序员可以通过调用System. gc方法来建议执行垃圾收集器。</p>
<p>5．不能保证一个无用的对象一定会被垃圾收集器收集，也不能保证垃圾收集器在一段Java语言代码中一定会执行。因此在程序执行过程中被分配出去的内存空间可能会一直保留到该程序执行完毕，除非该空间被重新分配或被其他方法回收。由此可见，完全彻底地根绝内存渗漏体的产生也是不可能的。但是请不要忘记，Java的垃圾收集器毕竟使程序员从手工回收内存空间的繁重工作中解脱了出来。设想一个程序员要用C或C++来编写一段10万行语句的代码，那么他一定会充分体会到Java的垃圾收集器的优点！</p>
<p>6．同样没有办法预知在一组均符合垃圾收集器收集标准的对象中，哪一个会被首先收集。</p>
<p>7．循环引用对象不会影响其被垃圾收集器收集。</p>
<p>8．可以通过将对象的引用变量（reference variables，即句柄handles）初始化为null值，来暗示垃圾收集器来收集该对象。但此时，如果该对象连接有事件监听器（典型的 AWT组件），那它还是不可以被收集。所以在设一个引用变量为null值之前，应注意该引用变量指向的对象是否被监听，若有，要首先除去监听器，然后才可以赋空值。</p>
<p>9．每一个对象都有一个finalize( )方法，这个方法是从Object类继承来的。</p>
<p>10．finalize( )方法用来回收内存以外的系统资源，就像是文件处理器和网络连接器。该方法的调用顺序和用来调用该方法的对象的创建顺序是无关的。换句话说，书写程序时该方法的顺序和方法的实际调用顺序是不相干的。请注意这只是finalize( )方法的特点。</p>
<p>11．每个对象只能调用finalize( )方法一次。如果在finalize( )方法执行时产生异常（exception），则该对象仍可以被垃圾收集器收集。</p>
<p>12．垃圾收集器跟踪每一个对象，收集那些不可到达的对象（即该对象没有被程序的任何"活的部分"所调用），回收其占有的内存空间。但在进行垃圾收集的时候，垃圾收集器会调用finalize( )方法，通过让其他对象知道它的存在，而使不可到达的对象再次"复苏"为可到达的对象。既然每个对象只能调用一次finalize( )方法，所以每个对象也只可能"复苏"一次。</p>
<p>13．finalize( )方法可以明确地被调用，但它却不能进行垃圾收集。</p>
<p>14．finalize( )方法可以被重载（overload），但只有具备初始的finalize( )方法特点的方法才可以被垃圾收集器调用。</p>
<p>15．子类的finalize( )方法可以明确地调用父类的finalize( )方法，作为该子类对象的最后一次适当的操作。但Java编译器却不认为这是一次覆盖操作（overriding），所以也不会对其调用进行检查。</p>
<p>16．当finalize( )方法尚未被调用时，System. runFinalization( )方法可以用来调用finalize( )方法，并实现相同的效果，对无用对象进行垃圾收集。</p>
<p>17．当一个方法执行完毕，其中的局部变量就会超出使用范围，此时可以被当作垃圾收集，但以后每当该方法再次被调用时，其中的局部变量便会被重新创建。</p>
<p>18．Java语言使用了一种"标记交换区的垃圾收集算法"。该算法会遍历程序中每一个对象的句柄，为被引用的对象做标记，然后回收尚未做标记的对象。所谓遍历可以简单地理解为"检查每一个"。</p>
<p>19．Java语言允许程序员为任何方法添加finalize( )方法，该方法会在垃圾收集器交换回收对象之前被调用。但不要过分依赖该方法对系统资源进行回收和再利用，因为该方法调用后的执行结果是不可预知的。</p>
<p>通过以上对垃圾收集器特点的了解，你应该可以明确垃圾收集器的作用，和垃圾收集器判断一块内存空间是否无用的标准。简单地说，当你为一个对象赋值为null并且重新定向了该对象的引用者，此时该对象就符合垃圾收集器的收集标准。</p>
<p>判断一个对象是否符合垃圾收集器的收集标准，这是SUN公司程序员认证考试中垃圾收集器部分的重要考点（可以说，这是唯一的考点）。所以，考生在一段给定的代码中，应该能够判断出哪个对象符合垃圾收集器收集的标准，哪个不符合。下面结合几种认证考试中可能出现的题型来具体讲解：</p>
<p>Object obj = new Object ( ) ;</p>
<p>我们知道，obj为Object的一个句柄。当出现new关键字时，就给新建的对象分配内存空间，而obj的值就是新分配的内存空间的首地址，即该对象的值(请特别注意，对象的值和对象的内容是不同含义的两个概念：对象的值就是指其内存块的首地址，即对象的句柄；而对象的内容则是其具体的内存块)。此时如果有 obj = null；则obj指向的内存块此时就无用了，因为下面再没有调用该变量了。</p>
<p>请再看以下三种认证考试时可能出现的题型：</p>
<p>程序段1：</p>
<p>1．fobj = new Object ( ) ;</p>
<p>2．fobj. Method ( ) ;</p>
<p>3．fobj = new Object ( ) ;</p>
<p>4．fobj. Method ( ) ;</p>
<p>问：这段代码中，第几行的fobj 符合垃圾收集器的收集标准？</p>
<p>答：第3行。因为第3行的fobj被赋了新值，产生了一个新的对象，即换了一块新的内存空间，也相当于为第1行中的fobj赋了null值。这种类型的题在认证0考试中是最简单的。</p>
<p>程序段2：</p>
<p>1．Object sobj = new Object ( ) ;</p>
<p>2．Object sobj = null ;</p>
<p>3．Object sobj = new Object ( ) ;</p>
<p>4．sobj = new Object ( ) ;</p>
<p>问：这段代码中，第几行的内存空间符合垃圾收集器的收集标准？</p>
<p>答：第1行和第3行。因为第2行为sobj赋值为null，所以在此第1行的sobj符合垃圾收集器的收集标准。而第4行相当于为sobj赋值为null，所以在此第3行的sobj也符合垃圾收集器的收集标准。</p>
<p>如果有一个对象的句柄a，且你把a作为某个构造器的参数，即 new Constructor ( a )的时候，即使你给a赋值为null，a也不符合垃圾收集器的收集标准。直到由上面构造器构造的新对象被赋空值时，a才可以被垃圾收集器收集。</p>
<p>程序段3：</p>
<p>1．Object aobj = new Object ( ) ;</p>
<p>2．Object bobj = new Object ( ) ;</p>
<p>3．Object cobj = new Object ( ) ;</p>
<p>4．aobj = bobj;</p>
<p>5．aobj = cobj;</p>
<p>6．cobj = null;</p>
<p>7．aobj = null;</p>
<p>问：这段代码中，第几行的内存空间符合垃圾收集器的收集标准？</p>
<p>答：第7行。注意这类题型是认证考试中可能遇到的最难题型了。</p>
<p>行1-3分别创建了Object类的三个对象：aobj，bobj，cobj</p>
<p>行4：此时对象aobj的句柄指向bobj，所以该行的执行不能使aobj符合垃圾收集器的收集标准。</p>
<p>行5：此时对象aobj的句柄指向cobj，所以该行的执行不能使aobj符合垃圾收集器的收集标准。</p>
<p>行6：此时仍没有任何一个对象符合垃圾收集器的收集标准。</p>
<p>行7：对象cobj符合了垃圾收集器的收集标准，因为cobj的句柄指向单一的地址空间。在第6行的时候，cobj已经被赋值为null，但由cobj同时还指向了aobj（第5行），所以此时cobj并不符合垃圾收集器的收集标准。而在第7行，aobj所指向的地址空间也被赋予了空值null，这就说明了，由cobj所指向的地址空间已经被完全地赋予了空值。所以此时cobj最终符合了垃圾收集器的收集标准。但对于aobj和bobj，仍然无法判断其是否符合收集标准。</p>
<p>总之，在Java语言中，判断一块内存空间是否符合垃圾收集器收集标准的标准只有两个：</p>
<p>1．给对象赋予了空值null，以下再没有调用过。</p>
<p>2．给对象赋予了新值，既重新分配了内存空间。</p>
<p>最后再次提醒一下，一块内存空间符合了垃圾收集器的收集标准，并不意味着这块内存空间就一定会被垃圾收集器收集。</p>
<p>&nbsp;<wbr></p>
<img src ="http://www.blogjava.net/balajinima/aggbug/298534.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/balajinima/" target="_blank">李云泽</a> 2009-10-16 11:39 <a href="http://www.blogjava.net/balajinima/articles/298534.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第二部分：流程控制，断言和异常处理</title><link>http://www.blogjava.net/balajinima/articles/298533.html</link><dc:creator>李云泽</dc:creator><author>李云泽</author><pubDate>Fri, 16 Oct 2009 03:38:00 GMT</pubDate><guid>http://www.blogjava.net/balajinima/articles/298533.html</guid><wfw:comment>http://www.blogjava.net/balajinima/comments/298533.html</wfw:comment><comments>http://www.blogjava.net/balajinima/articles/298533.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/balajinima/comments/commentRss/298533.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/balajinima/services/trackbacks/298533.html</trackback:ping><description><![CDATA[<p align="left">第二部分：流程控制，断言和异常处理</p>
<ul type="disc">
    <li>能够正确使用if,switch语句，并且能正确使用合法的参数类型。
    <li>能够正确使用所有带标签或不带标签的循环语句，能正确使用break,continue，能计算在循环中或循环后循环计数器的值。
    <li>能够正确使用异常和异常处理语句（try,catch,finally）。能正确声明抛出异常的方法，并知道怎样覆盖它。
    <li>了解代码段中的异常对程序跳转的影响。注意：异常可能是一个运行时异常（runtime&nbsp;<wbr>exception）,一个已经定义的异常（checked&nbsp;<wbr>exception），也可能是一个error。
    <li>能正确使用断言，并了解关于断言机制的正确说法。 </li>
</ul>
<div>
<ul type="disc">
    <li>能够正确使用if,switch语句，并且能正确使用合法的参数类型。
    <li>能够正确使用所有带标签或不带标签的循环语句，能正确使用break,continue，能计算在循环中或循环后循环计数器的值。
    <li>能够正确使用异常和异常处理语句（try,catch,finally）。能正确声明抛出异常的方法，并知道怎样覆盖它。
    <li>了解代码段中的异常对程序跳转的影响。注意：异常可能是一个运行时异常（runtime&nbsp;<wbr>exception）,一个已经定义的异常（checked&nbsp;<wbr>exception），也可能是一个error。
    <li>能正确使用断言，并了解关于断言机制的正确说法。 </li>
</ul>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr></p>
<h2>第一节&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 断言 assert</h2>
<h3><a name="1">&#167;1.1.1&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> assertion</a>的语法和语义</h3>
<p>J2SE 1.4在语言上提供了一个新特性，就是assertion(断言)功能，它是该版本在Java语言方面最大的革新。在软件开发中，assertion是一种经典的调试、测试方式，本文将深入解析assertion功能的使用以及其设计理念，并给出相关的例子。</p>
<p>assertion(断言)在软件开发中是一种常用的调试方式，很多开发语言中都支持这种机制，如C，C++和Eiffel等，但是支持的形式不尽相同，有的是通过语言本身、有的是通过库函数等。另外，从理论上来说，通过assertion方式可以证明程序的正确性，但是这是一项相当复杂的工作，目前还没有太多的实践意义。</p>
<p>在实现中，assertion就是在程序中的一条语句，它对一个boolean表达式进行检查，一个正确程序必须保证这个boolean表达式的值为true；如果该值为false，说明程序已经处于不正确的状态下，系统将给出警告或退出。一般来说，assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能，在软件发布后，assertion检查通常是关闭的。下面简单介绍一下Java中assertion的实现。</p>
<p><strong>1</strong><strong>．</strong><strong>1)</strong> <strong>语法表示</strong></p>
<p>在语法上，为了支持assertion，Java增加了一个关键字assert。它包括两种表达式，分别如下：</p>
<p>1.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> assert expression_r1;</p>
<p>2.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> assert expression_r1: expression_r2;</p>
<p>在两种表达式中，expression_r1表示一个boolean表达式，expression_r2表示一个基本类型或者是一个对象(Object) ，基本类型包括boolean,char,double,float,int和long。由于所有类都为Object的子类，因此这个参数可以用于所有对象。</p>
<p><strong>1</strong><strong>．</strong><strong>2)</strong> <strong>语义含义</strong></p>
<p>在运行时，如果关闭了assertion功能，这些语句将不起任何作用。如果打开了assertion功能，那么expression_r1的值将被计算，如果它的值为false，该语句强抛出一个AssertionError对象。如果assertion语句包括expression_r2参数，程序将计算出expression_r2的结果，然后将这个结果作为AssertionError的构造函数的参数，来创建AssertionError对象，并抛出该对象；如果expression_r1值为true，expression_r2将不被计算。</p>
<p>一种特殊情况是，如果在计算表达式时，表达式本身抛出Exception，那么assert将停止运行，而抛出这个Exception。</p>
<p><strong>1</strong><strong>．</strong><strong>3)</strong> <strong>一些</strong><strong>assertion</strong><strong>例子</strong></p>
<p>下面是一些Assert的例子。</p>
<p>1.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> assert　　0 &lt; value;</p>
<p>2.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> assert　　0 &lt; value:"value="+value;</p>
<p>3.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> assert　　ref != null:"ref doesn't equal null";</p>
<p>4.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> assert　　isBalanced();</p>
<p><strong>1</strong><strong>．</strong><strong>4)</strong> <strong>编译</strong></p>
<p>由于assert是一个新关键字，使用老版本的JDK是无法编译带有assert的源程序。因此，我们必须使用JDK1.4(或者更新)的Java编译器，在使用Javac命令时，我们必须加上-source 1.4作为参数。-source 1.4表示使用JDK 1.4版本的方式来编译源代码，否则编译就不能通过，因为缺省的Javac编译器使用JDK1.3的语法规则。</p>
<p>一个简单的例子如下：</p>
<p>javac&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> -source&nbsp;<wbr>&nbsp;<wbr> 1.4&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> test.java</p>
<p><strong>1</strong><strong>．</strong><strong>5)</strong> <strong>运行</strong></p>
<p>由于带有assert语句的程序运行时，使用了新的ClassLoader和Class类，因此，这种程序必须在JDK1.4(或者更高版本)的JRE下运行，而不能在老版本的JRE下运行。</p>
<p>1.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 由于我们可以选择开启assertion功能，或者不开启，另外我们还可以开启一部分类或包的assertion功能，所以运行选项变得有些复杂。通过这些选项，我们可以过滤所有我们不关心的类，只选择我们关心的类或包来观察。</p>
<h3><a name="2">&#167;1.1.2&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> assertion</a>的设计问题</h3>
<p>首先，我们认为assertion是必要的。因为，如果没有统一的assertion机制，Java程序通常使用if-then-else或者switch-case语句进行assertion检查，而且检查的数据类型也不完全相同。assertion机制让Java程序员用统一的方式处理assertion问题，而不是按自己的方式处理。另外，如果用户使用自己的方式进行检查，那么这些代码在发布以后仍然将起作用，这可能会影响程序的性能。而从语言言层次支持assertion功能，这将把assertion对性能带来的负面影响降到最小。</p>
<p>Java是通过增强一个关键字assert实现支持assertion，而不是使用一个库函数支持，这说明Java认为assertion对于语言本身来说是非常重要的。实际上，在Java的早期的规范中，Java是能够支持assert的，但是由于一些实现的限制，这些特性从规范中除去了。因此，assert的再次引入应该是恢复了Java对assert的支持。C语言就是通过Assert.h函数库实现断言的支持。</p>
<p>Java的assertion的开启也和C语言不太一样，我们都知道在C语言中，assertion的开启是在编译时候决定的。当我们使用debug方式编译程序时候，assertion被开启，而使用release方式编译时候，assertion自动被关闭。而Java的assertion却是在运行的时候进行决定的。其实，这两种方式是各有优缺点。如果采用编译时决定方式，开发人员将处理两种类型的目标码，debug版本和release版本，这加大了文档管理的难度，但是提高了代码的运行效率。Java采用运行时决定的方式，这样所有的assertion信息将置于目标代码中，同一目标代码可以选择不同方式运行，增强目标代码的灵活性，但是它将牺牲因为assertion而引起一部分性能损失。Java专家小组认为，所牺牲的性能相当小，因此java采用了运行时决定方式。</p>
<p>另外，我们注意到AssertionError作为Error的一个子类，而不是RuntimeException。关于这一点，专家组也进行了长期的讨论。Error代表一些异常的错误，通常是不可以恢复的，而RuntimeException强调该错误在运行时才发生的特点。AssertionError通常为非常关键的错误，这些错误往往是不容易恢复的，而且assertion机制也不鼓励程序员对这种错误进行恢复。因此，为了强调assertion的含义，Java专家小组选择了让AssertError为Error的子类。</p>
<h3><a name="3">&#167;1.1.3&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> assertion</a>与继承</h3>
<p>在本节，我们将考虑assertion与继承的关系，研究assert是如何定位的。如果开启一个子类的assertion，那么它的父类的assertion是否执行？</p>
<p>下面的例子将显示如果一个assert语句在父类，而当它的子类调用它时，该assert为false。我们看看在不同的情况下，该assertion是否被处理。</p>
<p>class Base</p>
<p>{</p>
<p>&nbsp;<wbr> public void baseMethod()</p>
<p>&nbsp;<wbr> { // 总是assertion失败</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> assert&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> false : "Assertion failed:This is base ";</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println("Base Method");</p>
<p>&nbsp;<wbr> }</p>
<p>}</p>
<p>&nbsp;<wbr></p>
<p>class Derived</p>
<p>&nbsp;<wbr> extends Base</p>
<p>{</p>
<p>&nbsp;<wbr> public void derivedMethod()</p>
<p>&nbsp;<wbr> { // 总是assertion失败</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> assert false: "Assertion failed:This is derive";</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println( "Derived Method" );</p>
<p>&nbsp;<wbr> }</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr> public static void main( String[] args )</p>
<p>&nbsp;<wbr> {</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> try</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> Derived derived = new Derived();</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> derived.baseMethod(&nbsp;<wbr> );</p>
<p>&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>derived.derivedMethod();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> catch( AssertionError ae )</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> {</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> System.out.println(ae);</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p>&nbsp;<wbr> }</p>
<p>}</p>
<table border="1" cellpadding="0" width="98%">
    <tbody>
        <tr>
            <td width="26%">
            <p>运行命令</p>
            </td>
            <td width="32%">
            <p>含义</p>
            </td>
            <td width="40%">
            <p>结果</p>
            </td>
        </tr>
        <tr>
            <td width="26%">
            <p>Java Derived</p>
            </td>
            <td width="32%">
            <p>不启用assertion</p>
            </td>
            <td width="40%">
            <p>Base Method<br />
            Derived Method</p>
            </td>
        </tr>
        <tr>
            <td width="26%">
            <p>Java -ea Derived</p>
            </td>
            <td width="32%">
            <p>开启所有assertion</p>
            </td>
            <td width="40%">
            <p>Java.lang.AssertionError:Assertion Failed:This is base</p>
            </td>
        </tr>
        <tr>
            <td width="26%">
            <p>Java -da Derived</p>
            </td>
            <td width="32%">
            <p>关闭所有assertion</p>
            </td>
            <td width="40%">
            <p>Base Method<br />
            Derived Method</p>
            </td>
        </tr>
        <tr>
            <td width="26%">
            <p>Java -ea:Base Derived</p>
            </td>
            <td width="32%">
            <p>仅打开Base的assertion</p>
            </td>
            <td width="40%">
            <p>Java.lang.AssertionError:Assertion Failed:This is base</p>
            </td>
        </tr>
        <tr>
            <td width="26%">
            <p>Java -ea:Derived Derived</p>
            </td>
            <td width="32%">
            <p>仅打开Derived的assertion</p>
            </td>
            <td width="40%">
            <p>Base Method<br />
            Java.lang.AssertionError:Assertion Failed:This is derived</p>
            </td>
        </tr>
    </tbody>
</table>
<p>从这个例子我们可以看出，父类的assert语句将只有在父类的assert开启才起作用，如果仅仅开启子类的assert，父类的assert仍然不运行。例如，我们执行java -ea:Derived Derived的时候，Base类的assert语句并不执行。因此，我们可以认为，assert语句不具有继承功能。</p>
<h3><a name="4">&#167;1.1.4&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> assertion</a>的使用</h3>
<p>assertion的使用是一个复杂的问题，因为这将涉及到程序的风格，assertion运用的目标，程序的性质等问题。通常来说，assertion用于检查一些关键的值，并且这些值对整个程序，或者局部功能的完成有很大的影响，并且这种错误不容易恢复的。assertion表达式应该短小、易懂，如果需要评估复杂的表达式，应该使用函数计算。以下是一些使用assertion的情况的例子，这些方式可以让java程序的可靠性更高。</p>
<p align="left">1.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 检查控制流；在if-then-else和swith-case语句中，我们可以在不应该发生的控制支流上加上assert false语句。如果这种情况发生了，assert能够检查出来。<br />
例如：x取值只能使1,2,3，我们的程序可以如下表示</p>
<p align="left">2.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> switch (x)</p>
<p>3.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> { case 1: &#8230;;</p>
<p>4.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>case 2: &#8230;;</p>
<p>5.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>case 3: &#8230;</p>
<p>6.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>default: assert false:"x value is invalid: "+x;</p>
<p>7.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> }</p>
<p align="left">8.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 在私有函数计算前，检查输入参数是否有效；对于一私有些函数，要求输入满足一些特定的条件，那么我们可以在函数开始处使用assert进行参数检查。对于公共函数，我们通常不使用assertion检查，因为一般来说，公共函数必须对无效的参数进行检查和处理。而私有函数往往是直接使用的。<br />
例如：某函数可能要求输入的参数必须不为null。那么我们可以在函数的一开始加上 assert parameter1!=null : "paramerter is null in test method";</p>
<p align="left">9.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 在函数计算后，检查函数结果是否有效；对于一些计算函数，函数运行完成后，某些值需要保证一定的性质，因此我们可以通过assert检查该值。<br />
例如，我们有一个计算绝对值的函数，那么我们就可以在函数的结果处，加上一个语句：</p>
<p align="left">assert&nbsp;<wbr> value&gt;=0:"Value should be bigger than 0:"+value;</p>
<p align="left">通过这种方式，我们可以对函数计算完的结果进行检查。</p>
<p align="left">10.&nbsp;<wbr>&nbsp;<wbr> 检查程序不变量；有些程序中，存在一些不变量，在程序的运行生命周期，这些不变量的值都是不变的。这些不变量可能是一个简单表达式，也可能是一个复杂的表达式。对于一些关键的不变量，我们可以通过assert进行检查。<br />
例如，在一个财会系统中，公司的支出和收入必须保持一定的平衡关系，因此我们可以编写一个表达式检查这种平衡关系，如下表示。</p>
<p align="left">11.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>private boolean isBalance() {</p>
<p align="left">12.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&#8230;&#8230;</p>
<p align="left">13.&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>}</p>
<p align="left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> &nbsp;<wbr></p>
<p align="left">在这个系统中，在一些可能影响这种平衡关系的方法的前后，我们都可以加上assert验证：assert isBalance():"balance is destoried";</p>
<h3><a name="5">&#167;1.1.5&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 结论</a></h3>
<p>assertion为开发人员提供了一种灵活地调试和测试机制，它的使用也非常简单、方便。但是，如何规范、系统地使用assertion(特别是在Java语言中)仍然是一个亟待研究的问题</p>
</div>
<img src ="http://www.blogjava.net/balajinima/aggbug/298533.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/balajinima/" target="_blank">李云泽</a> 2009-10-16 11:38 <a href="http://www.blogjava.net/balajinima/articles/298533.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>第一部分：声明和访问控制(练习题)</title><link>http://www.blogjava.net/balajinima/articles/298532.html</link><dc:creator>李云泽</dc:creator><author>李云泽</author><pubDate>Fri, 16 Oct 2009 03:37:00 GMT</pubDate><guid>http://www.blogjava.net/balajinima/articles/298532.html</guid><wfw:comment>http://www.blogjava.net/balajinima/comments/298532.html</wfw:comment><comments>http://www.blogjava.net/balajinima/articles/298532.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/balajinima/comments/commentRss/298532.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/balajinima/services/trackbacks/298532.html</trackback:ping><description><![CDATA[<p align="left">第一部分：声明和访问控制</p>
<ul type="disc">
    <li>知道怎么样声明、创建和初始化各种类型的数组
    <li>知道怎么样声明类、内部类、方法、成员变量、静态变量和方法内部变量，并会使用合法的修饰符（如public,final,static,abstract,等等）。了解这些修饰符单独使用或组合使用的含义，并且知道它们对于包作用域的影响。
    <li>了解类的构造器（constructor）
    <li>给定一个方法，能判断它的合法返回类型 </li>
</ul>
<div>
<h3><a name="_Toc74451139">&#167;1.1.1&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 一</a></h3>
<p>In the following pieces of code, A and D will compile without any error. True/False?</p>
<p>A: StringBuffer sb1 = "abcd";</p>
<p>B: Boolean b = new Boolean("abcd");</p>
<p>C: byte b = 255;</p>
<p>D: int x = 0x1234;</p>
<p>E: float fl = 1.2;</p>
<p>&nbsp;<wbr></p>
<p>Choices:</p>
<p>A. True</p>
<p>B. False</p>
<p>―――――――――――――――――――――――――――――――</p>
<p>答案 B. The code segments B and D will compile without any error. A is not a valid way to construct a StringBuffer, you need to creat a StringBuffer object using "new". B is a valid construction of a Boolean (any string other than "true" or "false" to the Boolean constructor will result in a Boolean with a value of "false"). C will fail to compile because the valid range for a byte is -128 to +127 (ie, 8 bits,signed). D is correct, 0x1234 is the hexadecimal representation in java. E fails to compile because the compiler interprets 1.2 as a double being assigned to a float (down-casting), which is not valid. You either need an explicit cast (as in "(float)1.2") or "1.2f", to indicate a float.</p>
<p align="left">&nbsp;<wbr></p>
<p align="left">&nbsp;<wbr></p>
<p align="left">&nbsp;<wbr></p>
<h3><a name="_Toc74451140">&#167;1.1.2&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 二</a></h3>
<p>What will be the result of executing the following code?</p>
<p>Given that Test1 is a class.</p>
<p>1. Test1[] t1 = new Test1[10];</p>
<p>2. Test1[][] t2 = new Test1[5][];</p>
<p>3. if (t1[0] == null)</p>
<p>4. {</p>
<p>5.t2[0] = new Test1[10]</p>
<p>6.t2[1] = new Test1[10]</p>
<p>7.t2[2] = new Test1[10]</p>
<p>8.t2[3] = new Test1[10]</p>
<p>9.t2[4] = new Test1[10]</p>
<p>10. }</p>
<p>11. System.out.println(t1[0]);</p>
<p>12. System.out.println(t2[1][0]);</p>
<p>Choices:</p>
<p>a. The code will not compile because the array t2 is not initialized in an unconditional statement before use.</p>
<p>b. The code will compile but a runtime exception will be thrown at line 12.</p>
<p>c. The code will compile but a runtime exception will be thrown at line 11.</p>
<p>d. None of these.</p>
<p>―――――――――――――――――――――</p>
<p>D is correct. Though we cannot use local variables without initializing them (compilation error), there is an exception to it. In case of arrays initialization is supposed to be complete when we specify the leftmost dimension of the array. The problem occurs at runtime if we try to access an element of the array which has not been initialized (specification of size). In the question above the array t2 is initialized before use, therefore there will be no problem at runtime also and the lines 11 and 12 will both print null.</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451141">&#167;1.1.3&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 三</a></h3>
<p>Which declarations of identifiers are legal?</p>
<p>　A. $persons</p>
<p>　　B. TwoUsers</p>
<p>　　C. *point</p>
<p>　　D. this</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> E. _endline</p>
<p>　　</p>
<p>　　答案　A,B,E</p>
<p>　　</p>
<p>　　解析　Java的标识符可以以一个Unicode字符，下滑线（_），美元符（$）开始，后续字</p>
<p>符可以是前面的符号和数字，没有长度限制，大小写敏感，不能是保留字。</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451142">&#167;1.1.4&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 四</a></h3>
<p>Which of the following answer is correct to express the value 8 in octal number?</p>
<p>　　A. 010</p>
<p>　　B. 0x10</p>
<p>　　C. 08</p>
<p>　　D. 0x8</p>
<p>&nbsp;<wbr></p>
<p>　　翻译</p>
<p>　　下面的哪些答案可以用以表示八进制值8。</p>
<p>　　答案　A</p>
<p>&nbsp;<wbr></p>
<p>　　解析　　八进制值以0开头，以0x开头的为十六进制值，八进制中不能出现数字8，最大只有7。</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451143">&#167;1.1.5&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 五</a></h3>
<p>Which are not Java keywords?</p>
<p>　　A. TRUE</p>
<p>　　B. sizeof</p>
<p>　　C. const</p>
<p>　　D. super</p>
<p>　　E. void</p>
<p>&nbsp;<wbr></p>
<p>　　翻译</p>
<p>　　哪些不是Java关键字。</p>
<p>&nbsp;<wbr></p>
<p>　　答案　A,B</p>
<p>&nbsp;<wbr></p>
<p>　　解析</p>
<p>　&nbsp;<wbr> A：不是，Java中有true,但是这也不是关键字而是字面量（literal）。</p>
<p>　B：不是，Java中不需要这个操作符，所有的类型（原始类型）的大小都是固定的。</p>
<p>　C、D、E都是，需要说明的是const是java中未被使用的关键字。</p>
<p>&nbsp;<wbr></p>
<h3><a name="_Toc74451144">&#167;1.1.6&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 六</a></h3>
<p>Which statements about Java code security are true?</p>
<p>　　A. The bytecode verifier loads all classes needed for the execution of a program.</p>
<p>　　B. Executing code is performed by the runtime interpreter.</p>
<p>　　C. At runtime the bytecodes are loaded, checked and run in an interpreter.</p>
<p>　　D. The class loader adds security by separating the namespaces for the</p>
<p>classes of the local file system from those imported from network sources.</p>
<p>&nbsp;<wbr></p>
<p>――――――――――――――</p>
<p>答案 BCD</p>
<p>&nbsp;<wbr></p>
<h3>&#167;1.1.7&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 七</h3>
<p>　　题目：下面有关java代码安全性的叙述哪些是对的。</p>
<p>　　A. 字节码校验器加载查询执行需要的所有类。</p>
<p>&nbsp;<wbr></p>
<p>　　B. 运行时解释器执行代码。</p>
<p>&nbsp;<wbr></p>
<p>　　C. 在运行时，字节码被加载，验证然后在解释器里面运行。</p>
<p>&nbsp;<wbr></p>
<p>　　D. 类加载器通过分离本机文件系统的类和从网络导入的类增加安全性。</p>
<p>&nbsp;<wbr></p>
<p>　　SL275中描述的Java程序运行的过程是这样的：类加载器（class loader）加载程序运行所需要的所有类，它通过区分本机文件系统的类和网络系统导入的类增加安全性，这可以限制任何的特洛伊木马程序，因为本机类总是先被加载，一旦所有的类被加载完，执行文件的内存划分就固定了，在这个时候特定的内存地址被分配给对应的符号引用，查找表（lookuo table）也被建立，由于内存划分发生在运行时，解释器在受限制的代码区增加保护防止未授权的访问；然后字节码校验器（byte code verifier）进行校验，主要执行下面的检查：类符合JVM规范的类文件格式，没有违反访问限制，代码没有造成堆栈的上溢或者下溢，所有操作代码的参数类型都是正确的，没有非法的数据类型转换（例如将整型数转换成对象类型）发生；校验通过的字节码被解释器（interpreter）执行，解释器在必要时通过运行时系统执行对底层硬件的合适调用。后三个答案是SL275中的原话。</p>
<h3>&#167;1.1.8&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 八</h3>
<p>Which fragments are correct in Java source file?</p>
<p>　　A. package testpackage;</p>
<p>　　public class Test{//do something...}</p>
<p>&nbsp;<wbr></p>
<p>　　B. import java.io.*;</p>
<p>　　package testpackage;</p>
<p>　　public class Test{// do something...}</p>
<p>&nbsp;<wbr></p>
<p>　　C. import java.io.*;</p>
<p>　　class Person{// do something...}</p>
<p>　　public class Test{// do something...}</p>
<p>&nbsp;<wbr></p>
<p>　　D. import java.io.*;</p>
<p>　　import java.awt.*;</p>
<p>　　public class Test{// do something...}</p>
<p>&nbsp;<wbr></p>
<p>------------------------</p>
<p>答案 ACD</p>
<p>　</p>
<h3>&#167;1.1.9&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 九</h3>
<p>Which of the following statements are legal?</p>
<p>　　A. long l = 4990;</p>
<p>　　B. int i = 4L;</p>
<p>　　C. float f = 1.1;</p>
<p>　　D. double d = 34.4;</p>
<p>　　E. double t = 0.9F.</p>
<p>----------------------------</p>
<p>答案　ADE</p>
<p>&nbsp;</p>
</div>
<img src ="http://www.blogjava.net/balajinima/aggbug/298532.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/balajinima/" target="_blank">李云泽</a> 2009-10-16 11:37 <a href="http://www.blogjava.net/balajinima/articles/298532.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>解析Java对象的equals()和hashCode()的使用</title><link>http://www.blogjava.net/balajinima/articles/298351.html</link><dc:creator>李云泽</dc:creator><author>李云泽</author><pubDate>Thu, 15 Oct 2009 03:21:00 GMT</pubDate><guid>http://www.blogjava.net/balajinima/articles/298351.html</guid><wfw:comment>http://www.blogjava.net/balajinima/comments/298351.html</wfw:comment><comments>http://www.blogjava.net/balajinima/articles/298351.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/balajinima/comments/commentRss/298351.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/balajinima/services/trackbacks/298351.html</trackback:ping><description><![CDATA[<p><strong>前言</strong> </p>
<p>在Java语言中，equals()和hashCode()两个函数的使用是紧密配合的，你要是自己设计其中一个，就要设计另外一个。在多数情况 下，这两个函数是不用考虑的，直接使用它们的默认设计就可以了。但是在一些情况下，这两个函数最好是自己设计，才能确保整个程序的正常运行。最常见的是当 一个对象被加入集合对象（collection object）时，这两个函数必须自己设计。更细化的定义是：如果你想将一个对象A放入另一个Collection Object B里，或者使用这个对象A为查找一个元对象在Collection Object&nbsp;&nbsp;&nbsp; B里位置的key，并支持是否容纳，删除Collection Object&nbsp;&nbsp;&nbsp; B里的元对象这样的操作，那么，equals()和hashCode()函数必须开发者自己定义。其他情 况下，这两个函数是不需要定义的。</p>
<p><strong>equals():</strong> <br />
它是用于进行两个对象的比较的，是对象内容的比较，当然也能用于进行对象参阅值的比较。什么是对象参阅值的比较？就是两个参阅变量的值得比较，我们 都知道参阅变量的值其实就是一个数字，这个数字可以看成是鉴别不同对象的代号。两个对象参阅值的比较，就是两个数字的比较，两个代号的比较。这种比较是默 认的对象比较方式，在Object这个对象中，这种方式就已经设计好了。所以你也不用自己来重写，浪费不必要的时间。</p>
<p>对象内容的比较才是设计equals()的真正目的，Java语言对equals()的要求如下，这些要求是必须遵循的。否则，你就不该浪费时间： <br />
对称性：如果x.equals(y)返回是&#8220;true&#8221;，那么y.equals(x)也应该返回是&#8220;true&#8221;。 <br />
反射性：x.equals(x)必须返回是&#8220;true&#8221;。 <br />
类推性：如果x.equals(y)返回是&#8220;true&#8221;，而且y.equals(z)返回是&#8220;true&#8221;，那么z.equals(x)也应该返回是&#8220;true&#8221;。 <br />
还有一致性：如果x.equals(y)返回是&#8220;true&#8221;，只要x和y内容一直不变，不管你重复x.equals(y)多少次，返回都是&#8220;true&#8221;。 <br />
任何情况下，x.equals(null)，永远返回是&#8220;false&#8221;；x.equals(和x不同类型的对象)永远返回是&#8220;false&#8221;。 <br />
<strong>hashCode():</strong><br />
这 个函数返回的就是一个用来进行hash操作的整型代号，请不要把这个代号和前面所说的参阅变量所代表的代号弄混了。后者不仅仅是个代号还具有在内存中才查找对 象的位置的功能。hashCode()所返回的值是用来分类对象在一些特定的Collection对象中的位置。这些对象是HashMap, Hashtable, HashSet，等等。这个函数和上面的equals()函数必须自己设计，用来协助HashMap, Hashtable, HashSet，等等对自己所收集的大量对象进行搜寻和定位。</p>
<p>这些Collection对象究竟如何工作的，想象每个元对象hashCode是一个箱子的 编码，按照编码，每个元对象就是根据hashCode()提供的代号归入相应的箱子里。所有的箱子加起来就是一个HashSet，HashMap，或 Hashtable对象，我们需要寻找一个元对象时，先看它的代码，就是hashCode()返回的整型值，这样我们找到它所在的箱子，然后在箱子里，每 个元对象都拿出来一个个和我们要找的对象进行对比，如果两个对象的内容相等，我们的搜寻也就结束。这种操作需要两个重要的信息，一是对象的 hashCode()，还有一个是对象内容对比的结果。</p>
<p>hashCode()的返回值和equals()的关系如下：</p>
<p>如果x.equals(y)返回&#8220;true&#8221;，那么x和y的hashCode()必须相等。 <br />
如果x.equals(y)返回&#8220;false&#8221;，那么x和y的hashCode()有可能相等，也有可能不等。 </p>
<p>为什么这两个规则是这样的，原因其实很简单，拿HashSet来说吧，HashSet可以拥有一个或更多的箱子，在同一个箱子中可以有一个 或更多的独特元对象（HashSet所容纳的必须是独特的元对象）。这个例子说明一个元对象可以和其他不同的元对象拥有相同的hashCode。但是一个 元对象只能和拥有同样内容的元对象相等。所以这两个规则必须成立。(在实际的某个集合对象如HashSet set.contains(object o);时，是先通过 hashcode()找到&#8220;箱子&#8221; ，在根据 equals判断对象内容 是否相等，从而判断集合对象是否包含某个元对象）</p>
<p><strong>设计这两个函数所要注意到的：<br />
</strong>如果你设计的对象类型并不使用于Collection对象，那么没有必要自己再设计这两个函数的处理方式。这是正确的面向对象设计方法，任何用户一时用不到的功能，就先不要设计，以免给日后功能扩展带来麻烦。</p>
<p>如果你在设计时想别出心裁，不遵守以上的两套规则，那么劝你还是不要做这样想入非非的事。我还没有遇到过哪一个开发者和我说设计这两个函数要违背前面说的两个规则，我碰到这些违反规则的情况时，都是作为设计错误处理。</p>
<p>当一个对象类型作为Collection对象的元对象时，这个对象应该拥有自己处理equals()，和/或处理hashCode()的设计，而且要遵守前面所说 的两种原则。equals()先要查null和是否是同一类型。查同一类型是为了避免出现ClassCastException这样的异常给丢出来。查 null是为了避免出现NullPointerException这样的异常给丢出来。</p>
<p>如果你的对象里面容纳的数据过多，那么这两个函数 equals()和hashCode()将会变得效率低。如果对象中拥有无法serialized的数据，equals()有可能在操作中出现错误。想象 一个对象x，它的一个整型数据是transient型（不能被serialize成二进制数据流）。然而equals()和hashCode()都有依靠 这个整型数据，那么，这个对象在serialization之前和之后，是否一样？答案是不一样。因为serialization之前的整型数据是有效的 数据，在serialization之后，这个整型数据的值并没有存储下来，再重新由二进制数据流转换成对象后，两者（对象在serialization 之前和之后）的状态已经不同了。这也是要注意的。</p>
<p><strong>知道以上这些能够帮助你：<br />
</strong>1. 进行更好的设计和开发。<br />
2. 进行更好的测试案例开发。<br />
3. 在面试过程中让面试者对你的学识渊博感到满意。 </p>
<p><span style="color: red">在Hibernate中，POJO类要重写hashcode()方法和equals()方法。为什么呢？</span></p>
<p>1，重点是equals，重写hashCode只是技术要求（为了提高效率） </p>
<p>2，为什么要重写equals呢，因为在java的集合框架中，是通过equals来判断两个对象是否相等的 </p>
<p>3，在hibernate中，经常使用set集合来保存相关对象，而set集合是不允许重复的，但是下面的程序，判断一下运行结果：</p>
<p>&nbsp;&nbsp;&nbsp; Set user = new HashSet(); <br />
&nbsp;&nbsp;&nbsp; user.add(new Book("精通struts")); <br />
&nbsp;&nbsp;&nbsp; user.add(new Book("精通struts")); <br />
&nbsp;&nbsp;&nbsp; System.out.println(user.size()); </p>
<p>上面程序的运行结果取决于Book类是否重写了equals方法。</p>
<p>如果没有重写，默认equals是比较地址，那么这两个book对象不一样，输出2，意味着hibernate会认为这是两个对象，再接下来的持久化过程中可能会出错。</p>
<p>如果重写了equals，比如按照主键（书名）比较，那么这两个对象是一样的，输出1 。</p>
<p><br />
&nbsp;</p>
<img src ="http://www.blogjava.net/balajinima/aggbug/298351.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/balajinima/" target="_blank">李云泽</a> 2009-10-15 11:21 <a href="http://www.blogjava.net/balajinima/articles/298351.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java异常分类</title><link>http://www.blogjava.net/balajinima/articles/298342.html</link><dc:creator>李云泽</dc:creator><author>李云泽</author><pubDate>Thu, 15 Oct 2009 03:03:00 GMT</pubDate><guid>http://www.blogjava.net/balajinima/articles/298342.html</guid><wfw:comment>http://www.blogjava.net/balajinima/comments/298342.html</wfw:comment><comments>http://www.blogjava.net/balajinima/articles/298342.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/balajinima/comments/commentRss/298342.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/balajinima/services/trackbacks/298342.html</trackback:ping><description><![CDATA[<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong><span style="font-size: 14pt"><span style="font-family: Times New Roman">Java</span></span></strong><strong><span style="font-family: 宋体; font-size: 14pt">中异常的分类</span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-size: small"><span style="font-family: 宋体">所有异常，都继承自</span><span style="font-family: Times New Roman">java.lang.Throwable</span><span style="font-family: 宋体">类。</span></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-size: small"><span style="font-family: Times New Roman">Throwable</span><span style="font-family: 宋体">有两个直接子类，</span><span style="font-family: Times New Roman">Error</span><span style="font-family: 宋体">类和</span><span style="font-family: Times New Roman">Exception</span><span style="font-family: 宋体">类。</span></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong><span style="font-size: 14pt"><span style="font-family: Times New Roman">Exception</span></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-size: small"><span style="font-family: Times New Roman">Exception</span><span style="font-family: 宋体">则可使从任何标准</span><span style="font-family: Times New Roman">Java</span><span style="font-family: 宋体">库的类方法，自己的方法以及运行时任何异常中抛出来的基类型。</span></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-size: small"><span style="font-family: 宋体">异常可分为执行异常（</span><span style="font-family: Times New Roman">RuntimeException</span><span style="font-family: 宋体">）和检查异常（</span><span style="font-family: Times New Roman">Checked Exceptions</span><span style="font-family: 宋体">）两种</span></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong><span style="font-size: 14pt"><span style="font-family: Times New Roman">RuntimeException</span></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">RuntimeException</span><span style="font-size: small"><span style="font-family: 宋体">在默认情况下会得到自动处理。所以通常用不着捕获</span><span style="font-family: Times New Roman">RuntimeException</span><span style="font-family: 宋体">，但在自己的封装里，也许仍然要选择抛出一部分</span><span style="font-family: Times New Roman">RuntimeException</span><span style="font-family: 宋体">。</span></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><code><span style="font-size: 12pt"><span style="font-family: 宋体">RuntimeException</span></span></code><span style="font-size: small"><span style="font-family: 宋体">是那些可能在</span><span style="font-family: Times New Roman"> Java </span><span style="font-family: 宋体">虚拟机正常运行期间抛出的异常的超类。可能在执行方法期间抛出但未被捕获的</span><code><span style="font-size: 12pt"><span style="font-family: 宋体">RuntimeException</span></span></code><span style="font-family: 宋体">的任何子类都<strong><span style="color: red">无需</span></strong>在</span><code><span style="font-size: 12pt"><span style="font-family: 宋体">throws</span></span></code><span style="font-family: 宋体">子句中进行声明。（</span><span style="font-family: Times New Roman">java api</span><span style="font-family: 宋体">）</span></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-size: small"><span style="font-family: 宋体">它是</span><span style="font-family: Times New Roman">uncheckedExcepiton</span><span style="font-family: 宋体">。</span></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.ArithmeticException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.ArrayStoreExcetpion</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.ClassCastException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.EnumConstantNotPresentException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.IllegalArgumentException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-size: small"><span style="font-family: Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Java.lang.IllegalThreadStateException</span></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-size: small"><span style="font-family: Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Java.lang.NumberFormatException</span></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.IllegalMonitorStateException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.IllegalStateException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.IndexOutOfBoundsException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-size: small"><span style="font-family: Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Java.lang.ArrayIndexOutOfBoundsException</span></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-size: small"><span style="font-family: Times New Roman">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Java.lang.StringIndexOutOfBoundsException</span></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.NegativeArraySizeException&#8217;</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.NullPointerException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.SecurityException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.TypeNotPresentException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.UnsupprotedOperationException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong><span style="font-size: 14pt"><span style="font-family: Times New Roman">CheckedException</span></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-size: small"><span style="font-family: 宋体">除了</span><span style="font-family: Times New Roman">runtimeException</span><span style="font-family: 宋体">以外的异常，都属于</span><span style="font-family: Times New Roman">checkedException</span><span style="font-family: 宋体">，它们都在</span><span style="font-family: Times New Roman">java.lang</span><span style="font-family: 宋体">库内部定义。</span><span style="font-family: Times New Roman">Java</span><span style="font-family: 宋体">编译器要求程序必须捕获或声明抛出这种异常。</span></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-size: small"><span style="font-family: 宋体">一个方法必须通过</span><span style="font-family: Times New Roman">throws</span><span style="font-family: 宋体">语句在方法的声明部分说明它可能抛出但并未捕获的所有</span><span style="font-family: Times New Roman">checkedException</span><span style="font-family: 宋体">。</span></span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.ClassNotFoundException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.CloneNotSupportedException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.IllegalAccessException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.InterruptedException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.NoSuchFieldException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman; font-size: small">Java.lang.NoSuchMetodException</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><strong><span style="font-size: 14pt"><span style="font-family: Times New Roman">Error</span></span></strong></p>
<p style="margin: 0cm 0cm 0pt" class="Default"><span style="font-family: 宋体; color: windowtext; font-size: 10.5pt">当程序发生不可控这种错误时，通常的做法是通知用户并中止程序的执行。</span></p>
<p style="margin: 0cm 0cm 0pt" class="Default"><span style="font-family: 宋体; color: windowtext; font-size: 10.5pt">与异常不同的是</span><span style="font-family: 'Times New Roman'; color: windowtext; font-size: 10.5pt">Error</span><span style="font-family: 宋体; color: windowtext; font-size: 10.5pt">及其子类的对象不应被抛出。</span></p>
<p style="margin: 0cm 0cm 0pt" class="Default"><span style="font-family: 'Times New Roman'; color: windowtext; font-size: 10.5pt">Error </span><span style="font-family: 宋体; color: windowtext; font-size: 10.5pt">是</span><span style="font-family: 'Times New Roman'; color: windowtext; font-size: 10.5pt"> Throwable </span><span style="font-family: 宋体; color: windowtext; font-size: 10.5pt">的子类，代表编译时间和系统错误，用于指示合理的应用程序</span><strong><span style="font-family: 宋体; color: red; font-size: 10.5pt">不应该试图捕获</span></strong><span style="font-family: 宋体; color: windowtext; font-size: 10.5pt">的严重问题。大多数这样的错误都是异常条件。虽然</span><span style="font-family: 'Times New Roman'; color: windowtext; font-size: 10.5pt"> ThreadDeath </span><span style="font-family: 宋体; color: windowtext; font-size: 10.5pt">错误是一个</span><span style="font-family: 'Times New Roman'; color: windowtext; font-size: 10.5pt">&#8220;</span><span style="font-family: 宋体; color: windowtext; font-size: 10.5pt">正规</span><span style="font-family: 'Times New Roman'; color: windowtext; font-size: 10.5pt">&#8221;</span><span style="font-family: 宋体; color: windowtext; font-size: 10.5pt">的条件，但它也是</span><span style="font-family: 'Times New Roman'; color: windowtext; font-size: 10.5pt"> Error </span><span style="font-family: 宋体; color: windowtext; font-size: 10.5pt">的子类，因为大多数应用程序都不应该试图捕获它。</span></p>
<p style="margin: 0cm 0cm 0pt" class="Default"><span style="font-family: 宋体; color: windowtext; font-size: 10.5pt">在执行该方法期间，</span><strong><span style="font-family: 宋体; color: red; font-size: 10.5pt">无需在其</span></strong><strong><span style="font-family: 'Times New Roman'; color: red; font-size: 10.5pt"> throws </span></strong><strong><span style="font-family: 宋体; color: red; font-size: 10.5pt">子句中声明可能抛出但是未能捕获</span></strong><span style="font-family: 宋体; color: windowtext; font-size: 10.5pt">的</span><span style="font-family: 'Times New Roman'; color: windowtext; font-size: 10.5pt"> Error </span><span style="font-family: 宋体; color: windowtext; font-size: 10.5pt">的任何子类，因为这些错误可能是再也不会发生的异常条件。</span></p>
<p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-size: small"><span style="font-family: 宋体">它是</span><span style="font-family: Times New Roman">uncheckedExcepiton</span><span style="font-family: 宋体">。</span></span></p>
<img src ="http://www.blogjava.net/balajinima/aggbug/298342.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/balajinima/" target="_blank">李云泽</a> 2009-10-15 11:03 <a href="http://www.blogjava.net/balajinima/articles/298342.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>