課程網(wǎng)站:
相關(guān)文章:
- 第一課:Java進(jìn)階與Socket通訊實(shí)驗(yàn)
- 第二課:Socket通訊與HTTP服務(wù)器
- 第三課:Java Web 編程原理
- 第四課:RESTful Webservice 編程
解釋 RuntimeException乒融。例舉它的1-2個(gè)子類,并用一個(gè)小程序驗(yàn)證捕獲并處理異常的過(guò)程弥搞。
RuntimeException是Java中的一種異常類。與其他異常類不同市殷,RuntimeException是非檢查型異常屈尼,而其他的都是檢查型異常篡撵。常見(jiàn)的RuntimeException的子類大約有以下幾種:
NullPointerException - 空指針引用異常
ClassCastException - 類型強(qiáng)制轉(zhuǎn)換異常。
IllegalArgumentException - 傳遞非法參數(shù)異常坷澡。
ArithmeticException - 算術(shù)運(yùn)算異常
ArrayStoreException - 向數(shù)組中存放與聲明類型不兼容對(duì)象異常
IndexOutOfBoundsException - 下標(biāo)越界異常
NegativeArraySizeException - 創(chuàng)建一個(gè)大小為負(fù)數(shù)的數(shù)組錯(cuò)誤異常
NumberFormatException - 數(shù)字格式異常
SecurityException - 安全異常
UnsupportedOperationException - 不支持的操作異常
例子:NumberFormatException異常
public class Test {
public static void main(String args[]) {
int temp = Integer.parseInt("");
}
}
當(dāng)執(zhí)行這個(gè)程序的時(shí)候托呕,將拋出NumberFormatException異常,如圖:
參考資料:
http://lelglin.iteye.com/blog/1454999
http://blog.csdn.net/feihong247/article/details/7873540
在生產(chǎn)實(shí)踐中,每個(gè)業(yè)務(wù)模塊都會(huì)定義一個(gè)異诚罱迹基類馅扣,例如 Account 模塊定義 AccountException 繼承 Exception,然后在定義各種業(yè)務(wù)異常 如 OutOfMoneyException 繼承 AccountException着降。請(qǐng)使用 UML 繪圖工具 UMLet 繪制這些類及其關(guān)系差油。
UMLet介紹:
UMLet是一款特別棒的專業(yè)UML繪圖工具∪味矗可以更好地繪制UML蓄喇,從而更容易分析軟件的架構(gòu)。
下載地址:http://umlet.com/
UML圖:
類的方法中侈咕,如果拋出一個(gè)異常類型公罕,方法聲明中能否不申明?例如 public void transfer(double amount) throws OutOfMoney 去掉 throws OutOfMoney耀销。去掉的后果是什么楼眷?
不行。方法后面的throws主要是聲明這個(gè)方法會(huì)拋出這種類型的異常熊尉,使其他地方調(diào)用它時(shí)知道要捕獲這個(gè)異常罐柳,使得提醒必須做出處理。如果不申明throws編譯是不會(huì)通過(guò)的狰住。
參考資料:
http://www.cnblogs.com/zhangzongle/p/5425843.html
Socket是兩個(gè)進(jìn)程聯(lián)系的虛擬通道张吉。如果服務(wù)器程序不啟動(dòng),僅運(yùn)行客戶端催植,客戶端會(huì)阻塞還是出錯(cuò)肮蛹?在那條語(yǔ)句?
會(huì)出錯(cuò)创南,拋出一個(gè)ConnectException異常伦忠。出錯(cuò)語(yǔ)句為:
Socket server = new Socket(args[0], Integer.parseInt(args[1]));
即在建立客戶端的時(shí)候出錯(cuò)。
如果程序運(yùn)行到一半稿辙,服務(wù)端意外退出昆码,客戶端會(huì)表現(xiàn)出什么行為?
如果不進(jìn)行數(shù)據(jù)傳輸邻储,則不會(huì)有問(wèn)題赋咽;如果向服務(wù)端發(fā)出數(shù)據(jù),客戶端將拋出一個(gè)SocketException異常吨娜,然后中止了程序脓匿。
(!)BufferedReader in=new BufferedReader(new InputStreamReader(server.getInputStream())); 語(yǔ)句是典型的設(shè)計(jì)模式“裝飾模式”萌壳,請(qǐng)檢索自學(xué)“Decorator Pattern”亦镶,請(qǐng)使用 UML 繪圖工具 UMLet 繪制涉及的類及其關(guān)系日月。
……
案例中 ServerSocket 能否支持兩個(gè)或以上客戶端?為什么缤骨?
不能支持兩個(gè)爱咬。因?yàn)樵诖a中,只實(shí)現(xiàn)了接受一個(gè)服務(wù)端绊起。
Socket client = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream());
如果要支持多個(gè)精拟,就需要開(kāi)多線程。
線程與進(jìn)程的區(qū)別虱歪?
進(jìn)程是運(yùn)行中的程序蜂绎。線程是進(jìn)程的一個(gè)實(shí)體,是CPU調(diào)度的基本單位笋鄙。兩者有幾個(gè)主要區(qū)別:
- 一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程.
- 線程的劃分尺度小于進(jìn)程师枣,使得多線程程序的并發(fā)性高。
- 另外萧落,進(jìn)程在執(zhí)行過(guò)程中擁有獨(dú)立的內(nèi)存單元践美,而多個(gè)線程共享內(nèi)存,從而極大地提高了程序的運(yùn)行效率找岖。
- 線程在執(zhí)行過(guò)程中與進(jìn)程還是有區(qū)別的陨倡。每個(gè)獨(dú)立的線程有一個(gè)程序運(yùn)行的入口、順序執(zhí)行序列和程序的出口许布。但是線程不能夠獨(dú)立執(zhí)行兴革,必須依存在應(yīng)用程序中,由應(yīng)用程序提供多個(gè)線程執(zhí)行控制蜜唾。
- 從邏輯角度來(lái)看杂曲,多線程的意義在于一個(gè)應(yīng)用程序中,有多個(gè)執(zhí)行部分可以同時(shí)執(zhí)行袁余。但操作系統(tǒng)并沒(méi)有將多個(gè)線程看做多個(gè)獨(dú)立的應(yīng)用解阅,來(lái)實(shí)現(xiàn)進(jìn)程的調(diào)度和管理以及資源分配。這就是進(jìn)程和線程的重要區(qū)別泌霍。
參考資料:
http://blog.csdn.net/yaosiming2011/article/details/44280797
Java 兩個(gè)啟動(dòng)線程方法各有哪些優(yōu)點(diǎn)、缺點(diǎn)述召?
Java實(shí)際上有三種啟動(dòng)線程的方式:
- 繼承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 ");
}
}
- 實(shí)現(xiàn)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 ");
}
}
- 直接在函數(shù)體使用
void java_thread()
{
Thread t = new Thread(new Runnable(){
public void run(){
mSoundPoolMap.put(index, mSoundPool.load(filePath, index));
getThis().LoadMediaComplete();
}});
t.start();
}
三種方式的優(yōu)缺點(diǎn)比較
實(shí)現(xiàn)Runnable接口優(yōu)勢(shì):
- 適合多個(gè)相同的程序代碼的線程去處理同一個(gè)資源
- 可以避免java中的單繼承的限制
- 增加程序的健壯性朱转,代碼可以被多個(gè)線程共享,代碼和數(shù)據(jù)獨(dú)立积暖。
繼承Thread類優(yōu)勢(shì):
- 可以將線程類抽象出來(lái)藤为,當(dāng)需要使用抽象工廠模式設(shè)計(jì)時(shí)。
- 多線程同步
在函數(shù)體使用優(yōu)勢(shì):
- 無(wú)需繼承thread或者實(shí)現(xiàn)Runnable夺刑,縮小作用域缅疟。
參考資料:
http://blog.csdn.net/typename/article/details/7212512
(7直稹)簡(jiǎn)述 Java 中 synchronized 的用法。
synchronized是Java中的關(guān)鍵字存淫,是一種同步鎖耘斩。用同步鎖可以保證,在多線程的情況下桅咆,防止操作互相沖突括授。
synchronized大概有四種用法:
- 修飾某段代碼塊:
synchronized(this) {
// Todo
}
- 修飾某個(gè)對(duì)象:
synchronized(obj) {
// Todo
}
- 修飾某個(gè)方法:
public synchronized void run() {
// Todo
}
- 修改一個(gè)類:
synchronized(ClassName.class) {
// todo
}
參考資料:
http://blog.csdn.net/luoweifu/article/details/46613015
對(duì)象序列化二進(jìn)制流中能否存在指針值(內(nèi)存地址引用)?為什么岩饼?
不能荚虚。因?yàn)樾蛄谢哪康氖菫榱藘?chǔ)存對(duì)象,以便未來(lái)通過(guò)反序列化把對(duì)象再提取出來(lái)籍茧。如果存在內(nèi)存地址版述,那么下次提取的時(shí)候,對(duì)應(yīng)的地址就有可能不是原來(lái)的地址寞冯,從而導(dǎo)致程序崩潰渴析。
(!)為了使序列化和反序列化變得易于理解简十,人們提出了使用 Json檬某,XML,Yaml等格式的文本表示對(duì)象螟蝙。請(qǐng)寫(xiě)一個(gè)小程序恢恼,選擇其中一種格式,在控制臺(tái)輸出Account對(duì)象
轉(zhuǎn)化為XML可以用XStream胰默。但是用XStream首先需要兩個(gè)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 很好用场斑,為什么需要反射技術(shù)呢?請(qǐng)結(jié)合案例簡(jiǎn)述反射的必要性牵署。
反射技術(shù):
主要是指程序可以訪問(wèn)漏隐,檢測(cè)和修改它本身狀態(tài)或行為的一種能力,并能根據(jù)自身行為的狀態(tài)和結(jié)果奴迅,調(diào)整或修改應(yīng)用所描述行為的狀態(tài)和相關(guān)的語(yǔ)義青责。
反射是Java中一種強(qiáng)大的工具,能夠使我們很方便的創(chuàng)建靈活的代碼取具,這些代碼可以再運(yùn)行時(shí)裝配脖隶,無(wú)需在組件之間進(jìn)行源代碼鏈接。但是反射使用不當(dāng)會(huì)成本很高暇检!
例如产阱,我們可以通過(guò)三種方式獲取類:
//第一種方式:
Classc1 = Class.forName("Employee");
//第二種方式:
//java中每個(gè)類型都有class 屬性.
Classc2 = Employee.class;
//第三種方式:
//java語(yǔ)言中任何一個(gè)java對(duì)象都有g(shù)etClass 方法
Employeee = new Employee();
Classc3 = e.getClass(); //c3是運(yùn)行時(shí)類 (e的運(yùn)行時(shí)類是Employee)
然后獲取類之后,我們就可以直接創(chuàng)建對(duì)象或者獲取類的屬性块仆。這樣在編程的時(shí)候就可以更加靈活构蹬,更加簡(jiǎn)單王暗。
例如如果我們要找一個(gè)對(duì)象是不是某個(gè)類的特例,如果用instanceof就比一般的機(jī)制簡(jiǎn)單庄敛。
參考資料:
http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html
http://blog.csdn.net/liujiahan629629/article/details/18013523
代理模式(proxy pattern)的特征是代理類與委托類有同樣的接口俗壹。請(qǐng)使用 UML 繪圖工具 UMLet 繪制案例代理模式的 UML 圖(圖8),并用自然語(yǔ)言簡(jiǎn)單描述靜態(tài)代理類 StaticServiceProxy 的工作過(guò)程铐姚。
StaticServiceProxy 除了構(gòu)造方法策肝,只有g(shù)etAccount方法。代碼如下:
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;
}
簡(jiǎn)述靜態(tài)代理和動(dòng)態(tài)代理的區(qū)別隐绵。
靜態(tài)代理:
由程序員創(chuàng)建或工具生成代理類的源碼之众,再編譯代理類。所謂靜態(tài)也就是在程序運(yùn)行前就已經(jīng)存在代理類的字節(jié)碼文件依许,代理類和委托類的關(guān)系在運(yùn)行前就確定了棺禾。
靜態(tài)代理類優(yōu)缺點(diǎn)
優(yōu)點(diǎn):業(yè)務(wù)類只需要關(guān)注業(yè)務(wù)邏輯本身,保證了業(yè)務(wù)類的重用性峭跳。這是代理的共有優(yōu)點(diǎn)膘婶。
缺點(diǎn):
- 代理對(duì)象的一個(gè)接口只服務(wù)于一種類型的對(duì)象,如果要代理的方法很多蛀醉,勢(shì)必要為每一種方法都進(jìn)行代理雾消,靜態(tài)代理在程序規(guī)模稍大時(shí)就無(wú)法勝任了愈捅。
- 如果接口增加一個(gè)方法粥脚,除了所有實(shí)現(xiàn)類需要實(shí)現(xiàn)這個(gè)方法外纵揍,所有代理類也需要實(shí)現(xiàn)此方法。增加了代碼維護(hù)的復(fù)雜度垛玻。
動(dòng)態(tài)代理
動(dòng)態(tài)代理類的源碼是在程序運(yùn)行期間由JVM根據(jù)反射等機(jī)制動(dòng)態(tài)的生成割捅,所以不存在代理類的字節(jié)碼文件。代理類和委托類的關(guān)系是在程序運(yùn)行時(shí)確定帚桩。
動(dòng)態(tài)代理類優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
動(dòng)態(tài)代理與靜態(tài)代理相比較亿驾,最大的好處是接口中聲明的所有方法都被轉(zhuǎn)移到調(diào)用處理器一個(gè)集中的方法中處理(InvocationHandler.invoke)。這樣账嚎,在接口方法數(shù)量比較多的時(shí)候莫瞬,我們可以進(jìn)行靈活處理,而不需要像靜態(tài)代理那樣每一個(gè)方法進(jìn)行中轉(zhuǎn)郭蕉。在本示例中看不出來(lái)乏悄,因?yàn)閕nvoke方法體內(nèi)嵌入了具體的外圍業(yè)務(wù)(記錄任務(wù)處理前后時(shí)間并計(jì)算時(shí)間差),實(shí)際中可以類似Spring AOP那樣配置外圍業(yè)務(wù)恳不。
缺點(diǎn):
誠(chéng)然,Proxy 已經(jīng)設(shè)計(jì)得非常優(yōu)美开呐,但是還是有一點(diǎn)點(diǎn)小小的遺憾之處烟勋,那就是它始終無(wú)法擺脫僅支持 interface 代理的桎梏规求,因?yàn)樗脑O(shè)計(jì)注定了這個(gè)遺憾÷训耄回想一下那些動(dòng)態(tài)生成的代理類的繼承關(guān)系圖阻肿,它們已經(jīng)注定有一個(gè)共同的父類叫 Proxy。Java 的繼承機(jī)制注定了這些動(dòng)態(tài)代理類們無(wú)法實(shí)現(xiàn)對(duì) class 的動(dòng)態(tài)代理沮尿,原因是多繼承在 Java 中本質(zhì)上就行不通丛塌。
有很多條理由,人們可以否定對(duì) class 代理的必要性畜疾,但是同樣有一些理由赴邻,相信支持 class 動(dòng)態(tài)代理會(huì)更美好。接口和類的劃分啡捶,本就不是很明顯姥敛,只是到了 Java 中才變得如此的細(xì)化。如果只從方法的聲明及是否被定義來(lái)考量瞎暑,有一種兩者的混合體彤敛,它的名字叫抽象類。實(shí)現(xiàn)對(duì)抽象類的動(dòng)態(tài)代理了赌,相信也有其內(nèi)在的價(jià)值墨榄。此外,還有一些歷史遺留的類勿她,它們將因?yàn)闆](méi)有實(shí)現(xiàn)任何接口而從此與動(dòng)態(tài)代理永世無(wú)緣袄秩。如此種種,不得不說(shuō)是一個(gè)小小的遺憾嫂拴。