diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d60efe4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,437 @@ +Attribution-NonCommercial-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International +Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-NonCommercial-ShareAlike 4.0 International Public License +("Public License"). To the extent this Public License may be +interpreted as a contract, You are granted the Licensed Rights in +consideration of Your acceptance of these terms and conditions, and the +Licensor grants You such rights in consideration of benefits the +Licensor receives from making the Licensed Material available under +these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-NC-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution, NonCommercial, and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. NonCommercial means not primarily intended for or directed towards + commercial advantage or monetary compensation. For purposes of + this Public License, the exchange of the Licensed Material for + other material subject to Copyright and Similar Rights by digital + file-sharing or similar means is NonCommercial provided there is + no payment of monetary compensation in connection with the + exchange. + + l. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + m. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + n. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part, for NonCommercial purposes only; and + + b. produce, reproduce, and Share Adapted Material for + NonCommercial purposes only. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties, including when + the Licensed Material is used other than for NonCommercial + purposes. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-NC-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database for NonCommercial purposes + only; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + including for purposes of Section 3(b); and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/README.md b/README.md index 910d849..d166e19 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ Java SE 6 技術手冊 我在 GitBook 上用這本書前半本 [試排了一個版本](http://caterpillar.gitbooks.io/javase6tutorial/),如果你需要在 GitBook 上取得完整版本,請跟我聯絡! -《Java SE 6 技術手冊》(以及它先前的版本)是以 [我的網站](http://openhome.cc) 中早期學習 Java 的筆記 [JavaGossip1](http://openhome.cc/Gossip/JavaGossip-V1/) 與 [JavaGossip2](http://openhome.cc/Gossip/JavaGossip-V2/) 為基礎,記錄著我學習 Java 的一些心得。 +《Java SE 6 技術手冊》(以及它先前的版本)是以 [我的網站](https://openhome.cc) 中早期學習 Java 的筆記 JavaGossip1 與 JavaGossip2 為基礎,記錄著我學習 Java 的一些心得。 -在 JDK7 問世之後,由於累積不少 Java 教學經驗與想法,為了有一本可以符合我教學所需的教材,因而在為 JDK7 撰寫 Java 書籍時,並不是改版《Java SE 6 技術手冊》,而是重新撰寫了一本 [《Java SE 7 技術手冊》](http://books.gotop.com.tw/bookdetails.aspx?bn=ACL034000)。 +在 JDK7 問世之後,由於累積不少 Java 教學經驗與想法,為了有一本可以符合我教學所需的教材,因而在為 JDK7 撰寫 Java 書籍時,並不是改版《Java SE 6 技術手冊》,而是重新撰寫了一本 [《Java SE 7 技術手冊》](https://play.google.com/store/books/details/%E6%9E%97%E4%BF%A1%E8%89%AF_Java_SE_7%E6%8A%80%E8%A1%93%E6%89%8B%E5%86%8A_%E9%9B%BB%E5%AD%90%E6%9B%B8?id=qscCBAAAQBAJ)。 《Java SE 6 技術手冊》呢?就我目前來看它,真的就像是筆記,然而就因為是筆記,想法、口吻、脈絡甚至範例上,都比較適合新手,在靜靜地留在我硬碟近兩年,我有一天看到它,想說放著也是沒用,不如開放它 ... @@ -16,132 +16,132 @@ Java SE 6 技術手冊 每章的〈網路資源〉被我拿掉了,因為不少鏈結年代久遠已經失效,我懶得一個一個去檢查還有哪些鏈結活著 ... 附錄內容也因較舊而拿掉了,你可以分別參考以下資訊: - [認識 Gradle](http://www.codedata.com.tw/java/understanding-gradle-1-ant/) -- [JUnit](http://openhome.cc/Gossip/JUnit/) +- [JUnit](https://openhome.cc/Gossip/JUnit/) - [MySQL 超新手入門](http://www.codedata.com.tw/database/mysql-tutorial-getting-started/) 原始碼範例都改為 UTF-8 編碼了,因此使用 `javac` 編譯時,記得加上 `-encoding UTF-8`。 -新的 Java 文件基於 JDK8 而撰寫,你可以在 [我的網站](http://openhome.cc) 上的 [Java Gossip](http://openhome.cc/Gossip/Java/) 進行閱讀。 +新的 Java 文件基於 JDK17 而撰寫,你可以在 [我的網站](https://openhome.cc) 上的 [Java](https://openhome.cc/zh-tw/java/) 進行閱讀。 ---------- - [第 1 章 瞭解 Java](docs/CH01.md#%E7%AC%AC-1-%E7%AB%A0-%E7%9E%AD%E8%A7%A3-java) - - [1.1 什麼是 Java](docs/CH01.md#11%E4%BB%80%E9%BA%BC%E6%98%AF-java) - - [1.2 Java 的特性](docs/CH01.md#12java-%E7%9A%84%E7%89%B9%E6%80%A7) - - [1.3 如何學習 Java](docs/CH01.md#13%E5%A6%82%E4%BD%95%E5%AD%B8%E7%BF%92-java) - - [1.4 接下來的主題](docs/CH01.md#14%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [1.1 什麼是 Java](docs/CH01.md#11%E4%BB%80%E9%BA%BC%E6%98%AF-java) + - [1.2 Java 的特性](docs/CH01.md#12java-%E7%9A%84%E7%89%B9%E6%80%A7) + - [1.3 如何學習 Java](docs/CH01.md#13%E5%A6%82%E4%BD%95%E5%AD%B8%E7%BF%92-java) + - [1.4 接下來的主題](docs/CH01.md#14%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 2 章 入門準備](docs/CH02.md#%E7%AC%AC-2-%E7%AB%A0-%E5%85%A5%E9%96%80%E6%BA%96%E5%82%99) - - [2.1 下載、安裝、瞭解 JDK](docs/CH02.md#21-%E4%B8%8B%E8%BC%89%E5%AE%89%E8%A3%9D%E7%9E%AD%E8%A7%A3-jdk) - - [2.2 設定 Path 與 Classpath](docs/CH02.md#22-%E8%A8%AD%E5%AE%9A-path-%E8%88%87-classpath) - - [2.3 第一個 Java 程式](docs/CH02.md#23-%E7%AC%AC%E4%B8%80%E5%80%8B-java-%E7%A8%8B%E5%BC%8F) - - [2.4 選擇開發工具](docs/CH02.md#24-%E9%81%B8%E6%93%87%E9%96%8B%E7%99%BC%E5%B7%A5%E5%85%B7) - - [2.5 接下來的主題](docs/CH02.md#25-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [2.1 下載、安裝、瞭解 JDK](docs/CH02.md#21-%E4%B8%8B%E8%BC%89%E5%AE%89%E8%A3%9D%E7%9E%AD%E8%A7%A3-jdk) + - [2.2 設定 Path 與 Classpath](docs/CH02.md#22-%E8%A8%AD%E5%AE%9A-path-%E8%88%87-classpath) + - [2.3 第一個 Java 程式](docs/CH02.md#23-%E7%AC%AC%E4%B8%80%E5%80%8B-java-%E7%A8%8B%E5%BC%8F) + - [2.4 選擇開發工具](docs/CH02.md#24-%E9%81%B8%E6%93%87%E9%96%8B%E7%99%BC%E5%B7%A5%E5%85%B7) + - [2.5 接下來的主題](docs/CH02.md#25-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 3 章 語法入門](docs/CH03.md#%E7%AC%AC-3-%E7%AB%A0-%E8%AA%9E%E6%B3%95%E5%85%A5%E9%96%80) - - [3.1 第一個 Java 程式](docs/CH03.md#31-%E7%AC%AC%E4%B8%80%E5%80%8B-java-%E7%A8%8B%E5%BC%8F) - - [3.2 在文字模式下與程式互動](docs/CH03.md#32-%E5%9C%A8%E6%96%87%E5%AD%97%E6%A8%A1%E5%BC%8F%E4%B8%8B%E8%88%87%E7%A8%8B%E5%BC%8F%E4%BA%92%E5%8B%95) - - [3.3 資料、運算](docs/CH03.md#33-%E8%B3%87%E6%96%99%E9%81%8B%E7%AE%97) - - [3.4 流程控制](docs/CH03.md#34-%E6%B5%81%E7%A8%8B%E6%8E%A7%E5%88%B6) - - [3.5 接下來的主題](docs/CH03.md#35-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [3.1 第一個 Java 程式](docs/CH03.md#31-%E7%AC%AC%E4%B8%80%E5%80%8B-java-%E7%A8%8B%E5%BC%8F) + - [3.2 在文字模式下與程式互動](docs/CH03.md#32-%E5%9C%A8%E6%96%87%E5%AD%97%E6%A8%A1%E5%BC%8F%E4%B8%8B%E8%88%87%E7%A8%8B%E5%BC%8F%E4%BA%92%E5%8B%95) + - [3.3 資料、運算](docs/CH03.md#33-%E8%B3%87%E6%96%99%E9%81%8B%E7%AE%97) + - [3.4 流程控制](docs/CH03.md#34-%E6%B5%81%E7%A8%8B%E6%8E%A7%E5%88%B6) + - [3.5 接下來的主題](docs/CH03.md#35-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 4 章 從 autoboxing、unboxing 認識物件](docs/CH04.md#%E7%AC%AC-4-%E7%AB%A0-%E5%BE%9E-autoboxingunboxing-%E8%AA%8D%E8%AD%98%E7%89%A9%E4%BB%B6) - - [4.1 關於物件](docs/CH04.md#41-%E9%97%9C%E6%96%BC%E7%89%A9%E4%BB%B6) - - [4.2 自動裝箱、拆箱](docs/CH04.md#42-%E8%87%AA%E5%8B%95%E8%A3%9D%E7%AE%B1%E6%8B%86%E7%AE%B1) - - [4.3 接下來的主題](docs/CH04.md#43-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [4.1 關於物件](docs/CH04.md#41-%E9%97%9C%E6%96%BC%E7%89%A9%E4%BB%B6) + - [4.2 自動裝箱、拆箱](docs/CH04.md#42-%E8%87%AA%E5%8B%95%E8%A3%9D%E7%AE%B1%E6%8B%86%E7%AE%B1) + - [4.3 接下來的主題](docs/CH04.md#43-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 5 章 陣列](docs/CH05.md#%E7%AC%AC-5-%E7%AB%A0-%E9%99%A3%E5%88%97) - - [5.1 一維陣列、二維陣列](docs/CH05.md#51-%E4%B8%80%E7%B6%AD%E9%99%A3%E5%88%97%E4%BA%8C%E7%B6%AD%E9%99%A3%E5%88%97) - - [5.2 進階陣列觀念](docs/CH05.md#52-%E9%80%B2%E9%9A%8E%E9%99%A3%E5%88%97%E8%A7%80%E5%BF%B5) - - [5.3 接下來的主題](docs/CH05.md#53-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [5.1 一維陣列、二維陣列](docs/CH05.md#51-%E4%B8%80%E7%B6%AD%E9%99%A3%E5%88%97%E4%BA%8C%E7%B6%AD%E9%99%A3%E5%88%97) + - [5.2 進階陣列觀念](docs/CH05.md#52-%E9%80%B2%E9%9A%8E%E9%99%A3%E5%88%97%E8%A7%80%E5%BF%B5) + - [5.3 接下來的主題](docs/CH05.md#53-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 6 章 字串](docs/CH06.md#%E7%AC%AC-6-%E7%AB%A0-%E5%AD%97%E4%B8%B2) - - [6.1 認識字串](docs/CH06.md#61-%E8%AA%8D%E8%AD%98%E5%AD%97%E4%B8%B2) - - [6.2 字串進階運用](docs/CH06.md#62-%E5%AD%97%E4%B8%B2%E9%80%B2%E9%9A%8E%E9%81%8B%E7%94%A8) - - [6.3 接下來的主題](docs/CH06.md#63-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [6.1 認識字串](docs/CH06.md#61-%E8%AA%8D%E8%AD%98%E5%AD%97%E4%B8%B2) + - [6.2 字串進階運用](docs/CH06.md#62-%E5%AD%97%E4%B8%B2%E9%80%B2%E9%9A%8E%E9%81%8B%E7%94%A8) + - [6.3 接下來的主題](docs/CH06.md#63-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 7 章 封裝(Encapsulation)](docs/CH07.md#%E7%AC%AC-7-%E7%AB%A0-%E5%B0%81%E8%A3%9Dencapsulation) - - [7.1 定義類別(Class)](docs/CH07.md#71-%E5%AE%9A%E7%BE%A9%E9%A1%9E%E5%88%A5class) - - [7.2 關於方法](docs/CH07.md#72-%E9%97%9C%E6%96%BC%E6%96%B9%E6%B3%95) - - [7.3 接下來的主題](docs/CH07.md#73-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [7.1 定義類別(Class)](docs/CH07.md#71-%E5%AE%9A%E7%BE%A9%E9%A1%9E%E5%88%A5class) + - [7.2 關於方法](docs/CH07.md#72-%E9%97%9C%E6%96%BC%E6%96%B9%E6%B3%95) + - [7.3 接下來的主題](docs/CH07.md#73-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 8 章 繼承(Inheritance)、多型(Polymorphism)](docs/CH08.md#%E7%AC%AC-8-%E7%AB%A0-%E7%B9%BC%E6%89%BFinheritance%E5%A4%9A%E5%9E%8Bpolymorphism) - - [8.1 繼承](docs/CH08.md#81-%E7%B9%BC%E6%89%BF) - - [8.2 多型(Polymorphism)](docs/CH08.md#82-%E5%A4%9A%E5%9E%8Bpolymorphism) - - [8.3 接下來的主題](docs/CH08.md#83-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [8.1 繼承](docs/CH08.md#81-%E7%B9%BC%E6%89%BF) + - [8.2 多型(Polymorphism)](docs/CH08.md#82-%E5%A4%9A%E5%9E%8Bpolymorphism) + - [8.3 接下來的主題](docs/CH08.md#83-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 9 章 管理類別檔案](docs/CH09.md#%E7%AC%AC-9-%E7%AB%A0-%E7%AE%A1%E7%90%86%E9%A1%9E%E5%88%A5%E6%AA%94%E6%A1%88) - - [9.1 內部類別](docs/CH09.md#91-%E5%85%A7%E9%83%A8%E9%A1%9E%E5%88%A5) - - [9.2 package 與 import](docs/CH09.md#92-package-%E8%88%87-import) - - [9.3 接下來的主題](docs/CH09.md#93-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [9.1 內部類別](docs/CH09.md#91-%E5%85%A7%E9%83%A8%E9%A1%9E%E5%88%A5) + - [9.2 package 與 import](docs/CH09.md#92-package-%E8%88%87-import) + - [9.3 接下來的主題](docs/CH09.md#93-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 10 章 例外處理(Exception Handling)](docs/CH10.md#%E7%AC%AC-10-%E7%AB%A0-%E4%BE%8B%E5%A4%96%E8%99%95%E7%90%86exception-handling) - - [10.1 例外處理入門](docs/CH10.md#101-%E4%BE%8B%E5%A4%96%E8%99%95%E7%90%86%E5%85%A5%E9%96%80) - - [10.2 受檢例外(Checked Exception)、執行時期例外 + - [10.1 例外處理入門](docs/CH10.md#101-%E4%BE%8B%E5%A4%96%E8%99%95%E7%90%86%E5%85%A5%E9%96%80) + - [10.2 受檢例外(Checked Exception)、執行時期例外 (Runtime Exception)](docs/CH10.md#102-%E5%8F%97%E6%AA%A2%E4%BE%8B%E5%A4%96checked-exception%E5%9F%B7%E8%A1%8C%E6%99%82%E6%9C%9F%E4%BE%8B%E5%A4%96runtime-exception) - - [10.3 throw、throws](docs/CH10.md#103-throwthrows) - - [10.4 例外的繼承架構](docs/CH10.md#104-%E4%BE%8B%E5%A4%96%E7%9A%84%E7%B9%BC%E6%89%BF%E6%9E%B6%E6%A7%8B) - - [10.5 斷言(Assertion)](docs/CH10.md#105-%E6%96%B7%E8%A8%80assertion) - - [10.6 接下來的主題](docs/CH10.md#106-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [10.3 throw、throws](docs/CH10.md#103-throwthrows) + - [10.4 例外的繼承架構](docs/CH10.md#104-%E4%BE%8B%E5%A4%96%E7%9A%84%E7%B9%BC%E6%89%BF%E6%9E%B6%E6%A7%8B) + - [10.5 斷言(Assertion)](docs/CH10.md#105-%E6%96%B7%E8%A8%80assertion) + - [10.6 接下來的主題](docs/CH10.md#106-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 11 章 列舉型態(Enumerated Types)](docs/CH11.md#%E7%AC%AC-11-%E7%AB%A0-%E5%88%97%E8%88%89%E5%9E%8B%E6%85%8Benumerated-types) - - [11.1 常數設置與列舉型態](docs/CH11.md#111-%E5%B8%B8%E6%95%B8%E8%A8%AD%E7%BD%AE%E8%88%87%E5%88%97%E8%88%89%E5%9E%8B%E6%85%8B) - - [11.2 定義列舉型態](docs/CH11.md#112-%E5%AE%9A%E7%BE%A9%E5%88%97%E8%88%89%E5%9E%8B%E6%85%8B) - - [11.3 接下來的主題](docs/CH11.md#113-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [11.1 常數設置與列舉型態](docs/CH11.md#111-%E5%B8%B8%E6%95%B8%E8%A8%AD%E7%BD%AE%E8%88%87%E5%88%97%E8%88%89%E5%9E%8B%E6%85%8B) + - [11.2 定義列舉型態](docs/CH11.md#112-%E5%AE%9A%E7%BE%A9%E5%88%97%E8%88%89%E5%9E%8B%E6%85%8B) + - [11.3 接下來的主題](docs/CH11.md#113-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 12 章 泛型(Generics)](docs/CH12.md#%E7%AC%AC-12-%E7%AB%A0-%E6%B3%9B%E5%9E%8B) - - [12.1 泛型入門](docs/CH12.md#121-%E6%B3%9B%E5%9E%8B%E5%85%A5%E9%96%80) - - [12.2 泛型進階語法](docs/CH12.md#122-%E6%B3%9B%E5%9E%8B%E9%80%B2%E9%9A%8E%E8%AA%9E%E6%B3%95) - - [12.3 接下來的主題](docs/CH12.md#123-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [12.1 泛型入門](docs/CH12.md#121-%E6%B3%9B%E5%9E%8B%E5%85%A5%E9%96%80) + - [12.2 泛型進階語法](docs/CH12.md#122-%E6%B3%9B%E5%9E%8B%E9%80%B2%E9%9A%8E%E8%AA%9E%E6%B3%95) + - [12.3 接下來的主題](docs/CH12.md#123-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 13 章 物件容器(Container)](docs/CH13.md#%E7%AC%AC-13-%E7%AB%A0-%E7%89%A9%E4%BB%B6%E5%AE%B9%E5%99%A8container) - - [13.1 Collection 類](docs/CH13.md#131-collection-%E9%A1%9E) - - [13.2 Map 類](docs/CH13.md#132-map-%E9%A1%9E) - - [13.3 接下來的主題](docs/CH13.md#133-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [13.1 Collection 類](docs/CH13.md#131-collection-%E9%A1%9E) + - [13.2 Map 類](docs/CH13.md#132-map-%E9%A1%9E) + - [13.3 接下來的主題](docs/CH13.md#133-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 14 章 輸入輸出](docs/CH14.md#%E7%AC%AC-14-%E7%AB%A0-%E8%BC%B8%E5%85%A5%E8%BC%B8%E5%87%BA) - - [14.1 檔案](docs/CH14.md#141-%E6%AA%94%E6%A1%88) - - [14.2 位元串流](docs/CH14.md#142-%E4%BD%8D%E5%85%83%E4%B8%B2%E6%B5%81) - - [14.3 字元串流](docs/CH14.md#143-%E5%AD%97%E5%85%83%E4%B8%B2%E6%B5%81) - - [14.4 接下來的主題](docs/CH14.md#144-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [14.1 檔案](docs/CH14.md#141-%E6%AA%94%E6%A1%88) + - [14.2 位元串流](docs/CH14.md#142-%E4%BD%8D%E5%85%83%E4%B8%B2%E6%B5%81) + - [14.3 字元串流](docs/CH14.md#143-%E5%AD%97%E5%85%83%E4%B8%B2%E6%B5%81) + - [14.4 接下來的主題](docs/CH14.md#144-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 15 章 執行緒(Thread)](docs/CH15.md#%E7%AC%AC-15-%E7%AB%A0-%E5%9F%B7%E8%A1%8C%E7%B7%92thread) - - [15.1 執行緒入門](docs/CH15.md#151-%E5%9F%B7%E8%A1%8C%E7%B7%92%E5%85%A5%E9%96%80) - - [15.2 同步化(synchronized)議題](docs/CH15.md#152-%E5%90%8C%E6%AD%A5%E5%8C%96synchronized%E8%AD%B0%E9%A1%8C) - - [15.3 concurrent 套件新增類別](docs/CH15.md#153-concurrent-%E5%A5%97%E4%BB%B6%E6%96%B0%E5%A2%9E%E9%A1%9E%E5%88%A5) - - [15.4 接下來的主題](docs/CH15.md#154-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [15.1 執行緒入門](docs/CH15.md#151-%E5%9F%B7%E8%A1%8C%E7%B7%92%E5%85%A5%E9%96%80) + - [15.2 同步化(synchronized)議題](docs/CH15.md#152-%E5%90%8C%E6%AD%A5%E5%8C%96synchronized%E8%AD%B0%E9%A1%8C) + - [15.3 concurrent 套件新增類別](docs/CH15.md#153-concurrent-%E5%A5%97%E4%BB%B6%E6%96%B0%E5%A2%9E%E9%A1%9E%E5%88%A5) + - [15.4 接下來的主題](docs/CH15.md#154-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 16 章 反射(Reflection)](docs/CH16.md#%E7%AC%AC-16-%E7%AB%A0-%E5%8F%8D%E5%B0%84reflection) - - [16.1 類別載入與檢視](docs/CH16.md#161-%E9%A1%9E%E5%88%A5%E8%BC%89%E5%85%A5%E8%88%87%E6%AA%A2%E8%A6%96) - - [16.2 使用反射生成與操作物件](docs/CH16.md#162-%E4%BD%BF%E7%94%A8%E5%8F%8D%E5%B0%84%E7%94%9F%E6%88%90%E8%88%87%E6%93%8D%E4%BD%9C%E7%89%A9%E4%BB%B6) - - [16.3 接下來的主題](docs/CH16.md#163-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [16.1 類別載入與檢視](docs/CH16.md#161-%E9%A1%9E%E5%88%A5%E8%BC%89%E5%85%A5%E8%88%87%E6%AA%A2%E8%A6%96) + - [16.2 使用反射生成與操作物件](docs/CH16.md#162-%E4%BD%BF%E7%94%A8%E5%8F%8D%E5%B0%84%E7%94%9F%E6%88%90%E8%88%87%E6%93%8D%E4%BD%9C%E7%89%A9%E4%BB%B6) + - [16.3 接下來的主題](docs/CH16.md#163-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 17 章 Annotation](docs/CH17.md#%E7%AC%AC-17-%E7%AB%A0-annotation) - - [17.1 Annotation](docs/CH17.md#171-annotation) - - [17.2 meta-annotation](docs/CH17.md#172-meta-annotation) - - [17.3 接下來的主題](docs/CH17.md#173-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [17.1 Annotation](docs/CH17.md#171-annotation) + - [17.2 meta-annotation](docs/CH17.md#172-meta-annotation) + - [17.3 接下來的主題](docs/CH17.md#173-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 18 章 捨遺補缺](docs/CH18.md#%E7%AC%AC-18-%E7%AB%A0-%E6%8D%A8%E9%81%BA%E8%A3%9C%E7%BC%BA) - - [18.1 日期、時間](docs/CH18.md#181-%E6%97%A5%E6%9C%9F%E6%99%82%E9%96%93) - - [18.2 日誌(Logging)](docs/CH18.md#182-%E6%97%A5%E8%AA%8Clogging) - - [18.3 訊息綁定](docs/CH18.md#183-%E8%A8%8A%E6%81%AF%E7%B6%81%E5%AE%9A) - - [18.4 接下來的主題](docs/CH18.md#184-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [18.1 日期、時間](docs/CH18.md#181-%E6%97%A5%E6%9C%9F%E6%99%82%E9%96%93) + - [18.2 日誌(Logging)](docs/CH18.md#182-%E6%97%A5%E8%AA%8Clogging) + - [18.3 訊息綁定](docs/CH18.md#183-%E8%A8%8A%E6%81%AF%E7%B6%81%E5%AE%9A) + - [18.4 接下來的主題](docs/CH18.md#184-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) -- [第 19 章 專題製作 - 文字編輯器](docs/CH19.md#%E7%AC%AC-19-%E7%AB%A0-%E5%B0%88%E9%A1%8C%E8%A3%BD%E4%BD%9C---%E6%96%87%E5%AD%97%E7%B7%A8%E8%BC%AF%E5%99%A8) - - [19.1 產品生命週期](docs/CH19.md#191-%E7%94%A2%E5%93%81%E7%94%9F%E5%91%BD%E9%80%B1%E6%9C%9F) - - [19.2 Swing 入門](docs/CH19.md#192-swing-%E5%85%A5%E9%96%80) - - [19.3 事件處理](docs/CH19.md#193-%E4%BA%8B%E4%BB%B6%E8%99%95%E7%90%86) - - [19.4 文字編輯與儲存](docs/CH19.md#194-%E6%96%87%E5%AD%97%E7%B7%A8%E8%BC%AF%E8%88%87%E5%84%B2%E5%AD%98) - - [19.5 Executable Jar 的製作](docs/CH19.md#195-executable-jar-%E7%9A%84%E8%A3%BD%E4%BD%9C) - - [19.6 接下來的主題](docs/CH19.md#196-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) +- [第 19 章 專題製作 - 文字編輯器](docs/CH19.md#%E7%AC%AC-19-%E7%AB%A0-%E5%B0%88%E9%A1%8C%E8%A3%BD%E4%BD%9C---%E6%96%87%E5%AD%97%E7%B7%A8%E8%BC%AF%E5%99%A8) + - [19.1 產品生命週期](docs/CH19.md#191-%E7%94%A2%E5%93%81%E7%94%9F%E5%91%BD%E9%80%B1%E6%9C%9F) + - [19.2 Swing 入門](docs/CH19.md#192-swing-%E5%85%A5%E9%96%80) + - [19.3 事件處理](docs/CH19.md#193-%E4%BA%8B%E4%BB%B6%E8%99%95%E7%90%86) + - [19.4 文字編輯與儲存](docs/CH19.md#194-%E6%96%87%E5%AD%97%E7%B7%A8%E8%BC%AF%E8%88%87%E5%84%B2%E5%AD%98) + - [19.5 Executable Jar 的製作](docs/CH19.md#195-executable-jar-%E7%9A%84%E8%A3%BD%E4%BD%9C) + - [19.6 接下來的主題](docs/CH19.md#196-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 20 章 JDBC 入門](docs/CH20.md#%E7%AC%AC-20-%E7%AB%A0-jdbc-%E5%85%A5%E9%96%80) - - [20.1 使用 JDBC 連接資料庫](docs/CH20.md#201-%E4%BD%BF%E7%94%A8-jdbc-%E9%80%A3%E6%8E%A5%E8%B3%87%E6%96%99%E5%BA%AB) - - [20.2 使用 JDBC 進行資料操作](docs/CH20.md#202-%E4%BD%BF%E7%94%A8-jdbc-%E9%80%B2%E8%A1%8C%E8%B3%87%E6%96%99%E6%93%8D%E4%BD%9C) - - [20.3 接下來的主題](docs/CH20.md#203-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [20.1 使用 JDBC 連接資料庫](docs/CH20.md#201-%E4%BD%BF%E7%94%A8-jdbc-%E9%80%A3%E6%8E%A5%E8%B3%87%E6%96%99%E5%BA%AB) + - [20.2 使用 JDBC 進行資料操作](docs/CH20.md#202-%E4%BD%BF%E7%94%A8-jdbc-%E9%80%B2%E8%A1%8C%E8%B3%87%E6%96%99%E6%93%8D%E4%BD%9C) + - [20.3 接下來的主題](docs/CH20.md#203-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) - [第 21 章 Java SE 6 新功能簡介](docs/CH21.md#java-se-6-%E6%96%B0%E5%8A%9F%E8%83%BD%E7%B0%A1%E4%BB%8B) - - [21.1 Java SE 6 基本新功能](docs/CH21.md#211-java-se-6-%E5%9F%BA%E6%9C%AC%E6%96%B0%E5%8A%9F%E8%83%BD) - - [21.2 Apache Derby、JDBC 4.0](docs/CH21.md#2121-%E4%BD%BF%E7%94%A8-apache-derby) - - [21.3 接下來的主題](docs/CH21.md#213-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) + - [21.1 Java SE 6 基本新功能](docs/CH21.md#211-java-se-6-%E5%9F%BA%E6%9C%AC%E6%96%B0%E5%8A%9F%E8%83%BD) + - [21.2 Apache Derby、JDBC 4.0](docs/CH21.md#2121-%E4%BD%BF%E7%94%A8-apache-derby) + - [21.3 接下來的主題](docs/CH21.md#213-%E6%8E%A5%E4%B8%8B%E4%BE%86%E7%9A%84%E4%B8%BB%E9%A1%8C) diff --git a/docs/CH01.md b/docs/CH01.md index 0b7deae..dc562e1 100644 --- a/docs/CH01.md +++ b/docs/CH01.md @@ -122,7 +122,7 @@ Java 至今日主要發展出三個領域的應用平台:Java Platform, Standa 隨著 Java 的應用領域越來越廣,並逐漸擴及至各級應用軟體的開發,Sun 公司在 1999 年 6 月美國舊金山的 Java One 大會上,公佈了新的 Java 體系架構,該架構根據不同級別的應用開發區分了不同的應用版本: J2SE、J2EE 與 J2ME。這些是當時的名稱,為配合 Java SE 6 中的名稱,以下則稱 為Java SE、JavaEE 與 Java ME。 - Java EE 以 Java SE 的基礎,定義了一系列的服務、API、協定等,適用於開發分散式、多層式(Multi-tiered)、以元件為基礎、以Web為基礎的應用程式,整個 ava EE 的體系是相當龐大的,比較為人所熟悉的技術像是 JSP、Servlet、Enterprise JavaBeans(EJB)、Java Remote Method Invocation(RMI)等,當中的每個服務或技術都可以使用專書進行說明,所以並不是本書說明的範圍,但可以肯定的是,您必須在 Java SE 上奠定良好的基礎再來學習 Java EE 的開發。 + Java EE 以 Java SE 的基礎,定義了一系列的服務、API、協定等,適用於開發分散式、多層式(Multi-tiered)、以元件為基礎、以Web為基礎的應用程式,整個 Java EE 的體系是相當龐大的,比較為人所熟悉的技術像是 JSP、Servlet、Enterprise JavaBeans(EJB)、Java Remote Method Invocation(RMI)等,當中的每個服務或技術都可以使用專書進行說明,所以並不是本書說明的範圍,但可以肯定的是,您必須在 Java SE 上奠定良好的基礎再來學習 Java EE 的開發。 - Java Platform, Micro Edition (Java ME) diff --git a/docs/CH03.md b/docs/CH03.md index bc16b89..274d8aa 100644 --- a/docs/CH03.md +++ b/docs/CH03.md @@ -1471,6 +1471,6 @@ continue 配合標籤,可以自由的跳至任何一層 for 迴圈,您可以 程式語言本質上就是語言,就像中文、英文一樣,要學習語言必先學習文法,這個章節所介紹的就是 Java 語言的基本文法(語法),接下來就是多使用這種語言以求熟悉這個語言,多找些題目來練習是必要的,在練習的同時培養使用 Java 語言的邏輯來思考問題,您可以在我的網站上找到一些常見的程式題目來作練習: -- http://openhome.cc/Gossip/AlgorithmGossip/ +- https://openhome.cc/Gossip/AlgorithmGossip/ 接下來我會介紹 Java SE 下提供的一些標準物件如何使用,在您正式瞭解 Java 的物件導向程式設計之前,您可以先將物件理解為一個現成的工具,Java SE 下提供了許多標準工具可以使用,熟悉這些工具的使用也是學習 Java 的必備功課。 \ No newline at end of file diff --git a/docs/CH06.md b/docs/CH06.md index 301a36f..e666a58 100644 --- a/docs/CH06.md +++ b/docs/CH06.md @@ -310,7 +310,7 @@ public class AppendStringTest { for(int i = 0; i < 10000; i++) builder.append(i); -使用 StringBuilder 最後若要輸出字串結果,可以呼叫其 toString() 方法,您可以使用 length() 方法得知目前物件中的字元長度,而 capacity() 可傳回該物件目前可容納的字元容量,另外 StringBuilder 還有像是 insert() 方法可以將字元插入指定的位置,如果該位置以後有字元,則將所有的字元往後移;deleteChar() 方法可以刪除指定位置的字元,而 reserve() 方法可以反轉字串,詳細的使用可以查詢看看 java.lang.StringBuilder 的 API 文件說明。 +使用 StringBuilder 最後若要輸出字串結果,可以呼叫其 toString() 方法,您可以使用 length() 方法得知目前物件中的字元長度,而 capacity() 可傳回該物件目前可容納的字元容量,另外 StringBuilder 還有像是 insert() 方法可以將字元插入指定的位置,如果該位置以後有字元,則將所有的字元往後移;deleteChar() 方法可以刪除指定位置的字元,而 reverse() 方法可以反轉字串,詳細的使用可以查詢看看 java.lang.StringBuilder 的 API 文件說明。 StringBuilder 是 J2SE 5.0 才新增的類別,在 J2SE 5.0 之前的版本若有相同的需求,是使用 java.lang.StringBuffer,事實上,StringBuilder 被設計為與 StringBuffer 具有相同的操作介面,在單機非「多執行緒」(Multithread)的情況下使用 StringBuilder 會有較好的效率,因為 StringBuilder 沒有處理「同步」(Synchronized)問題;StringBuffer 則會處理同步問題,如果您的 StringBuilder 會在多執行緒下被操作,則要改用 StringBuffer,讓物件自行管理同步問題,關於多執行緒的觀念,會在第 15 章詳細說明。 @@ -414,14 +414,14 @@ Java 在 J2SE 1.4 之後開始支援正則表示式,您可以在 API 文件的 對於一些簡單的字元比對,例如 1 到 9、A-Z 等,您可以使用預先定義的符號來表示,表 6.4 列出幾個常用的字元比對符號。 #### **表 6.4 字元比對符號** -| 方法 | 說明 -|:-- |:- -| . | 符合任一字元 -| \d | 符合 0 到 9 任一個數字字元 -| \D | 符合 0-9 以外的字元 -| \s | 符合 '\t'、'\n'、'\x0B'、'\f'、'\r' 等空白字元 -| \w | 符合 a 到 z、A 到 Z、0 到 9 等字元,也就是數字或是字母都符合 -| \W | 符合 a 到 z、A 到 Z、0 到 9 等之外的字元,也就是除數字與字母外都符合 +| 方法 | 說明 | +|:----- |:-- | +| . | 符合任一字元 | +| \d | 符合 0 到 9 任一個數字字元 | +| \D | 符合 0-9 以外的字元 | +| \s | 符合 '\t'、'\n'、'\x0B'、'\f'、'\r' 等空白字元 | +| \w | 符合 a 到 z、A 到 Z、0 到 9 等字元,也就是數字或是字母都符合 | +| \W | 符合 a 到 z、A 到 Z、0 到 9 等之外的字元,也就是除數字與字母外都符合 | 舉例來說,如果有一字串 "abcdebcadxbc",使用 ".bc" 來作比對的話,符合的子字串有 "abc"、"ebc"、"xbc" 三個;如果使用 "..cd",則符合的子字串只有 "abcd",範例 6.9證實這個說明。 @@ -457,28 +457,28 @@ public class RegularExpressionDemo { 您也可以使用「字元類」(Character class)來比較一組字元範圍,表 6.5 示範了幾個字元類的設定方式。 #### **表 6.5 字元類範例** -| 範例 | 作用 -|:- |:- -| [abc] | 符合 a、b 或 c -| [^abc] | 符合「a 或 b 或 c」之外的字元 -| [a-zA-Z] | 符合 a 到 z 或者是 A 到 Z 的字元 -| [a-d[m-p]] | a 到 d 或者是m 到 p,也可以寫成 [a-dm-p] -| [a-z&&[def]] | a 到 z 並且是 d 或 e 或 f,結果就是 d 或 e 或 f 可以符合 -| [a-z&&[^bc]] | a 到 z 並且不是 b 或 c -| [a-z&&[^m-p]] | a 到 z 並且不是 m 到 p +| 範例 | 作用 | +|:--------------|:--| +| [abc] | 符合 a、b 或 c | +| [^abc] | 符合「a 或 b 或 c」之外的字元 | +| [a-zA-Z] | 符合 a 到 z 或者是 A 到 Z 的字元 | +| [a-d[m-p]] | a 到 d 或者是m 到 p,也可以寫成 [a-dm-p] | +| [a-z&&[def]] | a 到 z 並且是 d 或 e 或 f,結果就是 d 或 e 或 f 可以符合 | +| [a-z&&[^bc]] | a 到 z 並且不是 b 或 c | +| [a-z&&[^m-p]] | a 到 z 並且不是 m 到 p | 指定一個字元之外,您也可以加上「貪婪量詞」(Greedy quantifiers)來指定字元可能出現的次數,表 6.6 示範了幾個例子。 #### **表 6.6 貪婪量詞範例** -| 範例 | 作用 -|:- |:- -| X? | X 可出現一次或完全沒有 -| X* | X 可出現零次或多次 -| X+ | X 可出現一次或多次 -| X{n} | X 可出現 n 次 -| X{n,} | X 可出現至少n次 -| X{n, m} | X 可出現至少 n 次,但不超過 m 次 -| X? | X 可出現一次或完全沒有 +| 範例 | 作用 | +|:--------- |:-- | +| X? | X 可出現一次或完全沒有 | +| X* | X 可出現零次或多次 | +| X+ | X 可出現一次或多次 | +| X{n} | X 可出現 n 次 | +| X{n,} | X 可出現至少n次 | +| X{n, m} | X 可出現至少 n 次,但不超過 m 次 | +| X? | X 可出現一次或完全沒有 | 另外還有 Reluctant quantifiers、Possessive quantifiers 等的指定,您可以自行參考 java.util.regex.Pattern 類別 API 文件中的說明。 @@ -624,4 +624,4 @@ public class RegularExpressionDemo2 { - 瞭解使用 '==' 與 equals() 方法比較兩個字串時的不同點 - 瞭解 '+' 使用於字串串接上的負擔 -到目前為止,您僅止於使用物件的階段,接下來就要進入重頭戲了,從下一個章節開始,您將會逐步接觸 Java 中物件導向程式設計的領域,瞭解 Java 中的何種特性可以支援物件導向設計。 \ No newline at end of file +到目前為止,您僅止於使用物件的階段,接下來就要進入重頭戲了,從下一個章節開始,您將會逐步接觸 Java 中物件導向程式設計的領域,瞭解 Java 中的何種特性可以支援物件導向設計。 diff --git a/docs/CH07.md b/docs/CH07.md index d1d6244..be61983 100644 --- a/docs/CH07.md +++ b/docs/CH07.md @@ -131,7 +131,7 @@ public class Account {
Account account1 = new Account(); Account account2 = new Account("123-4567", 100.0);- 在上面的程式片段中宣告了 account1 與 account2 兩個 Account 型態的參考名稱,並讓它們分別參考至物件,account1 所參考的物件在建立時並不指定任何引數,所以根據之前對 Account 類別的定義,account1 所參考物件的 balance 將設定為 0.0,accountNumber 設定為 "empty";accont2 所參考的物件在新建時則給定兩個引數,所以 account2 所參考物件的 balance 設定為 100.0,而 accountNumber 設定為 "empty"。 + 在上面的程式片段中宣告了 account1 與 account2 兩個 Account 型態的參考名稱,並讓它們分別參考至物件,account1 所參考的物件在建立時並不指定任何引數,所以根據之前對 Account 類別的定義,account1 所參考物件的 balance 將設定為 0.0,accountNumber 設定為 "empty";account2 所參考的物件在新建時則給定兩個引數,所以 account2 所參考物件的 balance 設定為 100.0,而 accountNumber 設定為 "123-4567"。 要透過公開成員來操作物件或取得物件資訊的話,可以在物件名稱後加上「.」運算子來進行,例如:
account1.getBalance(); @@ -359,7 +359,7 @@ public class SafeArrayDemo { ### 7.1.5 關於 this -請您回顧一下範例 7.1,在範例的 Account 類別中定義有 accountNumber 與 balance 成員,當您使用 Account 類別新增兩個物件並使用 account1 與 account2 來參考時,account1 與 account2 所參考的物件會各自擁有自己的 accountNumber 與 balance 資料成員,然而方法成員在記憶體中會只有一份,當您使用 account1.getBalance() 與 account1.getBalance() 方法取回 balance 的值時,既然類別的方法成員只有一份,getBalance() 時如何知道它傳回的 balance 是 account1 所參考物件的 balance,還是 account2 所參考物件的 balance 呢? +請您回顧一下範例 7.1,在範例的 Account 類別中定義有 accountNumber 與 balance 成員,當您使用 Account 類別新增兩個物件並使用 account1 與 account2 來參考時,account1 與 account2 所參考的物件會各自擁有自己的 accountNumber 與 balance 資料成員,然而方法成員在記憶體中會只有一份,當您使用 account1.getBalance() 與 account2.getBalance() 方法取回 balance 的值時,既然類別的方法成員只有一份,getBalance() 時如何知道它傳回的 balance 是 account1 所參考物件的 balance,還是 account2 所參考物件的 balance 呢?  @@ -388,7 +388,7 @@ public class SafeArrayDemo { public Account(String number, double money) { accountNumber = number; // 實際等於this.accountNumber = number; - this.balance = money; // 實際等於this.balance = money; + balance = money; // 實際等於this.balance = money; } this 除了用來參考至呼叫方法的實際物件之外,還有一種可以帶引數的用法,主要是用於呼叫建構方法,而避免直接以建構方法的名稱來呼叫,例如在下面的程式片段中,當使用無參數的建構方法 Ball() 時,它會呼叫有參數的建構方法: @@ -716,7 +716,7 @@ public class UseRecursion { > **良葛格的話匣子** 在我的網站上有很多題目可以作練習,也不乏有遞迴求解的例子: > -> - http://openhome.cc/Gossip/AlgorithmGossip/ +> - https://openhome.cc/Gossip/AlgorithmGossip/ ### 7.2.4 垃圾收集 @@ -737,7 +737,10 @@ public class UseRecursion { 圖 7.5 沒有被名稱參考到的物件資源將會被回收 範例7.13簡單的示範了finalize()方法的使用。 + 範例7.13 GcTest.java + +```java public class GcTest { private String name; @@ -750,7 +753,8 @@ public class GcTest { protected void finalize() { System.out.println(name + "被回收"); } -}. +} +``` 使用範例 7.14來作個簡單的執行測試。 @@ -780,12 +784,12 @@ public class UseGC { 在程式中您故意加上無窮迴圈,以讓垃圾收集在程式結束前有機會執行,藉以瞭解垃圾收集確實會運作,程式執行結果如下所示: 請按Ctrl + C終止程式........ - bject1建立 - bject2建立 - bject3建立 - bject3被回收 - bject2被回收 - bject1被回收 + object1建立 + object2建立 + object3建立 + object3被回收 + object2被回收 + object1被回收 ## 7.3 接下來的主題 @@ -798,4 +802,4 @@ public class UseGC { - 瞭解靜態(static)成員的作用 - 瞭解如何重載方法 -在物件導向程式設計中,只是單純的封裝物件特性只能解決一部份的問題,有時候您必須提取出物件的共同抽象特性並加以定義,然後再「繼承」(Inherit)抽象的定義對個別的物件加以實作,有時您必須繼承某個類別並重新改寫類別中的某些定義,這在下一個章節中都會加以說明,並且您也將瞭解「抽象類別」(Abstract class)與「介面」(Interface)的不同。 \ No newline at end of file +在物件導向程式設計中,只是單純的封裝物件特性只能解決一部份的問題,有時候您必須提取出物件的共同抽象特性並加以定義,然後再「繼承」(Inherit)抽象的定義對個別的物件加以實作,有時您必須繼承某個類別並重新改寫類別中的某些定義,這在下一個章節中都會加以說明,並且您也將瞭解「抽象類別」(Abstract class)與「介面」(Interface)的不同。 diff --git a/docs/CH08.md b/docs/CH08.md index d811cb2..01f7ee7 100644 --- a/docs/CH08.md +++ b/docs/CH08.md @@ -254,7 +254,7 @@ SafeArray 與 SimpleArray 擁有一致的操作介面,因為 SafeArray 是 Sim public Bird(String name) { this.name = name; } - public Bird getCopied { + public Bird getCopied() { return new Bird(name); } } @@ -643,7 +643,7 @@ public class CloneDemo { public class ConcreteCircle { private double radius; - public void setRedius(int radius) { this.radius = radius; } + public void setRadius(double radius) { this.radius = radius; } public double getRadius() { return radius; } public void render() { System.out.printf("畫一個半徑 %f 的實心圓\n", getRadius()); @@ -652,7 +652,7 @@ public class CloneDemo { public class HollowCircle { private double radius; - public void setRedius(int radius) { this.radius = radius; } + public void setRadius(double radius) { this.radius = radius; } public double getRadius() { return radius; } public void render() { System.out.printf("畫一個半徑 %f 的空心圓\n", getRadius()); @@ -666,7 +666,7 @@ public class CloneDemo { public abstract class AbstractCircle { protected double radius; - public void setRedius(int radius) { this.radius = radius; } + public void setRadius(double radius) { this.radius = radius; } public double getRadius() { return radius; } public abstract void render(); @@ -836,7 +836,7 @@ public class GuessGameDemo { > > 我的網站上也整理有一些設計模式相關資料,並附有簡單的Java程式實例,您也可以一併參考: > -> - http://openhome.cc/Gossip/DesignPattern/ +> - https://openhome.cc/Gossip/DesignPattern/ ### 8.2.4 介面(Interface) diff --git a/docs/CH09.md b/docs/CH09.md index 29159f2..5c5f419 100644 --- a/docs/CH09.md +++ b/docs/CH09.md @@ -12,7 +12,7 @@ ### 9.1.1 成員內部類別、區域內部類別 -使用內部類別有幾個好處,其一是內部類別可以直接存取其所在類別中的私用(private)成員;其二是當某個 Slav e類別完全只服務於一個 Master 類別時,您可以將之設定為內部類別,如此使用 Master 類別的人就不用知道 Slave 的存在;再者是像在「靜態工廠」(Static factory)模式中,對呼叫靜態方法的物件隱藏返回物件的實作細節或產生方式。 +使用內部類別有幾個好處,其一是內部類別可以直接存取其所在類別中的私用(private)成員;其二是當某個 Slave類別完全只服務於一個 Master 類別時,您可以將之設定為內部類別,如此使用 Master 類別的人就不用知道 Slave 的存在;再者是像在「靜態工廠」(Static factory)模式中,對呼叫靜態方法的物件隱藏返回物件的實作細節或產生方式。 先來介紹成員內部類別,基本上是在一個類別中直接宣告另一個類別,例如: @@ -114,7 +114,7 @@ public class PointShow { // 實作 } -一個使用內部匿名類別的例子如範例7.3所示,您直接繼承 Object 類別定義一個匿名類別,重新定義 toString() 方法,並使用匿名類別直接產生一個物件。 +一個使用內部匿名類別的例子如範例9.3所示,您直接繼承 Object 類別定義一個匿名類別,重新定義 toString() 方法,並使用匿名類別直接產生一個物件。 #### **範例 9.3 AnonymousClassDemo.java** ```java @@ -197,7 +197,7 @@ public class PackageDemo { 在編譯時您使用以下的指令指定編譯過後的類別檔案儲存目錄,'.'表示建立在目前的工作位置: - javac -d . UsePackage.java + javac -d . PackageDemo.java 編譯完成之後,在目前的工作位置中會出現 onlyfun 目錄,而 onlyfun 目錄下會有個 caterpillar 目錄,而 caterpillar 目錄下則有一個 PackageDemo.class 檔案,在編譯完成之後,"package" 的設定會成為類別名稱的一部份,也就是完整的類別名稱是 onlyfun.caterpillar.PackageDemo,所以在執行時要這麼下指令以指定類別名稱: @@ -497,7 +497,7 @@ public class ImportStaticDemo { 如果您想要 "import" 類別下所有的靜態成員,也可以使用 '\*' 字元,例如將範例 9.10 中的 "import static" 改為以下也是可行的: - `import static java.util.Arrays.*; + import static java.util.Arrays.*; "import static" 語法可以讓您少打一些字,但是您要注意名稱衝突問題,對於名稱衝突編譯器可能透過以下的幾個方法來解決: diff --git a/docs/CH10.md b/docs/CH10.md index bff504a..3e4ea4d 100644 --- a/docs/CH10.md +++ b/docs/CH10.md @@ -273,7 +273,7 @@ Error 類別與 Exception 類別都繼承自 Throwable 類別,Throwable 類別 除了使用這些方法之外,您也可以簡單的利用例外物件 toString() 方法取得例外的簡單訊息描述。 -您所接觸的例外通常都是衍生自 Exception 類別,其中是有些「受檢例外」(Checked exception),例如 ClassNotFoundException(嘗試載入類別時失敗所引發,例如類別檔案不存在)、InterruptedException(執行緒非執行中而嘗試中斷所引發的例外)等,而有些是「執行時期例外」(Runtime exception),也稱「非受檢例外」(Unckecked exception),例如 ArithmeticException、ArrayIndexOutOfBoundsException 等。以下列出一些重要的例外繼承架構: +您所接觸的例外通常都是衍生自 Exception 類別,其中有些是「受檢例外」(Checked exception),例如 ClassNotFoundException(嘗試載入類別時失敗所引發,例如類別檔案不存在)、InterruptedException(執行緒非執行中而嘗試中斷所引發的例外)等,而有些是「執行時期例外」(Runtime exception),也稱「非受檢例外」(Unchecked exception),例如 ArithmeticException、ArrayIndexOutOfBoundsException 等。以下列出一些重要的例外繼承架構: Throwable Error(嚴重的系統錯誤) diff --git a/docs/CH11.md b/docs/CH11.md index c4cd6ab..93be20f 100644 --- a/docs/CH11.md +++ b/docs/CH11.md @@ -358,7 +358,7 @@ public enum DetailAction3 implements IDescription { > **良葛格的話匣子** 非公開的建構方法最常見的例子就是「Singleton 模式」的應用,當某個類別只能有一個實例時,可由類別維護唯一的實例,這時可以將建構方法設定為私用(private),取用此類別的開發人員就不能自行新增多個實例了,可以看看我網站上有關 Singleton模式的介紹: > -> - http://openhome.cc/Gossip/DesignPattern/ +> - https://openhome.cc/Gossip/DesignPattern/ ### 11.2.3 因值而異的類實作(Value-Specific Class Bodies) diff --git a/docs/CH12.md b/docs/CH12.md index 60afc64..20d0787 100644 --- a/docs/CH12.md +++ b/docs/CH12.md @@ -198,8 +198,8 @@ public class GenericFoo2{ 您可以如下使用 GenericFoo2 類別,分別以 Integer 與 Boolean 設定 T1 與 T2 的真正型態: - GenericFoo foo = - new GenericFoo (); + GenericFoo2 foo = + new GenericFoo2 (); 泛型可以用於宣告陣列型態,範例 12.7 是個簡單示範。 @@ -220,7 +220,7 @@ public class GenericFoo3 { 您可以像下面的方式來使用範例 12.7 所定義的類別。 - `String[] strs = {"caterpillar", "momor", "bush"}; + String[] strs = {"caterpillar", "momor", "bush"}; GenericFoo3 foo = new GenericFoo3 (); foo.setFooArray(strs); strs = foo.getFooArray(); @@ -324,7 +324,7 @@ HashMap 並沒有實作 List 介面,所以無法作為實例化型態持有者 > **良葛格的話匣子** 實際上由於 List、Map、Set 與實作這些介面的相關類別,都已經用新的泛型功能重新改寫過了,實際撰寫時會更複雜一些,例如實際上您還可以再細部定義範例 12.9 的 ListGenericFoo: > > import java.util.List; -> public class ListGenericFoo> { +> public class ListGenericFoo<T extends List<String>> { > private T[] fooArray; > public void setFooArray(T[] fooArray) { > this.fooArray = fooArray; diff --git a/docs/CH13.md b/docs/CH13.md index 24f5733..3eddb02 100644 --- a/docs/CH13.md +++ b/docs/CH13.md @@ -33,7 +33,7 @@ Iterable 介面要求實作它的類別傳回一個實作 java.util.Iterator 介 > **良葛格的話匣子** Iterator 是「Iterator 模式」的一個實例,有關 Iterator 模式,請參考我網站上的文件: > -> - http://openhome.cc/Gossip/DesignPattern/ +> - https://openhome.cc/Gossip/DesignPattern/ Collection 介面繼承了 Iterator 介面,定義了加入元素、移除元素、元素長度等方法, @@ -761,9 +761,9 @@ public class LinkedHashMapDemo { > **良葛格的話匣子** HashMap 是個被經常使用的物件,您可以參考下面幾個例子中有關 HashMap 的應用: > -> - http://openhome.cc/Gossip/DesignPattern/CommandPattern.htm -> - http://openhome.cc/Gossip/DesignPattern/ThreadPerMessage.htm -> - http://openhome.cc/Gossip/JSPServlet/ControllerExample.htm +> - https://openhome.cc/Gossip/DesignPattern/CommandPattern.htm +> - https://openhome.cc/Gossip/DesignPattern/ThreadPerMessage.htm +> - https://openhome.cc/Gossip/JSPServlet/ControllerExample.htm ### 13.2.2 TreeMap diff --git a/docs/CH14.md b/docs/CH14.md index ef56a1a..851d05f 100644 --- a/docs/CH14.md +++ b/docs/CH14.md @@ -297,7 +297,7 @@ public class StreamDemo { ### 14.2.2 FileInputStream、FileOutputStream -java.io.FileInputStream 是 InputStream 的子類,由開頭 File 名稱上就可以知道,FileInputStream 與從指定的檔案中讀取資料至目的地有關,而 java.io.FileOutputStream 是 OutputStream 的子類,顧名思義,FileOnputStream 主要與從來源地寫入資料至指定的檔案中有關。 +java.io.FileInputStream 是 InputStream 的子類,由開頭 File 名稱上就可以知道,FileInputStream 與從指定的檔案中讀取資料至目的地有關,而 java.io.FileOutputStream 是 OutputStream 的子類,顧名思義,FileOutputStream 主要與從來源地寫入資料至指定的檔案中有關。 當您建立一個 FileInputStream 或 FileOutputStream 的實例時,必須指定檔案位置及檔案名稱,實例被建立時檔案的串流就會開啟,而不使用串流時,您必須關閉檔案串流,以釋放與串流相依的系統資源,完成檔案讀寫的動作。 @@ -751,7 +751,7 @@ public class ObjectStreamDemo { momor 103 becky 104 -注意在試圖將物件附加至一個先前已寫入物件的檔案時,由於 ObjectOutputStream 在寫入資料時,還會加上一個特別的串流頭(Stream header),而讀取檔案時會檢查這個串流頭,如果一個檔案中被多次附加物件,那麼該檔案中會有多個串流頭,如此讀取檢查時就會發現不一致,這會丟出 java.io.StreamCorrupedException,為了解決這個問題,您可以重新定義 ObjectOutputStream 的 writeStreamHeader() 方法,如果是以附加的方式來寫入物件,就不寫入串流頭: +注意在試圖將物件附加至一個先前已寫入物件的檔案時,由於 ObjectOutputStream 在寫入資料時,還會加上一個特別的串流頭(Stream header),而讀取檔案時會檢查這個串流頭,如果一個檔案中被多次附加物件,那麼該檔案中會有多個串流頭,如此讀取檢查時就會發現不一致,這會丟出 java.io.StreamCorruptedException,為了解決這個問題,您可以重新定義 ObjectOutputStream 的 writeStreamHeader() 方法,如果是以附加的方式來寫入物件,就不寫入串流頭: ObjectOutputStream objOutputStream = new ObjectOutputStream( @@ -973,7 +973,7 @@ public class PrintStreamDemo { ### 14.2.8 ByteArrayInputStream、ByteArrayOutputStream -串流的來源或目的地不一定是檔案,也可以是記憶體中的一個空間,例如一個位元陣列,java.io.ByteArrayInputStream、java.io.ByteArray OutputStream 即是將位元陣列當作串流輸入來源、輸出目的地的類別。 +串流的來源或目的地不一定是檔案,也可以是記憶體中的一個空間,例如一個位元陣列,java.io.ByteArrayInputStream、java.io.ByteArrayOutputStream 即是將位元陣列當作串流輸入來源、輸出目的地的類別。 ByteArrayInputStream 可以將一個陣列當作串流輸入的來源,而 ByteArrayOutputStream 則可以將一個位元陣列當作串流輸出的目的地,在這邊舉一個簡單的檔案位元編輯程式作為例子,您可以開啟一個簡單的文字檔案,當中有簡單的 ABCDEFG 等字元,在讀取檔案之後,您可以直接以程式來指定檔案中位元的位置來修改所指定的字元,作法是將檔案讀入陣列中,指定陣列索引修改元素,然後重新將陣列存回檔案,範例 14.14 是實作的程式內容。 diff --git a/docs/CH15.md b/docs/CH15.md index 0ffa9f7..1d129ed 100644 --- a/docs/CH15.md +++ b/docs/CH15.md @@ -424,12 +424,14 @@ package onlyfun.caterpillar; public class SomeThread implements Runnable { public void run() { System.out.println("sleep....至 blocked 狀態"); - try { - Thread.sleep(9999); - } - catch(InterruptedException e) { - System.out.println("I am interrupted...."); - } + while(true) { + try { + Thread.sleep(9999); + } + catch(InterruptedException e) { + System.out.println("I am interrupted...."); + } + } } public static void main(String[] args) { @@ -481,7 +483,7 @@ public class SomeThread implements Runnable { > **良葛格的話匣子** 有關於執行緒的終止,還可以參考「Two-phase Termination 模式」: > -> - http://openhome.cc/Gossip/DesignPattern/TwoPhaseTermination.htm +> - https://openhome.cc/Gossip/DesignPattern/TwoPhaseTermination.htm ### 15.1.7 ThreadGroup @@ -954,7 +956,7 @@ public class ProductTest { > **良葛格的話匣子** 有關於生產者消費者的例子,還可以參考「Producer Consumer 模式」: > -> - http://openhome.cc/Gossip/DesignPattern/ProducerConsumer.htm +> - https://openhome.cc/Gossip/DesignPattern/ProducerConsumer.htm ### 15.2.3 容器類的執行緒安全(Thread-safe) @@ -1129,7 +1131,7 @@ class TestThread extends Thread { > **良葛格的話匣子** 有關於 ThreadLocal 的例子,還可以參考「Thread-Specific Storage 模式」: > -> - http://openhome.cc/Gossip/DesignPattern/ThreadSpecificStorage.htm +> - https://openhome.cc/Gossip/DesignPattern/ThreadSpecificStorage.htm ## 15.3 concurrent 套件新增類別 @@ -1141,18 +1143,18 @@ class TestThread extends Thread { BlockingQueue 的幾個主要操作為下: -#### **表 7.1 BlockingQueue 的幾個操作** +#### **表 15.1 BlockingQueue 的幾個操作** -| 方法 | 說明 -|:-- | -| add() | 加入元素,如果佇列是滿的,則丟出 IllegalStateException -| remove() | 傳回並從佇列移除元素,如果佇列是空的,則丟出 NoSuchElementException -| element() | 傳回元素,如果佇列是空的,則丟出 NoSuchElementException -| offer() | 加入元素並傳回 true,如果佇列是滿的,則傳回 false -| poll() | 傳回並從佇列移除元素,如果佇列是空的,則傳回 null -| peek() | 傳回元素,如果佇列是空的,則傳回 null -| put() | 加入元素,如果佇列是滿,就 block -| take() | 傳回並移除元素,如果佇列是空的,就 block +| 方法 | 說明 | +|:--- | :--- | +| add() | 加入元素,如果佇列是滿的,則丟出 IllegalStateException | +| remove() | 傳回並從佇列移除元素,如果佇列是空的,則丟出 NoSuchElementException | +| element() | 傳回元素,如果佇列是空的,則丟出 NoSuchElementException | +| offer() | 加入元素並傳回 true,如果佇列是滿的,則傳回 false | +| poll() | 傳回並從佇列移除元素,如果佇列是空的,則傳回 null | +| peek() | 傳回元素,如果佇列是空的,則傳回 null | +| put() | 加入元素,如果佇列是滿,就 block | +| take() | 傳回並移除元素,如果佇列是空的,就 block | 在 java.util.concurrent 下提供幾種不同的 BlockingQueue,ArrayBlockingQueue 要指定容量大小來建構。LinkedBlockingQueue 預設沒有容量上限,但也可以指定容量上限。PriorityBlockingQueue 嚴格來說不是 Queue,因為它是根據優先權(Priority)來移除元素。 @@ -1222,28 +1224,23 @@ public class ConsumerQueue implements Runnable { ```java package onlyfun.caterpillar; +import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; -public class ConsumerQueue implements Runnable { - private BlockingQueue queue; - - public ConsumerQueue(BlockingQueue queue) { - this.queue = queue; - } - - public void run() { - for(int i = 1; i <= 10; i++) { - try { - // wait for a random time - Thread.sleep((int) (Math.random() * 3000)); - queue.take(); - } - catch(InterruptedException e) { - e.printStackTrace(); - } - } +public class BlockingQueueDemo { + public static void main(String[] args) { + BlockingQueue queue = new ArrayBlockingQueue (1); + + Thread producerThread = new Thread( + new ProducerQueue(queue)); + Thread consumerThread = new Thread( + new ConsumerQueue(queue)); + + producerThread.start(); + consumerThread.start(); } } + ``` 由於 BlockingQueue 不再是由您來控制了,所以在這邊就沒有特意顯示訊息以表示生產者、消費者放入產品至 Queue 的訊息,不過您仍可以在 ProducerQueue 與 ConsumerQueue 中放入相關訊息顯示,以確認程式確實有在運作。 @@ -1254,7 +1251,7 @@ java.util.concurrent.Callable 與 java.util.concurrent.Future 類別可以協助 > **良葛格的話匣子** 有關於 Future 模式的說明,可以參考: > -> - http://openhome.cc/Gossip/DesignPattern/FuturePattern.htm +> - https://openhome.cc/Gossip/DesignPattern/FuturePattern.htm Callable 是個介面,與 Runnable 類似,有個必須實作的方法,可以啟動為另一個執行緒來執行,不過 Callable 工作完成後,可以傳回結果物件,Callable 介面的定義如下: @@ -1314,7 +1311,7 @@ public class PrimeCallable implements Callable { > **良葛格的話匣子** 程式中的求質數方法是很簡單的,但效率不好,這邊只是為了示範方便,才使用那種方式而已,要有效率點的求質數,您可以參考 Eratosthenes 篩選求質數: > -> - http://openhome.cc/Gossip/AlgorithmGossip/EratosthenesPrime.htm +> - https://openhome.cc/Gossip/AlgorithmGossip/EratosthenesPrime.htm 假設現在求質數的需求是在啟動 PrimeCallable 後的幾秒之後,則我們可以搭配 Future 來取得 Callable 執行的結果,在未來的時間點取得結果,例如: @@ -1367,10 +1364,10 @@ java.util.concurrent.FutureTask 是個代理,真正執行找質數的是 Calla 有時候您需要建立一堆執行緒來執行一些小任務,然而頻繁的建立執行緒有時會是個開銷,因為執行緒的建立必須與作業系統互動,如果能建立一個執行緒池(Thread pool)來管理這些小的執行緒並加以重複使用,對於系統效能會是個改善的方式。 您可以使用 Executors 來建立執行緒池,Executors 有幾個靜態(static)方法,列出如下: -#### **表 7.2 Executors 幾個靜態方法** +#### **表 15.2 Executors 幾個靜態方法** -| 方法 | 說明 -|:--- | +| 方法 | 說明 +| :--- | :--- | newCachedThreadPool() | 建立可以快取的執行緒,每個執行緒預設可idle的時間為60秒 | newFixedThreadPool() | 包括固定數量的執行緒 | newSingleThreadExecutor() | 只有一個執行緒,循序的執行指定給它的每個任務 diff --git a/docs/CH16.md b/docs/CH16.md index a12be8e..63459cb 100644 --- a/docs/CH16.md +++ b/docs/CH16.md @@ -52,7 +52,7 @@ public class ClassDemo { Class stringClass = String.class; -Java 在真正需要類別時才會載入類別,所謂「真正需要」通常指的是要使用指定的類別生成物件時(或是使用者指定要載入類別時,例如使用 Class.forName() 載入類別,或是使用 ClassLoader 的 loadClass() 載入類別,稍後都會說明)。使用類別名稱來宣告參考名稱並不會導致類別的載入,可以設計一個測試類別的印證這個說法。 +Java 在真正需要類別時才會載入類別,所謂「真正需要」通常指的是要使用指定的類別生成物件時(或是使用者指定要載入類別時,例如使用 Class.forName() 載入類別,或是使用 ClassLoader 的 loadClass() 載入類別,稍後都會說明)。使用類別名稱來宣告參考名稱並不會導致類別的載入,可以設計一個測試類別印證這個說法。 #### **範例 16.2 TestClass.java** ```java @@ -300,7 +300,7 @@ public class SimpleClassViewer { System.out.printf("package %s;%n", p.getName()); - // 取得型態修飾,像是class、interface + // 取得型態修飾,像是public、final int m = c.getModifiers(); System.out.print(Modifier.toString(m) + " "); @@ -475,7 +475,7 @@ onlyfun.caterpillar.SomeClass 是個自訂類別,您在目前的工作目錄 由於 SomeClass 這次可以在 Bootstrap Loader 的設定路徑下找到,所以會由 Bootstrap Loader 來載入 SomeClass 類別,Bootstrap Loader 通常由 C 撰寫而成,在 Java 中沒有一個實際的類別來表示,所以顯示為 null,因為表示為 null,所以再 由 null 上嘗試呼叫 getParent() 方法就會丟出 NullPointerException 例外。 -取得 ClassLoader 的實例之後,您可以使用它的 loadClass() 方法來載入類別,使用 loadClass() 方法載入別時,不會執行靜態區塊,靜態區塊的執行會等到真正使用類別來建立實例時,例如您可以改寫範例 16.7 為範例 16.12。 +取得 ClassLoader 的實例之後,您可以使用它的 loadClass() 方法來載入類別,使用 loadClass() 方法載入類別時,不會執行靜態區塊,靜態區塊的執行會等到真正使用類別來建立實例時,例如您可以改寫範例 16.7 為範例 16.12。 #### **範例 16.12 ForNameDemoV3.java** ```java @@ -531,7 +531,7 @@ ExtClassLoader 與 AppClassLoader 在程式啟動後會在虛擬機器中存在 Java 的類別載入器階層架構除了可以達到動態載入類別目的之外,還有著安全上的考量,首先,因為每次尋找類別時都是委託 parent 開始尋找,所以除非有人可以侵入您的電腦,置換掉標準 Java SE API 與您自己安裝的延伸套件,否則是不可能藉由撰寫自己的類別載入器來載入惡意類別,以置換掉標準 Java SE API與您自己安裝的延伸套件。 -由於每次的類別載入是由子 ClassLoader 委託父 ClassLoader 先嘗試載入,但父 lassLoader 看不到子 ClassLoader,所以同一階層的子 ClassLoader 不會被誤用,從而避免了載入錯誤類別的可能性,例如在圖 16.4 中,您想從 YourClassLoader 來載入類別的話,類別載入器階層不會看到 MaliciousClassLoader。 +由於每次的類別載入是由子 ClassLoader 委託父 ClassLoader 先嘗試載入,但父 ClassLoader 看不到子 ClassLoader,所以同一階層的子 ClassLoader 不會被誤用,從而避免了載入錯誤類別的可能性,例如在圖 16.4 中,您想從 YourClassLoader 來載入類別的話,類別載入器階層不會看到 MaliciousClassLoader。  @@ -947,7 +947,7 @@ public class CommandUtilDemo { ### 16.2.3 修改成員值 -儘管直接存取類別的資料成員(Field)是不被鼓勵的,但您仍是可以直接存取公開的(public)資料成員,而您甚至也可以透過反射機制來存取私用資料成員,以一個實例來說明,首先撰寫個 TestedField 類別。 +儘管直接存取類別的資料成員(Field)是不被鼓勵的,但您仍是可以直接存取公開的(public)資料成員,而您甚至也可以透過反射機制來存取私用資料成員,以一個實例來說明,首先撰寫個 TestField 類別。 #### **範例 16.20 TestField.java** ```java @@ -1237,8 +1237,8 @@ public class ProxyDemo { > **良葛格的話匣子** 這邊的例子是「Proxy 模式」的實現,您可以進一步參考: > -> - [Proxy 模式(一)](http://openhome.cc/Gossip/DesignPattern/ProxyPattern.htm) -> - [Proxy 模式(二)](http://openhome.cc/Gossip/DesignPattern/ProxyPattern2.htm) +> - [Proxy 模式(一)](https://openhome.cc/Gossip/DesignPattern/ProxyPattern.htm) +> - [Proxy 模式(二)](https://openhome.cc/Gossip/DesignPattern/ProxyPattern2.htm) ## 16.3 接下來的主題 diff --git a/docs/CH17.md b/docs/CH17.md index 2e0b059..736d487 100644 --- a/docs/CH17.md +++ b/docs/CH17.md @@ -1,14 +1,14 @@ # 第 17 章 Annotation -J2SE 5.0 中對 metadata 提出的功能是 Annotation,metadata 就是「資料的資料」(Data about data),突然看到這樣的解釋會覺得奇怪,但以表格為例,表格中呈現的就是資料,但有時候還會有額外的資料用來說明表格的作用,從這個角度來看,metedata 就不這麼的奇怪。 +J2SE 5.0 中對 metadata 提出的功能是 Annotation,metadata 就是「資料的資料」(Data about data),突然看到這樣的解釋會覺得奇怪,但以表格為例,表格中呈現的就是資料,但有時候還會有額外的資料用來說明表格的作用,從這個角度來看,metadata 就不這麼的奇怪。 -在 J2SE 5.0 中,Annotation 的主要目的介於原始碼與 API 文件說明之間,Annotation 對程式碼作出一些說明與解釋,Class 中可以包含這些解釋,編譯器或其它程式分析工作可以使用 Annotation 來作分析,您可以從 java.lang.Override、java.lang.Deprectated、java.lang.SuppressWarnings 這三個 J2SE 5.0 中標準的 Annotation 型態開始瞭解 Annotation 的作用。 +在 J2SE 5.0 中,Annotation 的主要目的介於原始碼與 API 文件說明之間,Annotation 對程式碼作出一些說明與解釋,Class 中可以包含這些解釋,編譯器或其它程式分析工作可以使用 Annotation 來作分析,您可以從 java.lang.Override、java.lang.Deprecated、java.lang.SuppressWarnings 這三個 J2SE 5.0 中標準的 Annotation 型態開始瞭解 Annotation 的作用。 ------------- ## 17.1 Annotation -Annotation 對程式運行沒有影響,它的目的在對編譯器或分析工具說明程式的某些資訊,您可以在套件、類別、方法、資料成員等加上 Annotation,每一個 Annotation 對應於一個實際的 Annotation 型態,您可以從 java.lang.Override、java.lang.Deprectated、java.lang.SuppressWarnings 這三個 J2SE 5.0 中標準的 Annotation 型態開始瞭解 Annotation 的作用,這個小節也將告訴您如何自訂 Annotation 型態。 +Annotation 對程式運行沒有影響,它的目的在對編譯器或分析工具說明程式的某些資訊,您可以在套件、類別、方法、資料成員等加上 Annotation,每一個 Annotation 對應於一個實際的 Annotation 型態,您可以從 java.lang.Override、java.lang.Deprecated、java.lang.SuppressWarnings 這三個 J2SE 5.0 中標準的 Annotation 型態開始瞭解 Annotation 的作用,這個小節也將告訴您如何自訂 Annotation 型態。 ### 17.1.1 限定 Override 父類方法 @Override @@ -63,13 +63,13 @@ java.lang.Override 是個 Marker annotation,簡單的說就是用於標示的 > **良葛格的話匣子** 「Annotation 型態」與「Annotation」實際上是有所區分的,Annotation 是 Annotation 型態的實例,例如 @Override 是個 Annotation,它是 java.lang.Override 型態的一個實例,一個文件中可以有很多個 @Override,但它們都是屬於 java.lang.Override 型態。 -### 17.1.2 標示方法為 Deprecated @Deprectated +### 17.1.2 標示方法為 Deprecated @Deprecated -java.lang.Deprectated 是 J2SE 5.0 中標準的 Annotation 型態之一,它對編譯器說明某個方法已經不建議使用,如果有開發人員試圖使用或重新定義被 @Deprecated 標示的方法,編譯器必須提出警示訊息。 +java.lang.Deprecated 是 J2SE 5.0 中標準的 Annotation 型態之一,它對編譯器說明某個方法已經不建議使用,如果有開發人員試圖使用或重新定義被 @Deprecated 標示的方法,編譯器必須提出警示訊息。 -舉個例子來說,您可能定義一個 Something 類別,並在當中定義有 getSomething() 方法,而在這個類別被實際使用一段時間之後,您不建議開發人員使用 getSomething() 方法了,並想要將這個方法標示為 "deprectated",您可以使用 @Deprectated 在 getSomething() 方法加上標示。 +舉個例子來說,您可能定義一個 Something 類別,並在當中定義有 getSomething() 方法,而在這個類別被實際使用一段時間之後,您不建議開發人員使用 getSomething() 方法了,並想要將這個方法標示為 "deprecated",您可以使用 @Deprecated 在 getSomething() 方法加上標示。 -#### **範例 17.3 Somethingjava** +#### **範例 17.3 Something.java** ```java package onlyfun.caterpillar; @@ -524,7 +524,7 @@ public class SomeoneClass { 每一個章節的內容由淺至深,初學者該掌握的深度要到哪呢?在這個章節中,對於初學者我建議至少掌握以下幾點內容: -- 會使用 @Override、@Deprectated、@SuppressWarnings +- 會使用 @Override、@Deprecated、@SuppressWarnings - 知道如何在 Java 程式中讀出 Annotation 資訊 下一個章節是個捨遺補缺的章節,也是本書的最後一個章節,當中說明了一些本書中有使用到但還沒有詳細說明的 API,另外我還介紹了簡單的訊息綁定,這讓您在配置程式的文字訊息時能夠更有彈性。 diff --git a/docs/CH18.md b/docs/CH18.md index 990d0b4..a01db78 100644 --- a/docs/CH18.md +++ b/docs/CH18.md @@ -486,7 +486,7 @@ Level.ALL 表示顯示所有的訊息,所以這一次的執行結果可顯示 如果您想要關閉所有的訊息,可以設定為 Level.OFF。 -Logger 的 server()、warning()、info() 等方法,實際上是個便捷的方法,您也可以直接使用 log() 方法並指定等級來執行相同的作用,例如範例 18.10 的執行結果與範例 18.9 是一樣的。 +Logger 的 severe()、warning()、info() 等方法,實際上是個便捷的方法,您也可以直接使用 log() 方法並指定等級來執行相同的作用,例如範例 18.10 的執行結果與範例 18.9 是一樣的。 #### **範例 18.10 LoggingLevelDemo3.java** ```java @@ -825,7 +825,7 @@ public class MessageFormatDemo { ### 18.3.3 國際化訊息 -國際化的英文是 Internationalization,因為單字中總共有18個字母而首尾字元分別為 'I' 與 'N',所以簡稱 I18N,國際化的目的是讓應用程式可以依地區不同而顯示不同的訊息,最基本的就是讓不同語系的使用者可以看到屬於自己語系的訊息,像是英文語系的看到英文內容,而中文語系的可以看到中文的內容。 +國際化的英文是 Internationalization,因為單字中總共有20個字母而首尾字元分別為 'I' 與 'N',所以簡稱 I18N,國際化的目的是讓應用程式可以依地區不同而顯示不同的訊息,最基本的就是讓不同語系的使用者可以看到屬於自己語系的訊息,像是英文語系的看到英文內容,而中文語系的可以看到中文的內容。 為了在應用程式中表示一個區域,Java 提供有 java.util.Locale 類,一個 Locale 實例包括了語系資訊與區域資訊,例如 "en" 表示英文語系的國家,這個字母組合是在 ISO 639 中定義的,而區域資訊則是像 "US" 表示美國,這個字母組合則是在 ISO 3166 中定義的。 diff --git a/docs/CH19.md b/docs/CH19.md index c46f6b4..4745bca 100644 --- a/docs/CH19.md +++ b/docs/CH19.md @@ -1,6 +1,6 @@ # 第 19 章 專題製作 - 文字編輯器 -在學習完一個程式語言的基本語法、API 的使用之後,若要驗收學習的成果,試著自己撰寫一個文字編輯器是個不錯的驗收方式,在這個章節中將一步步告訴您,如何組合前面18個章節中學習到的語法及 API 功能,實作出一個具讀取、儲存功能的視窗文字編輯器。 +在學習完一個程式語言的基本語法、API 的使用之後,若要驗收學習的成果,試著自己撰寫一個文字編輯器是個不錯的驗收方式,在這個章節中將一步步告訴您,如何組合前面 18 個章節中學習到的語法及 API 功能,實作出一個具讀取、儲存功能的視窗文字編輯器。 在這個章節中,您也將學到基本的 Swing 視窗程式設計,了解 Java 的視窗程式中容器(Container)、元件(Component)、版面管理員(Layout Manager)、事件(Event)與傾聽者(Listener)的基本觀念。 @@ -16,7 +16,7 @@ - 具備視窗介面 - 您必須決定使用者將如何操作您的文字編輯器,這要考量使用者在操作上的習慣,或是領域(Domain)特有的操作需求,操作介面設計良好與否,對一個產品是否受歡迎有相當大的影響,您可以觀察所要開發的程式是否有相類似的產品,看看該產品是如何設計操作介面的,對於簡單的文字編輯器之開發,可以參考Windows的「記事本」程式在介面上是如何設計的。 + 您必須決定使用者將如何操作您的文字編輯器,這要考量使用者在操作上的習慣,或是領域(Domain)特有的操作需求,操作介面設計良好與否,對一個產品是否受歡迎有相當大的影響,您可以觀察所要開發的程式是否有相類似的產品,看看該產品是如何設計操作介面的,對於簡單的文字編輯器之開發,可以參考 Windows 的「記事本」程式在介面上是如何設計的。 您可以在紙上或繪圖軟體上,先設計出操作介面草稿,在設計介面的同時,也會大致勾勒出應用程式的部份功能,對於您將開發的文字編輯器,將具備以下的視窗介面: @@ -78,13 +78,13 @@ ### 19.1.3 開發(Development) -進入開發階段之後,將決定使用何種語言及技術來開發應用程式,在這個章節中,您將使用 Java 程式語言,並運用 Java SE 技術來開發文字編輯器,文字編輯器的介面將使用Swing視窗元件來開發,這也是這個章節所要著重的階段。 +進入開發階段之後,將決定使用何種語言及技術來開發應用程式,在這個章節中,您將使用 Java 程式語言,並運用 Java SE 技術來開發文字編輯器,文字編輯器的介面將使用 Swing 視窗元件來開發,這也是這個章節所要著重的階段。 ### 19.1.4 測試(Testing) 將完成的應用程式進行測試,以驗收其是否完成所期許的需求,並檢查程式中是否存在臭蟲(Bug),或是效能方面等的問題。 -測試在現今的軟體開發中是一個日易受到重視的問題,各種的測試開發理論與實作文件不斷的被提出,對於這個章節來說,測試是個超出討論範圍的課題,有興趣的話,可以看看我的 [JUnit 筆記](http://openhome.cc/Gossip/JUnit/) 的內容,瞭解一些測試方面的技術與觀念。 +測試在現今的軟體開發中是一個日易受到重視的問題,各種的測試開發理論與實作文件不斷的被提出,對於這個章節來說,測試是個超出討論範圍的課題,有興趣的話,可以看看我的 [JUnit 筆記](https://openhome.cc/Gossip/JUnit/) 的內容,瞭解一些測試方面的技術與觀念。 ### 19.1.5 完成(Implementation) @@ -102,7 +102,7 @@ ## 19.2 Swing 入門 -若要使用 Java SE 來開發視窗應用程式,就本書撰寫的時間點來說可以有兩種選擇,一個是使用 AWT(Abstract Window Toolkit),另一個是使用 JFC(Java Foundation Classes)/Swing。您所要開發的文字編輯器將使用 Swing 技術,Swing 的使用可以很複雜,是個可以用專書介紹的技術,而這個小節的目的,在讓您於開發文字編輯器的介面,同時也可以掌握 Swing 設計的最基本要素,也就是容器(Container)、元件(Component)、版面管理員(Layout Manager)、事件(Event)與傾聽者(Listener)等基本觀念。 +若要使用 Java SE 來開發視窗應用程式,就本書撰寫的時間點來說可以有兩種選擇,一個是使用 AWT(Abstract Window Toolkit),另一個是使用 JFC(Java Foundation Classes)/ Swing。您所要開發的文字編輯器將使用 Swing 技術,Swing 的使用可以很複雜,是個可以用專書介紹的技術,而這個小節的目的,在讓您於開發文字編輯器的介面,同時也可以掌握 Swing 設計的最基本要素,也就是容器(Container)、元件(Component)、版面管理員(Layout Manager)、事件(Event)與傾聽者(Listener)等基本觀念。 ### 19.2.1 Swing 簡介 @@ -161,7 +161,7 @@ Swing 的元件相當的豐富,若要詳細說明,實際上可以另外出 - 主視窗 -您可以繼承 javax.swing.JFrame 來撰寫一個可以呈現在螢幕上的視窗,最基本的動作包括:設定視窗元件、設定事件處理、呈現畫面。直接使用範例 19.1 來示範如何呈現一個基本的Swing視窗。 +您可以繼承 javax.swing.JFrame 來撰寫一個可以呈現在螢幕上的視窗,最基本的動作包括:設定視窗元件、設定事件處理、呈現畫面。直接使用範例 19.1 來示範如何呈現一個基本的 Swing 視窗。 #### **範例 19.1 JNotePadUI.java** ```java @@ -193,7 +193,7 @@ public class JNotePadUI extends JFrame { 在範例 19.1 中,將視窗元件的設置與事件的處理分別交由 setUpUIComponent() 與 setUpEventListener() 兩個方法來處理,這有助於將來程式碼內容增加時的管理。 -JFrame 擁有一個接受字串引數的建構方法,被設置的字串將用作視窗的標題文字,從 JFrame 繼承下來的 setSize() 方法用來設定視窗元件的大小,程式中設定為 640x480 的像素(Pixel)大小。setDefaultCloseOperation() 用來設定視窗右上角的X按鈕被按下時所該採取的動作,預設是 WindowConstants.HIDE_ONE_CLOSE,也就是按下後隱藏視窗,但並不會結束程式,在這邊希望按下X按鈕後可以直接結束程式,因而設定為 JFrame.EXIT_ON_CLOSE。 +JFrame 擁有一個接受字串引數的建構方法,被設置的字串將用作視窗的標題文字,從 JFrame 繼承下來的 setSize() 方法用來設定視窗元件的大小,程式中設定為 640x480 的像素(Pixel)大小。setDefaultCloseOperation() 用來設定視窗右上角的 X 按鈕被按下時所該採取的動作,預設是 WindowConstants.HIDE_ON_CLOSE,也就是按下後隱藏視窗,但並不會結束程式,在這邊希望按下 X 按鈕後可以直接結束程式,因而設定為 JFrame.EXIT_ON_CLOSE。 在所有的元件與事件處理都設置完成之後,可以使用從 JFrame 繼承下來的 setVisible(),藉由設定其引數為 true 來呈現視窗,程式的執行結果如下圖所示: @@ -350,7 +350,7 @@ public class JNotePadUI extends JFrame { 在 Container 中的元件的位置跟大小是由版面管理員(Layout manager)來決定,當 Container 需要決定它當中的元件的大小或位置時,就會呼叫版面管理員來為其執行。 -- JTextArea 與 JScorllPane +- JTextArea 與 JScrollPane 文字編輯器的基本需求,就是有一個文字編輯區域,這個文字編輯區域可以使用 javax.swing.JTextArea 類別,然而 JTextArea 並不具備捲軸,文字內容多時沒有捲軸對於編輯或瀏覽都不方便,您可以在 JTextArea 上加上一個 javax.swing.JScrollPane,JScrollPane 會檢驗 JTextArea 的文字內容,在必要的時候顯示捲軸,或者是在操作捲軸時,也會對 JTextArea 進行相對應的位置顯示,以下是結合 JTextArea、JScrollPane 以建立文字編輯區域的程式碼片段: @@ -464,7 +464,7 @@ public class JNotePadUI extends JFrame { ## 19.3 事件處理 -當使用者在圖形介面上進行一些操作時,例如移動滑鼠、選取選單項目等,將會引發相關事件(Event)的發生,在 Java 中事件以具體的物件來表示,使用者的相關動作會由JVM建立相對應的事件,用以描述事件來源、發生了什麼事、以及相關的訊息,您要藉由捕捉對應的事件,以進行對應的操作來完成應用程式的功能。 +當使用者在圖形介面上進行一些操作時,例如移動滑鼠、選取選單項目等,將會引發相關事件(Event)的發生,在 Java 中事件以具體的物件來表示,使用者的相關動作會由 JVM 建立相對應的事件,用以描述事件來源、發生了什麼事、以及相關的訊息,您要藉由捕捉對應的事件,以進行對應的操作來完成應用程式的功能。 ### 19.3.1 Java 事件模型 @@ -524,7 +524,7 @@ Java 對事件的處理採委託事件模型(Delegation event model),在 } ); -滑鼠處理者接受的是 MouseEvent,您可以使用 getButton() 方法取得一個常數,表示按下的是哪一個滑鼠鍵,MouseEvent.Button1 是指按下滑鼠左鍵,MouseEvent.Button3 則表示滑鼠右鍵,您使用 JTextArea的addMouseListener() 方法加入傾聽者,程式片段中的 popUpMenu 參考至 javax.swing.JPopupMenu 的實例,這個實例可用編輯選單直接取得,例如: +滑鼠處理者接受的是 MouseEvent,您可以使用 getButton() 方法取得一個常數,表示按下的是哪一個滑鼠鍵,MouseEvent.Button1 是指按下滑鼠左鍵,MouseEvent.Button3 則表示滑鼠右鍵,您使用 JTextArea 的 addMouseListener() 方法加入傾聽者,程式片段中的 popUpMenu 參考至 javax.swing.JPopupMenu 的實例,這個實例可用編輯選單直接取得,例如: JPopupMenu popUpMenu = editMenu.getPopupMenu(); @@ -728,7 +728,7 @@ public class JNotePadUI extends JFrame { ### 19.4.1 開啟檔案的流程處理 -首先定義出當使用者選取選單上的「開啟舊檔」時,所需的處理流程:先檢查目前編輯中的文件是否已儲存,若是,則希望出現對話方塊供使用者選取所需的檔案、開啟它然後顯示在文字編輯區;若否,則出現對話方塊顯示"檔案已修改,是否儲存?"的訊息,若選擇「是」則儲存檔案,若選擇「否」則放棄目前檔案直接開啟舊檔。 +首先定義出當使用者選取選單上的「開啟舊檔」時,所需的處理流程:先檢查目前編輯中的文件是否已儲存,若是,則希望出現對話方塊供使用者選取所需的檔案、開啟它然後顯示在文字編輯區;若否,則出現對話方塊顯示`檔案已修改,是否儲存?`的訊息,若選擇「是」則儲存檔案,若選擇「否」則放棄目前檔案直接開啟舊檔。 上面的流程中,可以分出幾個子流程,例如檢查檔案是否儲存、開啟文件、儲存檔案,這幾個子流程可以先定義為方法,待會再來實作,因此可以先實作出以下的程式內容: @@ -763,7 +763,7 @@ private boolean isCurrentFileSaved() { } ``` -JOptionPane.showConfirmDialog() 可以出現一個訊息對話方塊,設定 JOptionPane.YES_NO_OPTION 會出現「是」、「否」的按鈕,而設定 JOptionPane.WARNING_MESSAGE 會出現一個警告圖示,在確認是否之後,會得到一個 int 常數,與 JOptionPane.YES_OPTION 或 JOptionPane.YES_OPTION 比對,即可得知使用者按下了哪一個按鈕。 +JOptionPane.showConfirmDialog() 可以出現一個訊息對話方塊,設定 JOptionPane.YES_NO_OPTION 會出現「是」、「否」的按鈕,而設定 JOptionPane.WARNING_MESSAGE 會出現一個警告圖示,在確認是否之後,會得到一個 int 常數,與 JOptionPane.YES_OPTION 或 JOptionPane.NO_OPTION 比對,即可得知使用者按下了哪一個按鈕。  @@ -960,7 +960,7 @@ private void processTextArea() { 撰寫 Java 程式到這邊,相信您一定會有所疑問的是,編出來的 .class 檔案越來越多,難道要將這一堆 .class 檔案直接給想要執行程式的人嗎?在 Windows 下的話,有沒有辦法按一下檔案,就可以執行程式呢? -當然,實際上要交付程式時,並不是給一堆 .class 檔案,而是會將編譯好的 .class 檔包裝為一個J ava Archive File,也就是副檔名為 .jar 的檔案,在 JDK 的 bin 目錄下,附帶有一個 jar 工具程式,您可以直接執行 jar 程式,看看它的提示訊息: +當然,實際上要交付程式時,並不是給一堆 .class 檔案,而是會將編譯好的 .class 檔包裝為一個 Java Archive File,也就是副檔名為 .jar 的檔案,在 JDK 的 bin 目錄下,附帶有一個 jar 工具程式,您可以直接執行 jar 程式,看看它的提示訊息:  @@ -972,7 +972,7 @@ private void processTextArea() { 圖 19.14 準備製作 jar 檔案 -接著開啟文字模式,切換工作目錄至 jar 目錄下,然後鍵入以下的指令,表示將建立一個 JNotePad.jar 放到 bin 目錄中,來源是 classes 中的檔案,被放入的檔案將以 / 作為 .jar 檔案中的根目錄: +接著開啟文字模式,切換工作目錄至 jar 目錄下,然後鍵入以下的指令,表示將建立一個 JNotePad.jar 放到 bin 目錄中,來源是 classes 中的檔案,被放入的檔案將以 `/` 作為 .jar 檔案中的根目錄:  @@ -985,7 +985,7 @@ private void processTextArea() { 接著您的文字編輯器就會啟動了,現在您不用將一堆 .class 檔案交付出去,只要交付這個 JNotePad.jar 就可以了。 -然而,真的要指定 Classpath 這麼麻煩嗎?其實還有更方便的做法,製作一 個Executable Jar 檔案,指定讀取 .jar 檔案時要執行的 Main-Class 就可以了,這需要準備一個 manifest.txt,當中寫下: +然而,真的要指定 Classpath 這麼麻煩嗎?其實還有更方便的做法,製作一個 Executable Jar 檔案,指定讀取 .jar 檔案時要執行的 Main-Class 就可以了,這需要準備一個 manifest.txt,當中寫下:  @@ -997,7 +997,7 @@ private void processTextArea() { 圖 19.17 指定 manifest 檔案並製作 jar 檔案 -在 .jar 檔案製作出來後,您可以在執行 java 時指定 -jar 引數,以及您的 .jar 檔案,java 程式會自動尋找 Main-Clas s並執行,例如下達以下的指令: +在 .jar 檔案製作出來後,您可以在執行 java 時指定 -jar 引數,以及您的 .jar 檔案,java 程式會自動尋找 Main-Class 並執行,例如下達以下的指令: java -jar bin/JNotePad.jar diff --git a/docs/CH20.md b/docs/CH20.md index e9209ae..d194528 100644 --- a/docs/CH20.md +++ b/docs/CH20.md @@ -10,9 +10,9 @@ JDBC(Java DataBase Connectivity)是用於執行 SQL 的 Java 解決方案, 在正式使用 JDBC 進行資料庫操作之前,先來認識一下 JDBC 的基本架構,了解資料庫驅動程式與資料庫之間的關係,在這個小節也將看到,如何設計一個簡單的工具類別,讓您在進行資料庫連接(Connection)時更為方便。 -20.1.1 簡介 JDBC +### 20.1.1 簡介 JDBC -如果要連接資料庫並進行操作,基本上必須了解所使用的資料庫所提供的 API 操作介面,然而各個廠商所提供的 API 操作介面並不一致,如果今天要使用A廠商的資料庫,就必須設計一個專用的程式來操作 A 廠商資料庫所提供的 API,將來如果要使用 B 廠商的資料庫,即使目的相同,也是要撰寫專用於 B 廠商資料庫之程式,十分的不方便。 +如果要連接資料庫並進行操作,基本上必須了解所使用的資料庫所提供的 API 操作介面,然而各個廠商所提供的 API 操作介面並不一致,如果今天要使用 A 廠商的資料庫,就必須設計一個專用的程式來操作 A 廠商資料庫所提供的 API,將來如果要使用 B 廠商的資料庫,即使目的相同,也是要撰寫專用於 B 廠商資料庫之程式,十分的不方便。 使用 JDBC,可由廠商實作操作資料庫介面的驅動程式,而 Java 程式設計人員呼叫 JDBC 的 API 並操作 SQL,實際對資料庫的操作由 JDBC 驅動程式負責,如果要更換資料庫,基本上只要更換驅動程式,Java 程式中只要載入新的驅動程式來源即可完成資料庫的變更,Java 程式的部份則無需改變。 @@ -62,7 +62,7 @@ JDBC 資料庫驅動程式依實作方式可以分為四個類型: ### 20.1.2 連接資料庫 -為了要連接資料庫系統,您必須要有JDBC驅動程式,由於接下來將使用 MySQL 資料庫進行操作,所以請將下載回來的tar.gz檔案使用解壓縮軟體解開,並將當中的 mysql-connector-java-*.jar 加入至 Classpath 的設定之中,假設是放在 c:\workspace\library\mysql-connector-java-3.1.13-bin.jar,則 Classpath 中必須有 c:\workspace\library\mysql-connector-java-3.1.13-bin.jar 這個路徑設定。 +為了要連接資料庫系統,您必須要有JDBC驅動程式,由於接下來將使用 MySQL 資料庫進行操作,所以請將下載回來的 tar.gz 檔案使用解壓縮軟體解開,並將當中的 mysql-connector-java-*.jar 加入至 Classpath 的設定之中,假設是放在 c:\workspace\library\mysql-connector-java-3.1.13-bin.jar,則 Classpath 中必須有 c:\workspace\library\mysql-connector-java-3.1.13-bin.jar 這個路徑設定。 在 Java SE 中與資料庫操作相關的 JDBC 類別都位於 java.sql 套件中,要連接資料庫,基本上必須有幾個動作: @@ -83,7 +83,7 @@ JDBC 資料庫驅動程式依實作方式可以分為四個類型: 協定:子協定:資料來源識別 - 「協定」在 JDBC 中總是 jdbc 開始;「子協定」是橋接的驅動程式或是資料庫管理系統名稱,使用 MySQL 的話是 "mysql";「資料來源識別」標出找出資料庫來源的位址與連接埠。舉個例子來說,MySQL 的 JDBC URL 撰寫方式如下: + 「協定」在 JDBC 中總是 jdbc 開始;「子協定」是橋接的驅動程式或是資料庫管理系統名稱,使用 MySQL 的話是 `mysql`;「資料來源識別」標出找出資料庫來源的位址與連接埠。舉個例子來說,MySQL 的 JDBC URL 撰寫方式如下: jdbc:mysql://主機名稱:連接埠/資料庫名稱?參數=值&參數=值 @@ -126,7 +126,7 @@ getConnection() 方法可以在參數上指定使用者名稱與密碼,例如 您可以將 JDBC URL、使用者名稱與密碼等設定資訊,撰寫在一個屬性檔案當中,由程式讀取這個屬性檔中的資訊,如果需要變更資訊,則只要修改屬性檔即可,無須修改程式、重新編譯,在 Java SE 當中,屬性檔的讀取可以交給 java.util.Properties 類別。 -舉個實際的例子,假設您使用了以下的指令在MySQL後建立了demo資料庫: +舉個實際的例子,假設您使用了以下的指令在 MySQL 後建立了 demo 資料庫: CREATE DATABASE demo; @@ -192,7 +192,7 @@ public class SimpleDBSource implements DBSource { } ``` -預設的建構方法設定中,是讀取 jdbc.properties 檔案中的設定,如果打算自行指定屬性檔案名稱,則可以使用另一個有參數的建構方法。Properties 的 getProperty() 方法會讀取屬性檔案中的"鍵(Key)"對應的"值(Value)",假設您的屬性檔案設定如下: +預設的建構方法設定中,是讀取 jdbc.properties 檔案中的設定,如果打算自行指定屬性檔案名稱,則可以使用另一個有參數的建構方法。Properties 的 getProperty() 方法會讀取屬性檔案中的 **鍵(Key)** 對應的 **值(Value)**,假設您的屬性檔案設定如下: #### **範例 20.3 jdbc.properties** ``` @@ -376,7 +376,7 @@ onlyfun.caterpillar.poolmax=10 Statement stmt = conn.createStatement(); -取得 Statement 物件之後,可以使用 executeUpdate()、executeQuery() 等方法來執行 SQL,executeUpdate() 主要是用來執行 CREATE TABLE、INSERT、DROP TABLE、ALTER TABLE 等會改變資料庫內容的 SQL,例如可以在 demo 資料庫中建立一個 t_message 表格: +取得 Statement 物件之後,可以使用 executeUpdate()、executeQuery() 等方法來執行 SQL,executeUpdate() 主要是用來執行 CREATE TABLE、INSERT、DROP TABLE、ALTER TABLE 等會改變資料庫內容的 SQL,例如可以在 demo 資料庫中建立一個 t_message 表格: Use demo; CREATE TABLE t_message ( @@ -413,7 +413,7 @@ Statement 的 executeQuery() 方法則是用於 SELECT 等查詢資料庫的 SQL System.out.print(result.getString(4) + "\t"); } -Statement 的 execute() 可以用來執行 SQL,並可以測試所執行的 SQL 是執行查詢或是更新,傳回 true 的話表示 SQL 執行將傳回 ResultSet 表示查詢結果,此時可以使用 getResultSet() 取得 ResultSet 物件,如果 execute() 傳回 false,表示 SQL 執行會傳回更新筆數或沒有結果,此時可以使用 getUpdateCount() 取得更新筆數。如果事先無法得知是進行查詢或是更新,就可以使用 execute()。 +Statement 的 execute() 可以用來執行 SQL,並可以測試所執行的 SQL 是執行查詢或是更新,傳回 true 的話表示 SQL 執行將傳回 ResultSet 表示查詢結果,此時可以使用 getResultSet() 取得 ResultSet 物件,如果 execute() 傳回 false,表示 SQL 執行會傳回更新筆數或沒有結果,此時可以使用 getUpdateCount() 取得更新筆數。如果事先無法得知是進行查詢或是更新,就可以使用 execute()。 範例 20.8 是個示範新增與查詢資料的範例,當中使用了前一節設計的 SimpleDBSource。注意在查詢結束後,要使用 Statement 的 close() 方法來釋放 Statement 的資源,而最後不使用連接時,也使用了 closeConnection() 來關閉連接。 @@ -580,7 +580,7 @@ public class PreparedStatementDemo { } ``` -setXXX() 方法的第一個參數指定"?"的位置,而第二個參數為要新增至資料表欄位的值,要讓 SQL 執行生效,要執行 executeQuery() 或 executeUpdate() 方法,使用 setXXX() 來設定的參數會一直有效,可以於下一次使用,如果想要清除設定好的參數,可以執行 clearParameters() 方法。以下是這個範例的執行結果參考: +setXXX() 方法的第一個參數指定 "?" 的位置,而第二個參數為要新增至資料表欄位的值,要讓 SQL 執行生效,要執行 executeQuery() 或 executeUpdate() 方法,使用 setXXX() 來設定的參數會一直有效,可以於下一次使用,如果想要清除設定好的參數,可以執行 clearParameters() 方法。以下是這個範例的執行結果參考: 1 justin justin@mail.com mesage... 2 momor momor@mail.com message2... @@ -612,7 +612,7 @@ fin.close(); 如果要從資料庫中取得 BLOB 或 CLOB 資料,您可以如下進行,其中 result 參考一個 ResultSet 的實例: Blob blob = result.getBlob(2); // 取得BLOB - Clob clob = result.getClob(2) // 取得CLOB + Clob clob = result.getClob(2); // 取得CLOB Blob 擁有 getBinaryStream()、getBytes() 等方法,可以取得二進位串流或 byte 等資料,同樣的,Clob 擁有 getCharacterStream()、getSubString() 等方法,可以取得字元串流或子字串等資料,您可以查看 API 文件來獲得更詳細的訊息。 @@ -728,7 +728,7 @@ public class LobDemo { > **良葛格的話匣子** Lob 的讀寫方法在 Oracle 中有所不同,您可以參考: > -> - http://openhome.cc/Gossip/HibernateGossip/BlobClob_Oracle.html +> - https://openhome.cc/Gossip/HibernateGossip/BlobClob_Oracle.html > > 在 Java SE 6 中,對於 Blob、Clob 做了改進,詳細可以參考第 21 章的內容。 @@ -736,9 +736,9 @@ public class LobDemo { 交易是一組原子(Atomic)操作(一組 SQL 執行)的工作單元,這個工作單元中的所有原子操作在進行期間,與其它交易隔離,免於數據來源的交相更新而發生混亂,交易中的所有原子操作,要嘛全部執行成功,要嘛全部失敗(即使只有一個失敗,所有的原子操作也要全部撤消)。 -舉個簡單的例子,一個客戶從 A 銀行轉帳至 B 銀行,要做的動作為從A銀行的帳戶扣款、在 B 銀行的帳戶加上轉帳的金額,兩個動作必須成功,如果有一個動作失敗,則此次轉帳失敗。 +舉個簡單的例子,一個客戶從 A 銀行轉帳至 B 銀行,要做的動作為從 A 銀行的帳戶扣款、在 B 銀行的帳戶加上轉帳的金額,兩個動作必須成功,如果有一個動作失敗,則此次轉帳失敗。 -在 JDB C中,可以操作 Connection 的 setAutoCommit() 方法,給它 false 引數,在下達一連串的 SQL 語句後,自行呼叫 Connection 的 commit() 來送出變更,如果中間發生錯誤,則呼叫 rollback() 來撤消所有的執行,一個示範的流程如下所示: +在 JDBC 中,可以操作 Connection 的 setAutoCommit() 方法,給它 false 引數,在下達一連串的 SQL 語句後,自行呼叫 Connection 的 commit() 來送出變更,如果中間發生錯誤,則呼叫 rollback() 來撤消所有的執行,一個示範的流程如下所示: ```java try { @@ -762,7 +762,7 @@ try { } ``` -如果您在交易管理時,僅想要撤回(rollback)某個SQL執行點,則您可以設定儲存點(save point),例如: +如果您在交易管理時,僅想要撤回(rollback)某個 SQL 執行點,則您可以設定儲存點(save point),例如: ```java conn.setAutoCommit(false); @@ -776,7 +776,7 @@ conn.rollback(savepoint); . . . conn.commit(); // 記得釋放save point -stmt.releaseSavepoint(savepoint); +conn.releaseSavepoint(savepoint); ``` > **良葛格的話匣子** 您的資料表格必須支援交易,才可以執行以上所提到的功能,例如在 MySQL 中可以建立 InnoDB 類型的表格: @@ -789,7 +789,7 @@ stmt.releaseSavepoint(savepoint); ### 20.2.6 批次處理 -Statement 的 execute 等方法一次只能執行一個 SQL 敘述,如果有多個 SQL 敘述要執行的話,可以使用 executeBatch() 方法,在一次方法呼叫中執行多個 SQL 敘述,以增加執行的效能,您可以使用 addBatch() 方法將要執行的 SQL 敘述加入,然後執行 executeBatch() 即可: +Statement 的 execute 等方法一次只能執行一個 SQL 敘述,如果有多個 SQL 敘述要執行的話,可以使用 executeBatch() 方法,在一次方法呼叫中執行多個 SQL 敘述,以增加執行的效能,您可以使用 addBatch() 方法將要執行的 SQL 敘述加入,然後執行 executeBatch() 即可: ```java conn.setAutoCommit(false); @@ -802,7 +802,7 @@ stmt.executeBatch(); conn.commit(); ``` -在執行 executeBatch() 時而 SQL 有錯誤的情況下,會丟出 BatchUpdateException 例外,您可以由這個例外物件的 getUpdateCounts() 方法取得發生錯誤的SQL句數,如果中間有個 SQL 執行錯誤,則應該撤回(rollback)整個批次處理過程的SQL操作。 +在執行 executeBatch() 時而 SQL 有錯誤的情況下,會丟出 BatchUpdateException 例外,您可以由這個例外物件的 getUpdateCounts() 方法取得發生錯誤的 SQL 句數,如果中間有個 SQL 執行錯誤,則應該撤回(rollback)整個批次處理過程的 SQL 操作。 使用 PreparedStatement 也可以進行批次處理,直接來看個例子: @@ -947,7 +947,7 @@ relative() 方法則從目前游標處指定相對位置,例如若目前在第 ### 20.2.9 ResultSetMetaData -Meta Data 即「資料的資料」(Data about data),ResultSet 用來表示查詢到的資料,而 ResultSe t資料的資料,即描述所查詢到的資料背後的資料描述,即用來表示表格名稱、欄位名稱、欄位型態等,這些訊息可以透過 ResultSetMetaData 來取得。 +Meta Data 即「資料的資料」(Data about data),ResultSet 用來表示查詢到的資料,而 ResultSet 資料的資料,即描述所查詢到的資料背後的資料描述,即用來表示表格名稱、欄位名稱、欄位型態等,這些訊息可以透過 ResultSetMetaData 來取得。 範例 20.12 直接示範如何取得查詢到的資料欄位數、表格名稱、欄位名稱與欄位資料型態: diff --git a/docs/CH21.md b/docs/CH21.md index 793ebbd..561424e 100644 --- a/docs/CH21.md +++ b/docs/CH21.md @@ -115,7 +115,7 @@ public class BinarySearchDemo { } ``` -在這個程式中,指定搜尋索引 6 到索引 9(不包括索引 9)的範圍中是否有 85 的值,如果找到的話,傳回索引值,如果沒有找到,傳回一個負值,該負值加 1 再乘以 -1,就是插入點位置,也就是第一個比指定搜尋值大的值之索引位置,就這個程式而言,就是顯示 "插入點8" 的結果。 +在這個程式中,指定搜尋索引 6 到索引 9(不包括索引 9)的範圍中是否有 85 的值,如果找到的話,傳回索引值,如果沒有找到,傳回一個負值,該負值加 1 再乘以 -1,就是插入點位置,也就是第一個比指定搜尋值大的值之索引位置,就這個程式而言,就是顯示 "插入點 8" 的結果。 在 18.1.2 使用 Calendar 中,在範例 18.6 中使用 switch 進行判斷以顯示中文的日期格式,在 Java SE 6 中,您可以直接使用 getDisplayNames() 或 getDisplayName() 方法取得區域化的日期格式顯示,例如可以改寫範例 18.6 為以下的程式: @@ -154,7 +154,7 @@ public class CalendarDemo { 23 日 星期四 -在 Java SE 6 中,對於集合物件還增加有 Deque 介面(繼承自Queue介面)、NavigableMap 介面(繼承自 SortedMap 介面)、NavigableSet 介面(繼承自 SortedSet 介面),建議您可以查閱一下 API 文件,以了解這些集合物件的使用方式。 +在 Java SE 6 中,對於集合物件還增加有 Deque 介面(繼承自 Queue 介面)、NavigableMap 介面(繼承自 SortedMap 介面)、NavigableSet 介面(繼承自 SortedSet 介面),建議您可以查閱一下 API 文件,以了解這些集合物件的使用方式。 ### 21.1.3 java.io 套件 @@ -266,7 +266,7 @@ public class FileDemo { 在 Java SE 6 中對於視窗程式設計也作了極大的改進,雖然本書並沒有深入講解 Java 的視窗程式設計,然而在這邊可以介紹幾個有特色且使用簡單的功能。 -有些視窗程式在啟動時,會有個啟動畫面,在 Java SE 6 之前,您要自己實作才可以擁有這個功能,現在您可以直接在使用 "java" 程式執行程式時下達 "-splash" 引數指定啟動畫面的圖片,就可以擁有這個功能,例如若執行 19.5 所製作出來的 Executable Jar 檔時,如下指定圖片: +有些視窗程式在啟動時,會有個啟動畫面,在 Java SE 6 之前,您要自己實作才可以擁有這個功能,現在您可以直接在使用 "java" 程式執行程式時下達 `-splash` 引數指定啟動畫面的圖片,就可以擁有這個功能,例如若執行 19.5 所製作出來的 Executable Jar 檔時,如下指定圖片: java -splash:caterpillar.jpg -jar JNotePad.jar @@ -276,13 +276,13 @@ public class FileDemo { 圖 21.1 指定啟動畫面的執行結果 -您也可以在製作 Executable JAR 檔案時,於 manifest 檔案中指定 "SplashScreen-Image" 為啟動畫面的圖片,並在使用 jar 程式進行包裝時一併包裝圖片,如此啟動 JAR 檔案時,就會自動展現啟動畫面,一個 manifest 檔案的寫法如下所示: +您也可以在製作 Executable JAR 檔案時,於 manifest 檔案中指定 `SplashScreen-Image` 為啟動畫面的圖片,並在使用 jar 程式進行包裝時一併包裝圖片,如此啟動 JAR 檔案時,就會自動展現啟動畫面,一個 manifest 檔案的寫法如下所示: Manifest-Version: 1.0 Main-Class: onlyfun.caterpillar.JNotePad SplashScreen-Image: caterpillar.jpg -如果您對於啟動畫面更進一步的控制感興趣,例如在不同的啟動階段顯示不同的圖片,或者是在啟動圖片上顯示進度列,則可以看看 java.awt. SplashScreen 的 API 文件說明。 +如果您對於啟動畫面更進一步的控制感興趣,例如在不同的啟動階段顯示不同的圖片,或者是在啟動圖片上顯示進度列,則可以看看 java.awt.SplashScreen 的 API 文件說明。 在 Java SE 6 中加入了系統工具列圖示的支援,您可以使用 SystemTray 類別的 isSupported() 方法,測試看看目前的系統是否支援系統工具列圖示,如果支援的話,可以使用 getSystemTray() 取得 SystemTray 實例,使用 add() 方法加入 TrayIcon 實例,如此就可以加入一個系統工具列圖示,例如: @@ -357,8 +357,9 @@ public class SystemTrayDemo2 { 圖 21.3 系統工具列蹦現視窗 -如果要移除系統工具列中的圖示,則可以使用SystemTray實例的remove()方法,指定要移除的圖示,例如: -tray.remove(trayIcon); +如果要移除系統工具列中的圖示,則可以使用 SystemTray 實例的 remove() 方法,指定要移除的圖示,例如: + + tray.remove(trayIcon); ### 21.1.5 Classpath 簡化設定 @@ -380,7 +381,7 @@ Java SE 6 中包含了 JDBC 4.0,對於 JDBC 的使用有了相當的簡化, 目前對於 JDBC 4.0 支援的資料庫驅動程式還不多,在 JDK 6 中綑綁了 [Apache Derby 資料庫](http://db.apache.org/derby/),這是一個純 Java 撰寫的資料庫,支援 JDBC 4.0,您可以在 JDK 6 包裝目錄的 db 目錄下找到 Apache Derby 的相關檔案,也可以至 http://db.apache.org/derby/derby_downloads.html 下載 Apache Derby 資料庫,所下載的檔案中將包括更多的文件等相關資源。 -使用 Apache Derby 資料庫最簡單的方式之一,是使用 NetBeans IDE 來啟動、連接、管理 Derby 資料庫,您可以在 [Sun 官方網站](http://java.sun.com),或是 [NetBeans官方網站](http://www.netbeans.org/) 下載最新的 NetBeans IDE 並進行安裝,在這邊將以 NetBeans IDE 5.5 來示範,如何使用 Derby 資料庫。 +使用 Apache Derby 資料庫最簡單的方式之一,是使用 NetBeans IDE 來啟動、連接、管理 Derby 資料庫,您可以在 [Oracle 官方網站](http://www.oracle.com/technetwork/java/index.html),或是 [NetBeans 官方網站](http://www.netbeans.org/) 下載最新的 NetBeans IDE 並進行安裝,在這邊將以 NetBeans IDE 5.5 來示範,如何使用 Derby 資料庫。 首先,請啟動 NetBeans IDE,執行選單上的「Tools/Options」,接著選擇「Advanced Options」,在「IDE Configuration」中選擇「Server and External Tool Settings」的「Java DB Database」,接著在右邊的「Java DB Location」中設定 Apache Derby 的位置,在這邊是指向「C:\Program Files\Java\jdk1.6.0\db」,而在「Database Location」中設定您的資料庫儲存位置,在這邊是設定為「C:\workspace\database」,如下圖所示: @@ -430,23 +431,32 @@ Java SE 6 中包含了 JDBC 4.0,對於 JDBC 的使用有了相當的簡化, 圖 21.11 查詢表格資料 -關於Apache Derby的介紹先到這邊告一段落,接下來將要介紹,如何撰寫程式連接Apache Derby,並使用JDBC 4.0的新功能。 +關於 Apache Derby 的介紹先到這邊告一段落,接下來將要介紹,如何撰寫程式連接 Apache Derby,並使用 JDBC 4.0 的新功能。 + +### 21.2.2 載入驅動程式 + +在之前的操作中,可以從圖中看到,要連接 Apache Derby,使用的 JDBC URL 是 "jdbc:derby://localhost:1527/demo",而 Apache Derby 的 JDBC 驅動程式是放在 derbyclient.jar 之中,因此請記得在您的 Classpath 之中加以設定。 -21.2.2 載入驅動程式 -在之前的操作中,可以從圖中看到,要連接Apache Derby,使用的JDBC URL是" jdbc:derby://localhost:1527/demo",而Apache Derby的JDBC驅動程式是放在derbyclient.jar之中,因此請記得在您的Classpath之中加以設定。 -在JDBC 4.0之前,如果您要連接資料庫的話,必須使用Class.forName()並指定驅動程式類別名稱,以載入JDBC驅動程式,例如: +在 JDBC 4.0 之前,如果您要連接資料庫的話,必須使用 Class.forName() 並指定驅動程式類別名稱,以載入 JDBC 驅動程式,例如: + +``` String url = …; String username = …; String password = …; String driver = …; Class.forName(driver); Connection conn = DriverManager.getConnection(url, username, password); -在JDBC 4.0之中,不需要再呼叫Class.forName()並指定驅動程式了,也就是說,只要一行就可以了: -Connection conn = DriverManager.getConnection(url, username, password); -那麼JVM如何得知要載入哪個驅動程式呢?JVM會自動在Classpath中尋找適當的驅動程式,在包裝有JDBC驅動程式的JAR檔案中,必須有一個"META-INF/services/java.sql.Driver"檔案,當中撰寫驅動程式類別名稱,以Apache Derby為例,在derbyclient.jar中的"META-INF/services/java.sql.Driver"檔案中,撰寫的是"org.apache.derby.jdbc.ClientDriver "。 -以第20章的範例20.2為例,若使用JDBC 4.0,則可以將Class.forName()該行移除,並在執行時指定Classpath中包括derbyclient.jar的位置,而範例20.4仍然正常運行。 +``` + +在 JDBC 4.0 之中,不需要再呼叫 Class.forName() 並指定驅動程式了,也就是說,只要一行就可以了: + + Connection conn = DriverManager.getConnection(url, username, password); + +那麼 JVM 如何得知要載入哪個驅動程式呢? JVM 會自動在 Classpath 中尋找適當的驅動程式,在包裝有 JDBC 驅動程式的 JAR 檔案中,必須有一個 `META-INF/services/java.sql.Driver` 檔案,當中撰寫驅動程式類別名稱,以 Apache Derby 為例,在 derbyclient.jar 中的 `META-INF/services/java.sql.Driver` 檔案中,撰寫的是 `org.apache.derby.jdbc.ClientDriver`。 + +以第 20 章的範例 20.2 為例,若使用 JDBC 4.0,則可以將 Class.forName() 該行移除,並在執行時指定 Classpath 中包括 derbyclient.jar 的位置,而範例 20.4 仍然正常運行。 -### 21.2.2 改進的例外處理 +### 21.2.3 改進的例外處理 在 JDBC 4.0 之中,SQLException 新增了幾個建構函式,可以接受 Throwable 實例進行 SQLException 的建構,您可以重新將某個例外包裝為 SQLException,例如由於 IOException 發生的 SQLException,這表示您對於 SQLException 所發生的原因更加可以細分與掌握,SQLException 並實作了 `Iterable ` 介面,現在您可以在捕捉到 SQLException 時,使用加強的 for 迴圈來找出例外發生的原因,例如: @@ -468,7 +478,7 @@ catch(SQLException ex) { SQLException 在 JDBC 4.0 中多了幾個子類別,針對不同的錯誤將例外加以細分,您可以查看 API 文件中有關 SQLException 的說明。 -### 21.2.3 BLOB、CLOB 的改進 +### 21.2.4 BLOB、CLOB 的改進 在 20.2.3 中介紹過 JDBC 的 LOB 讀寫,當需要存入資料至 BLOB 或 CLOB 欄位時,要使用 PreparedStatement 的 setBinaryStream()、 setObject()、setAsciiStream()、setUnicodeStream() 等方法,在 API 名稱上並不是很明確。 diff --git a/example/CH15/SomeThread.java b/example/CH15/SomeThread.java index 724ad01..4cbcbe0 100644 --- a/example/CH15/SomeThread.java +++ b/example/CH15/SomeThread.java @@ -3,12 +3,14 @@ public class SomeThread implements Runnable { public void run() { System.out.println("sleep....至 blocked 狀態"); - try { - Thread.sleep(9999); - } - catch(InterruptedException e) { - System.out.println("I am interrupted...."); - } + while(true) { + try { + Thread.sleep(9999); + } + catch(InterruptedException e) { + System.out.println("I am interrupted...."); + } + } } public static void main(String[] args) {