20145207 《Java程序设计》第5周学习总结
前言:先聊兩句,上午電路實習(xí),剛開始沒多久就讓電烙鐵燙了,倒霉催的~晚上來這里接著弄代碼,透心涼心飛揚~
教材學(xué)習(xí)內(nèi)容總結(jié)
一、異常處理
1.語法與繼承結(jié)構(gòu)
使用try、catch: Java中所有錯誤都會被包裝成對象,可以嘗試(try)執(zhí)行程序并捕捉(catch)代表錯誤的對象后做一些處理。使用了try、catch語法,JVM會嘗試執(zhí)行try區(qū)塊中的程序代碼,如果發(fā)生錯誤,執(zhí)行程序會跳離錯誤發(fā)生點,然后比對catch括號中聲明的類型,是否符合被拋出的錯誤對象類型,如果是就執(zhí)行catch中的程序代碼。
程序中總有一些意想不到的狀況所引發(fā)的錯誤,Java中的錯誤也以對象方式呈現(xiàn)為java.lang.Throwable的各種子類實例。只要能捕捉包裝錯誤的對象,就可以針對該錯誤做一些處理。
在這里舉一個書上的列子關(guān)于使用try和catch的例子。
package ch08;
?
import java.util.Scanner;
public class Average {
??? public static void main(String[] args) {
??????? Scanner console = new Scanner(System.in);
??????? double sum = 0;
??????? int count = 0;
??????? while (true) {
??????????? int number = console.nextInt();
??????????? if (number == 0) {
??????????????? break;
??????????? }
??????????? sum += number;
??????????? count++;
??????? }
??????? System.out.printf("平均 %.2f%n", sum / count);
??? }
}
在這個程序中,輸入正確的數(shù)字,會計算出平均數(shù),結(jié)果如下:
?????
?
?????????
但是,若是不小心輸入了并非int的值,就會出現(xiàn)如下的情況:
?
這是另一個關(guān)于輸入錯誤的代碼,對其一部分進(jìn)行了判斷并糾正
package ch08;
?
import java.util.Scanner;
public class Average {
??? public static void main(String[] args) {
??????? Scanner console = new Scanner(System.in);
??????? double sum = 0;
??????? int count = 0;
??????? while (true) {
??????????? int number = console.nextInt();
??????????? if (number == 0) {
??????????????? break;
??????????? }
??????????? sum += number;
??????????? count++;
??????? }
??????? System.out.printf("平均 %.2f%n", sum / count);
??? }
}
若是輸入錯誤,就會出現(xiàn)以下的結(jié)果:
?
2.異常繼承結(jié)構(gòu)
錯誤會被包裝為對象,這些對象均可拋出,因此設(shè)計錯誤對象都繼承自java.lang.Throwable類,Throwable定義了取得錯誤信息、堆棧追蹤(Stack Trace)等方法,它有兩個子類:java.lang.Error與java.lang.Exception。在此簡述一下Error類與Exception類的區(qū)別,在Java中對于比較嚴(yán)重的問題,是通過Error類來進(jìn)行描述的,而對于非嚴(yán)重的問題,則是通過Exception類來進(jìn)行描述的。對于Error,一般不編寫針對性的代碼對其進(jìn)行處理,因為此時已經(jīng)超出了JVM的運行能力范圍之外了。
單就語法與繼承架構(gòu)上來說,如果某個方法聲明會拋出Throwable或子類實例,只要不是屬于Error或java.lang.RuntimeException或其子類實例,就必須明確使用try、catch語法加以處理,或者在方法中用throws聲明這個方法會拋出異常,否則會編譯失敗,throws的使用也提高了代碼的安全性。
Exception中有一個特殊的子類異常叫RuntimeException異常,就是運行時異常,它的特點是如果在函數(shù)內(nèi)容拋出該異常,函數(shù)上可以不用聲明,編譯一樣通過,如果在函數(shù)上聲明了該異常,調(diào)用者可以不用進(jìn)行處理,編譯一樣通過。Exception或其子對象,但非屬于RuntimeException或其子類對象,稱為受檢異常(Checked Exception),屬于RuntimeException衍生出來的類實例亦稱為非受檢異常(Unchecked Exception),受檢異常存在的目的,在于API設(shè)計者實現(xiàn)某方法時,某些條件成立時會引發(fā)錯誤,而且認(rèn)為調(diào)用方法的客戶端有能力處理錯誤,要求編譯程序提醒客戶端必須明確處理錯誤,不然不可通過編譯,API客戶端無權(quán)選擇要不要處理。
如果父類異常對象在子類異常對象前被捕捉,則catch子類異常對象將永遠(yuǎn)不會被執(zhí)行,編譯程序會檢查出這個錯誤。從JDK7開始,可以使用多重捕捉語法,不過仍需注意異常的繼承,catch括號中列出的異常不得有繼承關(guān)系,否則會發(fā)生編譯錯誤。
在catch區(qū)塊進(jìn)行完部分錯誤處理之后,可以使用throw將異常再度拋出,這里將throw和throws要區(qū)分開,throws使用在函數(shù)上,后面跟的是異常類,可以跟多個,用逗號隔開,而throw是使用在函數(shù)內(nèi),后面跟的是異常對象。
若想得知異常發(fā)生的根源,以及多重方法調(diào)用下異常的堆棧傳播,可以利用異常對象自動收集的堆棧追蹤來取得相關(guān)信息,例如調(diào)用異常對象的printStackTrace()、getStackTrace()等方法。要善于堆棧追蹤,前提是程序代碼中不可有私吞異常的行為、對異常做了不適當(dāng)?shù)奶幚?#xff0c;或顯示了不正確信息。在使用throw重拋異常時,異常的追蹤堆棧起點,仍是異常的發(fā)生根源,而不是重拋異常的地方。如果想要讓異常堆棧起點為重拋異常的地方,可以使用fillInStackTrace(),這個方法會重新裝填異常堆棧,將起點設(shè)為重拋異常的地方,并返回Throwable對象。
3.異常與資源管理
程序中因錯誤而拋出異常時,原本的執(zhí)行流程就會中斷,拋出異常處之后的程序代碼就不會被執(zhí)行,如果程序開啟了相關(guān)資源,是否在使用完畢后被關(guān)閉了呢?
finally區(qū)塊
最后一定要執(zhí)行關(guān)閉資源的動作,try、catch語法還可以搭配finally,無論try區(qū)塊中有無發(fā)生異常,若撰寫finally區(qū)塊,則finally區(qū)塊一定會被執(zhí)行。舉一個例子:
package ch08;
?
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
?
public class FileUtil {
??? public static String readFile(String name) throws FileNotFoundException {
??????? StringBuilder text = new StringBuilder();
??????? try {
??????????? Scanner console = new Scanner(new FileInputStream(name));
??????????? while (console.hasNext()) {
??????????????? text.append(console.nextLine()).append('\n');
??????????? }
??????? } catch (FileNotFoundException ex) {
??????????? ex.printStackTrace();
??????????? throw ex;
??????? }
??????? return text.toString();
??? }
}
由于finally區(qū)塊一定會被執(zhí)行,在這個范例中scanner原先是null,若FileInputStream創(chuàng)建失敗,則scanner就有可能還是null,因此在finally區(qū)塊中必須先檢查scanner是否有參考對象,有的話才進(jìn)一步調(diào)用close()方法,否則scanner參考至null又打算調(diào)用close()方法,反而會拋出NullPointerException。
想要嘗試關(guān)閉資源(Try-With-Resources)的對象,是撰寫在try之后的括號中,如果無須catch處理任何異常,可以不用撰寫,也不要撰寫finally。嘗試關(guān)閉資源語法可套用的對象,必須操作java.lang.AutoCloseable接口,該語法也可以同時關(guān)閉兩個以上的對象資源,只要中間以分號隔開。在try的括號中,越后面撰寫的對象資源會越早被關(guān)閉。
二、Collection與Map
1.認(rèn)識Collection架構(gòu)
JavaSE提供了滿足各種需求的API,在使用這些API前,建議先了解其繼承與接口的操作架構(gòu),才能了解何時該采用哪個類,以及類之間如何彼此合作,而不會淪為死背API或抄寫范例的境界。
收集對象的行為,像是新增對象的add()方法、移除對象的remove()方法等,都是定義在java.util.Collection中。既然可以收集對象,也要能逐一取得對象,這就是java.lang.Iterable定義的行為,它定義了iterable()方法返回java.util.Iterator操作對象,可以讓你逐一取得收集的對象。Collection接口中有三個子接口,分別是List、Set和Queue。如果希望收集時記錄記錄每個對象的索引順序,并可依索引取回對象,可以使用java.util.List接口,如果希望收集的對象不重復(fù),具有集合的行為,可以使用java.util.Set接口,如果希望收集對象時以隊列方式,收集的對象假如至尾端,取得對象時從前端,則可以使用java.util.Queue接口,如果希望對Queue的兩端進(jìn)行加入、移除等操作,則可以使用java.util.Deque。
2.鍵值對應(yīng)的Map
就如同網(wǎng)絡(luò)搜素,根據(jù)關(guān)鍵字可找到對應(yīng)的數(shù)據(jù),程序設(shè)計中也常有這類的需求,根據(jù)某個鍵來取得對應(yīng)的值。可以事先利用java.util.Map接口操作對象來建立鍵值對應(yīng)數(shù)據(jù),之后若要取得值,只要用對應(yīng)的鍵,只要用對應(yīng)的鍵就可以迅速取得。
常用Map操作類有HashMap、TreeMap和Properties。HashMap的特點是線程不安全,速度快,允許存放null 鍵,null值,TreeMap會對鍵進(jìn)行排序,條件是作為鍵的對象必須操作Comparable接口,或者是在創(chuàng)建TreeMap時指定操作Comparable接口的對象,Properties的setProperty()可以指定字符串類型的鍵值,getProperty()可以指定字符串類型的鍵,取回字符串類型的值,通常稱為屬性名稱與屬性值。
教材學(xué)習(xí)中的問題和解決過程
書中P295 MapKeyValue.java運行結(jié)果與書中采用HashMap顯示不同
import java.util.*;
import static java.lang.System.out;
?
public class MapKeyValue {
public static void main(String[] args) {
??? Map<String, String> map = new HashMap<>();
??? map.put("one", "一");
??? map.put("two", "二");
??? map.put("three", "三");
???
??? out.println("顯示鍵");
??? // keySet()返回set
??? map.keySet().forEach(key -> out.println(key));
???
??? out.println("顯示值");
??? // values()返回Collection
??? map.values().forEach(key -> out.println(key));
}
}
代碼調(diào)試中的問題和解決過程
在這兩章中我發(fā)現(xiàn)了有些東西按照書上來的話,是沒有辦法編譯通過的,還有就是例如266頁的代碼,他也是前后使用的變量名不一樣,前面定義的是object o,后面就拉過來一個elem,我覺得書上有錯誤是正常的,剛好可以順便檢測我們對于書上以前的內(nèi)容是否真的了解,以及是否看懂了這段代碼。附上266頁的代碼:
package ch08;
?
public class SimpleLinkedList {
??? private class Node {
??????? Node(Object o) {
??????????? this.o = o;
??????? }
??????? Object o;
??????? Node next;
??? }
??? private Node first;
?
??? public void add(Object o) {
??????? Node node = new Node(o);
??????? if (first == null) {
??????????? first = node;
??????? } else {
??????????? append(node);
??????? }
??? }
?
??? private void append(Node node) {
??????? Node last = first;
??????? while (last.next != null) {
??????????? last = last.next;
??????? }
??????? last.next = node;
??? }
?
??? public int size() {
??????? int count = 0;
??????? Node last = first;
??????? while (last != null) {
??????????? last = last.next;
??????????? count++;
??????? }
??????? return count;
??? }
?
??? public Object get(int index) {
??????? checkSize(index);
??????? return findElemOf(index);
??? }
?
??? private void checkSize(int index) throws IndexOutOfBoundsException {
??????? int size = size();
??????? if (index >= size) {
??????????? throw new IndexOutOfBoundsException(
??????????????????? String.format("Index: %d,Size: %d", index, size));
??????? }
??? }
?
??? private Object findElemOf(int index) {
??????? int count = 0;
??????? Node last = first;
??????? while (count < index) {
??????????? last = last.next;
??????????? count++;
??????? }
??????? return last.o;
??? }
?
?
}
在收集對象之后,對對象進(jìn)行排序是常用的動作,你不用親自操作排序算法,java.util.Collections提供有sort()方法。由于必須有索引才能進(jìn)行排序,因此Collections的sort()方法接受List操作對象。
import java.util.*;
public class Sort {
??? public static void main(String[] args) {
??????? List numbers = Arrays.asList(10,2,3,1,9,15,4);
??????? Collections.sort(numbers);
??????? System.out.println(numbers);
??? }
}
心得與體會
心得:實習(xí)好無聊~體會:實習(xí)完敲代碼好累…
轉(zhuǎn)載于:https://www.cnblogs.com/20145207lza/p/5819427.html
總結(jié)
以上是生活随笔為你收集整理的20145207 《Java程序设计》第5周学习总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux定时任务Crontab学习笔记
- 下一篇: 【设计模式之单例模式InJava】