課程網站:
相關文章:
解釋 RuntimeException。例舉它的1-2個子類,并用一個小程序驗證捕獲并處理異常的過程。
RuntimeException是Java中的一種異常類。與其他異常類不同,RuntimeException是非檢查型異常,而其他的都是檢查型異常。常見的RuntimeException的子類大約有以下幾種:
NullPointerException - 空指針引用異常
ClassCastException - 類型強制轉換異常。
IllegalArgumentException - 傳遞非法參數異常。
ArithmeticException - 算術運算異常
ArrayStoreException - 向數組中存放與聲明類型不兼容對象異常
IndexOutOfBoundsException - 下標越界異常
NegativeArraySizeException - 創建一個大小為負數的數組錯誤異常
NumberFormatException - 數字格式異常
SecurityException - 安全異常
UnsupportedOperationException - 不支持的操作異常
例子:NumberFormatException異常
public class Test {
public static void main(String args[]) {
int temp = Integer.parseInt("");
}
}
當執行這個程序的時候,將拋出NumberFormatException異常,如圖:
參考資料:
http://lelglin.iteye.com/blog/1454999
http://blog.csdn.net/feihong247/article/details/7873540
在生產實踐中,每個業務模塊都會定義一個異常基類,例如 Account 模塊定義 AccountException 繼承 Exception,然后在定義各種業務異常 如 OutOfMoneyException 繼承 AccountException。請使用 UML 繪圖工具 UMLet 繪制這些類及其關系。
UMLet介紹:
UMLet是一款特別棒的專業UML繪圖工具。可以更好地繪制UML,從而更容易分析軟件的架構。
下載地址:http://umlet.com/
UML圖:
類的方法中,如果拋出一個異常類型,方法聲明中能否不申明?例如 public void transfer(double amount) throws OutOfMoney 去掉 throws OutOfMoney。去掉的后果是什么?
不行。方法后面的throws主要是聲明這個方法會拋出這種類型的異常,使其他地方調用它時知道要捕獲這個異常,使得提醒必須做出處理。如果不申明throws編譯是不會通過的。
參考資料:
http://www.cnblogs.com/zhangzongle/p/5425843.html
Socket是兩個進程聯系的虛擬通道。如果服務器程序不啟動,僅運行客戶端,客戶端會阻塞還是出錯?在那條語句?
會出錯,拋出一個ConnectException異常。出錯語句為:
Socket server = new Socket(args[0], Integer.parseInt(args[1]));
即在建立客戶端的時候出錯。
如果程序運行到一半,服務端意外退出,客戶端會表現出什么行為?
如果不進行數據傳輸,則不會有問題;如果向服務端發出數據,客戶端將拋出一個SocketException異常,然后中止了程序。
(!)BufferedReader in=new BufferedReader(new InputStreamReader(server.getInputStream())); 語句是典型的設計模式“裝飾模式”,請檢索自學“Decorator Pattern”,請使用 UML 繪圖工具 UMLet 繪制涉及的類及其關系。
……
案例中 ServerSocket 能否支持兩個或以上客戶端?為什么?
不能支持兩個。因為在代碼中,只實現了接受一個服務端。
Socket client = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream());
如果要支持多個,就需要開多線程。
線程與進程的區別?
進程是運行中的程序。線程是進程的一個實體,是CPU調度的基本單位。兩者有幾個主要區別:
- 一個程序至少有一個進程,一個進程至少有一個線程.
- 線程的劃分尺度小于進程,使得多線程程序的并發性高。
- 另外,進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率。
- 線程在執行過程中與進程還是有區別的。每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。
- 從邏輯角度來看,多線程的意義在于一個應用程序中,有多個執行部分可以同時執行。但操作系統并沒有將多個線程看做多個獨立的應用,來實現進程的調度和管理以及資源分配。這就是進程和線程的重要區別。
參考資料:
http://blog.csdn.net/yaosiming2011/article/details/44280797
Java 兩個啟動線程方法各有哪些優點、缺點?
Java實際上有三種啟動線程的方式:
- 繼承Thread
public class java_thread extends Thread {
public static void main(String args[])
{
(new java_thread()).run();
System.out.println("main thread run ");
}
public synchronized void run()
{
System.out.println("sub thread run ");
}
}
- 實現Runnable接口
public class java_thread implements Runnable {
public static void main(String args[])
{
(new Thread(new java_thread())).start();
System.out.println("main thread run ");
}
public void run()
{
System.out.println("sub thread run ");
}
}
- 直接在函數體使用
void java_thread()
{
Thread t = new Thread(new Runnable(){
public void run(){
mSoundPoolMap.put(index, mSoundPool.load(filePath, index));
getThis().LoadMediaComplete();
}});
t.start();
}
三種方式的優缺點比較
實現Runnable接口優勢:
- 適合多個相同的程序代碼的線程去處理同一個資源
- 可以避免java中的單繼承的限制
- 增加程序的健壯性,代碼可以被多個線程共享,代碼和數據獨立。
繼承Thread類優勢:
- 可以將線程類抽象出來,當需要使用抽象工廠模式設計時。
- 多線程同步
在函數體使用優勢:
- 無需繼承thread或者實現Runnable,縮小作用域。
參考資料:
http://blog.csdn.net/typename/article/details/7212512
(!)簡述 Java 中 synchronized 的用法。
synchronized是Java中的關鍵字,是一種同步鎖。用同步鎖可以保證,在多線程的情況下,防止操作互相沖突。
synchronized大概有四種用法:
- 修飾某段代碼塊:
synchronized(this) {
// Todo
}
- 修飾某個對象:
synchronized(obj) {
// Todo
}
- 修飾某個方法:
public synchronized void run() {
// Todo
}
- 修改一個類:
synchronized(ClassName.class) {
// todo
}
參考資料:
http://blog.csdn.net/luoweifu/article/details/46613015
對象序列化二進制流中能否存在指針值(內存地址引用)?為什么?
不能。因為序列化的目的是為了儲存對象,以便未來通過反序列化把對象再提取出來。如果存在內存地址,那么下次提取的時候,對應的地址就有可能不是原來的地址,從而導致程序崩潰。
(!)為了使序列化和反序列化變得易于理解,人們提出了使用 Json,XML,Yaml等格式的文本表示對象。請寫一個小程序,選擇其中一種格式,在控制臺輸出Account對象
轉化為XML可以用XStream。但是用XStream首先需要兩個jar包:
- xpp3_min-1.1.4c.jar
- xstream-1.3.jar
代碼如下:
import com.thoughtworks.xstream.XStream;
public class Test {
public static void main(String[]args) {
Account obj = new Account();
XStream xStream = new XStream();
xStream.alias("obj", obj.class);
String xml = xStream.toXML(obj);
System.out.println(xml);
}
}
參考資料:
http://blog.csdn.net/baple/article/details/18219099
instanceof 很好用,為什么需要反射技術呢?請結合案例簡述反射的必要性。
反射技術:
主要是指程序可以訪問,檢測和修改它本身狀態或行為的一種能力,并能根據自身行為的狀態和結果,調整或修改應用所描述行為的狀態和相關的語義。
反射是Java中一種強大的工具,能夠使我們很方便的創建靈活的代碼,這些代碼可以再運行時裝配,無需在組件之間進行源代碼鏈接。但是反射使用不當會成本很高!
例如,我們可以通過三種方式獲取類:
//第一種方式:
Classc1 = Class.forName("Employee");
//第二種方式:
//java中每個類型都有class 屬性.
Classc2 = Employee.class;
//第三種方式:
//java語言中任何一個java對象都有getClass 方法
Employeee = new Employee();
Classc3 = e.getClass(); //c3是運行時類 (e的運行時類是Employee)
然后獲取類之后,我們就可以直接創建對象或者獲取類的屬性。這樣在編程的時候就可以更加靈活,更加簡單。
例如如果我們要找一個對象是不是某個類的特例,如果用instanceof就比一般的機制簡單。
參考資料:
http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html
http://blog.csdn.net/liujiahan629629/article/details/18013523
代理模式(proxy pattern)的特征是代理類與委托類有同樣的接口。請使用 UML 繪圖工具 UMLet 繪制案例代理模式的 UML 圖(圖8),并用自然語言簡單描述靜態代理類 StaticServiceProxy 的工作過程。
StaticServiceProxy 除了構造方法,只有getAccount方法。代碼如下:
public String getAccount(String Name) {
Connector connector = null;
try {
connector = new Connector(host, port);
RemoteCall call = new RemoteCall("AccountService", "getAccount", new Class[] { String.class }, new Object[] { Name });
connector.send(call);
call = (RemoteCall)connector.receive();
Object result = call.getResult();
return (String)result;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connector != null) connector.close();
}
return Name;
}
簡述靜態代理和動態代理的區別。
靜態代理:
由程序員創建或工具生成代理類的源碼,再編譯代理類。所謂靜態也就是在程序運行前就已經存在代理類的字節碼文件,代理類和委托類的關系在運行前就確定了。
靜態代理類優缺點
優點:業務類只需要關注業務邏輯本身,保證了業務類的重用性。這是代理的共有優點。
缺點:
- 代理對象的一個接口只服務于一種類型的對象,如果要代理的方法很多,勢必要為每一種方法都進行代理,靜態代理在程序規模稍大時就無法勝任了。
- 如果接口增加一個方法,除了所有實現類需要實現這個方法外,所有代理類也需要實現此方法。增加了代碼維護的復雜度。
動態代理
動態代理類的源碼是在程序運行期間由JVM根據反射等機制動態的生成,所以不存在代理類的字節碼文件。代理類和委托類的關系是在程序運行時確定。
動態代理類優缺點
優點:
動態代理與靜態代理相比較,最大的好處是接口中聲明的所有方法都被轉移到調用處理器一個集中的方法中處理(InvocationHandler.invoke)。這樣,在接口方法數量比較多的時候,我們可以進行靈活處理,而不需要像靜態代理那樣每一個方法進行中轉。在本示例中看不出來,因為invoke方法體內嵌入了具體的外圍業務(記錄任務處理前后時間并計算時間差),實際中可以類似Spring AOP那樣配置外圍業務。
缺點:
誠然,Proxy 已經設計得非常優美,但是還是有一點點小小的遺憾之處,那就是它始終無法擺脫僅支持 interface 代理的桎梏,因為它的設計注定了這個遺憾。回想一下那些動態生成的代理類的繼承關系圖,它們已經注定有一個共同的父類叫 Proxy。Java 的繼承機制注定了這些動態代理類們無法實現對 class 的動態代理,原因是多繼承在 Java 中本質上就行不通。
有很多條理由,人們可以否定對 class 代理的必要性,但是同樣有一些理由,相信支持 class 動態代理會更美好。接口和類的劃分,本就不是很明顯,只是到了 Java 中才變得如此的細化。如果只從方法的聲明及是否被定義來考量,有一種兩者的混合體,它的名字叫抽象類。實現對抽象類的動態代理,相信也有其內在的價值。此外,還有一些歷史遺留的類,它們將因為沒有實現任何接口而從此與動態代理永世無緣。如此種種,不得不說是一個小小的遺憾。