第一篇:java學習心得
學習心得
1.ArrayList:使用無參數構造時底層默認產生長度為10的數組 不可以向其中添加原生數據類型 他的底層默認成接受object數組,jdk1.6以后系統自動進行裝箱與拆箱所以添加原生類型不會報錯低版本沒這功能會報錯。
他的元素刪除會使后續元素前移代價較大
Linkedlist:添加對象底層會生成entry對象,linkedlist
雙向鏈表 鏈表由entry對象作為節點 添加元素為結點的值 Linkedlist所維護的是一個個entry對象
2.Java :真正執行的不是二進制碼而是字節碼
3.Java跨平臺,jvm 不是跨平臺 jvm 由C語言編寫
4.Java中方法參數傳遞無論是原生數據類型還是引用數據類型統一是pass value 即傳值。
5.對象擁有自己的屬性但是所有對象共享一個方法
6.Java 之所以跨平臺本質原因在于jvm不是跨平臺
7.方法的重載只在參數的個數或者參數的類型上有所不同。
8.方法的重寫發生在父類與子類之間具有層次關系,方法的重載發生在同一個類的內部的兩個或多個方法(包括繼承過來的方法)具有平行關系。
9.當生成子類對象時,java默認調任父類的無參構造函數
10.多態:父類型的引用可以指向子類型的對象,或者接口類型的引用可以指向實現該接口的類的實例
11.重載不能決定多態,重寫可以,重載不是一種晚綁定。鑒于thinking-java polymorphism
如:Animal a=new Dog();// dog ,cat 為animal子類
Animal b=new Cat();
Dog d=(Dog)a;1
Dog c=(Dog)b;2
上面編譯時都能通過,當執行時2是不能通過的,c不能指向cat類型對象。
12.靜態方法:只能被繼承不能被重寫(override)會被隱藏。
Class animal{
Public static void a{};
}
Class cat extends animal{
//@override 表示重寫方法 添加會出錯,靜態方法不能被重寫
Public static void a{};
}
Animal an=new cat();
上面代碼會調用animal類中的a方法。靜態方法不能被重寫,如上an屬如animal類所以調用父類。即調用方法取決于是從父類調用還是從子類調用。而普通方法是取決于引用所指向的實際對象。Cat中的a方法隱藏了父類的a方法
13.static 除聲明屬性和方法外使用static也可以聲明內部類,用static聲明的內部類變成了外部類,用static聲明的內部類不能訪問外部類非static屬性。
14.對于內部類若是static修飾的實列化對象:
outer.Inner in=new outer.Inner();
非static修飾的實列化對象:
outer out=new outer();
outer.Inner in=out.new Inner();
即首先通過外部類的實列化對象去實例化內部類對象。
15.引用數據類型可以使用Object進行接收包括數組和接口 16.一、當兩個并發線程訪問同一個對象object中的這個
synchronized(this)同步代碼塊時,一個時間內只能有一個線程得到執行。另一個線程必須等待當前線程執行完這個代碼塊以后才能執行該代碼塊。
二、然而,當一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。
三、尤其關鍵的是,當一個線程訪問object的一個
synchronized(this)同步代碼塊時,其他線程對object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞。
四、第三個例子同樣適用其它同步代碼塊。也就是說,當一個線程訪問object的一個synchronized(this)同步代碼塊時,它就獲得了這個object的對象鎖。結果,其它線程對該object對象所有同步代碼部分的訪問都被暫時阻塞。
五、以上規則對其它對象鎖同樣適用.17.即便有泛型聲明,也只是在內的定義上聲明,與構造方法的定義無關。子類的泛型類型不能用父類的泛型類型接受如:Info
第二篇:java學習心得
Java學習心得
專業:信息與計算科學班級:
姓名:學號:
日期:
河北建筑工程學院數理系
java語言產生于C++語言之后,是完全的面向對象的編程語言,充分吸取了C++語言的優點,采用了程序員所熟悉的C和C++語言的許多語法,同時又去掉了C語言中指針、內存申請和釋放等影響程序健壯性的部分,可以說java語言是站在C++語言這個“巨人的肩膀上”前進的。
java采用的是相對簡單的面向對象技術,去掉了運算符重載、多繼承的復雜概念,而采用了單一繼承、類強制轉換、多線程、引用(非指針)等方式。
在java程序中不能采用地址計算的方法通過指針訪問內存單元,大大減少了錯誤發生的可能性;而且java的數組并非用指針實現,這樣就可以在檢查中避免數組越界的發生。
Java語言學習要點
一、掌握靜態方法和屬性
靜態方法和屬性用于描述某一類對象群體的特征,而不是單個對象的特征。Java中大量應用了靜態方法和屬性,這是一個通常的技巧。但是這種技巧在很多語言中不被頻繁地使用。理解靜態方法和屬性對于理解類與對象的關系是十分有幫助的,在大量的Java規范中,靜態方法和屬性被頻繁使用。因此學習者應該理解靜態方法和屬性。Java在方法和屬性的調用上是一致的,區別只表現在聲明的時候,這和c++是不同的。
二、重視接口
在面向對象早期的應用中大量使用了類繼承。隨著軟件工程理論的不斷發展,人們開始意識到了繼承的眾多缺點,開始努力用聚合代替繼承。軟件工程解決擴展性的重要原則就是抽象描述,直接使用的工具就是接口。接口近年來逐漸成為Java編程方法的核心。另一方面,就應用而言,大部分開發是建立在規范基礎之上的,不需要自己建立復雜的繼承關系和龐大的類。因此讀懂規范和用好規范已經成為應用程序開發人員的首要任務,Java各項規范的主要描述手段就是接口。
三、學好集合框架
Java描述復雜數據結構的主要方式是集合框架。Java沒有指針,而是通過強大的集合框架描述數組、對象數組等復雜的數據結構。學好這些數據結構的描述方法對于應用程序編寫,特別是涉及到服務器方、3層結構編程至關重要。程序員在這個時候不能再用諸如數據庫結果集之類的結構描述數據了。
四、例外捕捉
Java對例外捕捉的強調是空前的,它強迫程序員用顯著的與邏輯方法完全不同的方式描述例外捕捉,對于程序描述的完整性和嚴謹性有很大的意義。
總之學編程語言不僅僅是從理論上的學習,更重要的是要利用這門語言為你的思想服務。理解這門語言是首要的,但是要達到心領神會、融會貫通就必須勤動手,多去時間,多編一些例子。計算機科學是注重實踐的學科,成功的軟件開發人員無不經過大量的上機鍛煉,只有理論和實踐相結合才能真正掌握只是和技能。
第三篇:Java學習心得
Java學習心得
一、如何學好java??
1.就本人認為學好java關鍵就在于態度。態度是學習好java的前
提,積極的態度注定你就比別人學得認真,自然最終學的一定
比不認真的人學的好!
2.有良好的前提,不努力也不行的,所以呀!還得練習。要做到
常練習,多看,多思考(舉一反三,多方位的,全面的使你的程序更加的完美);
3.最后一點,就是多多交流!閉門造車永遠是落后的學習方式,所以好要和身邊的一切可以交流技術的人積極交流,畢竟個人的力量有限的!
二、Java中那些重要知識點!(本人認為最主要的是思想,知識點也很重要,關鍵是在學習中總結出自己的一套思想,好的槍手都是子彈喂出來的,好的程序員都是寫代
碼寫出來的)
1. Java數據類型
a)基本數據類型:byte、short、int、long、float、double、char、boolean(注意各自的取值范圍,還有轉換方式)
b)引用數據類型: 數組、類、接口。
2. 運算符號
a)算術運算符:+、-、*、/、%、++、--;
b)賦值運算符:=、+=、-=、*=、/=、%=;
c)比較運算符:<、>、=<、=>、!=;(返回值都是false/true)d)邏輯運算符:&&、||、!
e)位運算符:用于操作二進制位的運算符:<<、>>、>>>……
4.基本數據結構:
a)順序結構
b)選擇結構(if……else……,switch……case……
default……);
c)循環結構(for()、do……while、while)(分清break與
continue的用法)
5.數組(用于存儲同一類型數據的一個容器)
a)表現形式:
i.ii.元素類型[] 變量名 = new 元素類型[元素的個數]; 元素類型[] 變量名 = {元素1,元素2...};(new 元素類
型[]{元素1,元素2...};)
b)數組排序方法:插入排序,二分法排序,希爾排序,還有
最主要的——冒泡排序
6.內存(1:寄存器2:本地方法區3:方法區4:棧5:堆)
a)棧(存儲的都是局部變量)只要數據運算完成所在的區域
結束,該數據就會被釋放。
b)堆(用于存儲數組和對象,也就是實體——用于封裝多個
數據的)
i.每一個實體都有內存首地址值。
ii.堆內存中的變量都有默認初始化值。因為數據類型不
同,值也不一樣。
iii.垃圾回收機制
7.面向對象
a)特點:
i.ii.iii.將復雜的事情簡單化。面向對象將以前的過程中的執行者,變成了指揮者。面向對象這種思想是符合現在人們思考習慣的一種思
想。
b)對事物進行屬性和行為的分析
i.ii.屬性:特點 行為:函數(方法)
8.訪問權限
a)Private(私有的訪問權限最低,只有在本類中的訪問有效)
(Set方法設置,get方法提取)
b)Protected(安全的)受保護權限,體現在繼承,即子類可
以訪問父類受保護成員,同時相同包內的其他類也可以訪問protected成員。
c)無修飾詞(默認),表示包訪問權限(friendly,java語言
中是沒有friendly這個修飾符的,這樣稱呼應該是來源于
c++),同一個包內可以訪問,訪問權限是包級訪問權限
d)public修飾詞,表示成員是公開的,所有其他類都可以訪
問
9.方法重載與方法重寫
a)方法重載(一個類中可以有多個具有相同名字的方法,但
這些方法的參數不同(類型、個數、順序不同))
b)方法重寫(子類定義一個方法,并且這個方法的名字、返
回類型、參數的個數、參數類型與父類繼承的方法完全相同)
10.java面向對象三大特性(繼承,封裝,多態)
a)封裝(private):主要是Set方法與get方法合作應用
b)繼承(extends):注意訪問權限,看看是否能繼承!
c)多態:父類引用或者接口的引用指向了自己的子類對象,eg(動物——1.食草動物2.食肉動物——老虎,獅子,狗);
11.抽象類與接口
a)抽象類(abstract)特點:1.不能new2.可以由抽象方法(但
是非抽象類不能有抽象方法)
b)接口(interface聲明)
i.接口使用(implements):一個類可以實現一個或多個
接口,用逗號隔開。
ii.接口強調的是功能:has——a的問題!
12.多線程(Thread類與Runable接口)
a)主要方法:
i.start()啟動線程
ii.iii.iv.run()程序運行的方法,功能實現區域 sleep()休眠,使程序處于休眠狀態 interrupt()吵醒:吵醒處于休眠狀態的程序,使進入正
常狀態;
b)線程同步(synchronized鎖)關鍵在于this與object的區別,各自使用的范圍與壞境。
13.流(input/output)
a)分類:主要是字節流與字符流,還有緩沖流,數據流,對
象流……
b)方法都差不多:主要是writer()與read()還有各自對應的數
組應用!
c)出現亂碼時注意你用的流是否合適以及你使用的編碼格式
以否可以支持
14.套接字(Socket)
a)主要功能就是通信(安全的)(利用port進行連接)
b)利用流連接進行通信,數據傳送
15.……還有好多,自己慢慢研究吧!java博大精深!
三、我們在學習中的那些難題?
1.總是遇到難以理解的東西?
2.總是以為自己回了,但是又寫不出來?
3.總是覺得問題很難,但是經過別人的指點就會覺得好簡
單?
第四篇:java學習心得(模版)
湖南軟件職業學院
HNSERJ20080101
.湖南軟件職業學院
畢 業 論 文
知識改變命運
課 題:java學習心得 院 系:軟件工程系 專 業:軟件技術 班 級:軟件0615班 姓 名:周專書 指導老師:鄭利嬌 完成時間:2009-5-12
www.tmdps.cn 軟件成就未來 湖南軟件職業學院
HNSERJ20080101
Java實習報告
一.引言
面臨畢業與就業的壓力,不久將來就要從一個學生到一個社會人的轉變:技術在不斷的提高,思路在不斷的開闊,思想在不斷的升華,更重要的是自己的理想和抱負更加的堅定。對于一個投身于IT的新人,經驗談不上,一些學習的心得倒是可以拿出來探討一下,我們該如何面臨這個似曾相識的社會,突然一天如此接近。面對“金融風暴”帶來的就業壓力,我們正在逐漸走向成熟,我們意志更加堅強,我們深知不經一番寒徹骨,哪來梅花撲鼻香。深深地體會到找一份好工作多么不容易的,尤其是能力匱乏的我們。一切都要付出行動,不能空想,要實現目標,就得不懈的努力。
的確,軟件仍然是一個朝陽行業,對于人才的需求量也很大,這也是為什么很多人努力走上這座獨木橋的原因。但是當你面臨人生的一個選擇時,當你決定要踏上軟件開發之路時,你應該問一下自己:我為什么要選擇它?其實很多人在這條道路上摸爬滾打了多年也沒弄清楚這個問題的答案。如果你想在這條道路上有所成就的 話,一是興趣使然,二是做好自己的職業規劃。軟件開發其實是一條非常艱苦的路,不停的學習,不斷的熬夜,沒有鮮花更沒有掌聲,陪伴你的是那漫長而孤獨的夜。想一想我們準備好迎接這一切了嗎?如果沒有興趣我勸你還是放棄這條路,沒有興趣你就在這條路上走不長,等待你的只有轉行。如果你真的把它作為你職業生涯的跳板,那么請你做好自己的人生規劃,有步驟的實現它。話題稍微遠了一點,現在我就談談自己在Java學習方面的心得和教訓。
古人云:活到老,學到老。讀書學習實乃艱苦之事,花費時間,消耗精力。然苦之外亦見其樂:得到了知識,提高了認識,完善了自己。學習,求其真,務其實,應“敏而好學,不恥下問”,才能不斷促使進步。學習,不僅求知,也要懂法,學會方法比掌握知識更加重要。笛卡爾說過,“沒有正確的方法,即使有知識改變命運 www.tmdps.cn 軟件成就未來 湖南軟件職業學院
HNSERJ20080101
眼睛的博學者也會像瞎子一樣盲目摸索”,可見學習方法的重要性。
其實,大學之前幾乎沒有軟件技術之類的概念,大三之前仍然對于程序懵懂不開。但是這并不能妨礙我熱愛這個行業,也不能就斷定我在這個行業里一事無成。剛學 Java,我的確感覺不開竅,特別對OO(面向對象)編程仍然不能理解。但是人如果一思考,其實什么問題都解決了。對于學習java基礎的經驗就是多做、多思考,基礎知識的學習不能不求甚解,要追本溯源,弄清問題的本質。這樣才能舉一反三,由點及面。對于抽象的東西要能具體化,對于具體的東西要能抽象化。我學習java基礎一直使用的是《編程思想》第四版這本書,感覺挺不錯的,全面透徹通俗易懂,在國外也是廣受好評,我很惋惜沒有早點知道這本書,否則也不回浪費大學三年青春歲月,一無是處的打發光陰,值得慶幸的事這本書一定程度上激發了我對java學習的興趣與潛力。英語能力強的話,可以直接看英文原版。我一直強調重視基礎,如果你的java基礎打的牢,你在學習那些java框架就是非常輕松的事了。
二.Java學習心得之我見
學習java,的確要學習的東西很多,就像這為朋友上面提到的那些。Java不像.net一家獨大,記得在大學里教我們.net老師早就提醒過我們學java才是出路,學好java才是王道,我當時就納悶,這不是搬石頭砸自己的腳,往自己身上潑冷水嗎?現在恍然大悟,他當時只是為我們指引一條明路,Java的繁盛在于開源社區的龐大,這也帶來了分支太多的問題,怎樣選擇一條好的學習路線,對于初學者來說,的確是一件很迷茫的事。其實不管java東西再多,總有規律可循。根據自己的發展方向的不同,可以選擇不同的學習路線。對于怎樣成為一名出色的Java Web程序員,我的建議是:
1、JSP的知識不能欠缺,理解什么是servlet,什么是java bean,熟悉jsp常使用的標簽。我自己感覺,對于JSP的學習不需要太認真,畢竟現在真正使用純JSP的情況已經不多了,能掌握基本的知識就綽綽有余。
2、學習一個或一個以上的web表現框架。如果從使用的程度上來講,Struts依然是最流行的框架,社會需求也很大,所以學習Struts是一個不錯的選擇,最近一個月我們剛剛模擬Struts開發了一個簡單的網上商城,雖然算不上一大正規知識改變命運 www.tmdps.cn 軟件成就未來 湖南軟件職業學院
HNSERJ20080101 的項目,總算也用到了框架,因為框架本身也是一種封裝,程序開發是將簡單事情復雜化,模擬Struts使我們學習三大框架和其他框架奠定良好的基礎,使用框架的前提是你對他處理的業務邏輯也相當熟練了。當然也可以學習其他的框架,JSF作為一個標準,雖然現在使用的人不多,但是為了明天的主流,學習JSF也非常不錯。我就是開始學習Struts,后來公司用JSF,自己又自學了JSF,其實領悟了程序設計的思想,學什么都很容易。
3、簡單說說Spring,EJB。鑒于培訓中心的課程安排,我們需要學習spring,spring作為業務邏輯層的輕量級架構框架spring,依然占據著主流的位置,雖然EJB3的發布對它沖擊很大,但是在比較長的時 間里,它的位置還不能撼動。學習spring會很快帶來實際效益。當然EJB3的發布開始漸漸挽回以前丟棄的市場,作為官方的標準,它的未來充滿光明,學習EJB3會非常的有前途。自己最近也在學習EJB3其實對于剛剛畢業的學生沒必要深入研究他們,很多公司也不使用這樣業務邏輯層的框架,尤其是中小型企業。
4、至于xml,css這樣的頁面表現的東西,如果你不從事美工方面,我認為沒有必要花過多的時間去學習,在平時的項目開發中慢慢的就會使用了。
還是那句話,基礎很重要,永遠不要忽視這一點。剛剛畢業,公司不會要求員工什么都會,只要技術扎實,學習的能力強,學習的速度就很快,企業有時候非??粗?這一點。其次掌握struts、hibernate這兩個框架,達到可以熟練使用的目的,這會增加你就業的砝碼。至于spring,EJB可以在以后的工作中學習使用,現在了解一下就可以了。當然作為一個java web程序員,還要了解數據庫、tomcat,jboss服務器、常用的開發工具Eclipse,NetsBean等。
三,Java學習態度之我見 1.學java切忌浮躁
欲速則不達,初學者請不要被新技術迷惑,先把基礎學扎實,一步一個腳印的逐步學習,不要想著一步登天。我們要如水底磐石切不可做那水上浮萍,浮躁的人永遠學不到什么東西。軟件開發之路是充滿荊棘與挑戰之路,也是充滿希望知識改變命運 www.tmdps.cn 軟件成就未來 湖南軟件職業學院
HNSERJ20080101
之路,沒有捷徑可走。夢想像《天龍八部》中虛竹一樣被無崖子醍醐灌頂而輕松獲得一甲子功力,是很不現實的。每天仰天大叫“天神啊,請賜給我一本葵花寶典吧”,殊不知即使你獲得了葵花寶典,除了受自宮其身之苦外,你也不一定成得了“東方不敗”,倒是成“西方失敗”的幾率高一點?!安蛔邚澛罚褪墙輳健保鸾浾f的不無道理。
2.要有自我約束力
春來不是讀書天,夏日炎炎正好眠,秋來蚊蟲冬又冷,背起書包待明年??傆幸恍├碛刹粚W習。這樣下去,我們的java之樹永遠長不大。古人云:“人靜而后安,安而能后定,定而能后慧,慧而能后悟,悟而能后得?!焙苡械览?。在四川大足佛教石刻藝術中,有一組大型佛雕《牧牛圖》,描繪了一個牧童和牛由斗爭、對抗到逐漸融合、協調,最后合而為一的故事。佛祖說:“人的心魔難伏,就像牛一樣,私心雜念太多太多;修行者就要像牧童,修煉他們,馴服他們,以完美自己的人生?!蔽覀儗Wjava也一樣,要能夠馴服那些影響我們學習的大牛、小牛,抵制各種誘惑,集中精力,專心學習。
3.課前稍作預習
我個人的經驗和理解,課前的預習對于我們學習java尤為重要。我們課前的預習相當于第一遍的學習,而這是為第二天的學習做了一個初步的了解,而且這樣學習更有效,更容易吸收課堂所學,這樣既培養了我們的自學能力,也讓我們發現了這個章節的難點和不懂點,上課時。在這里培訓每天的理論知識量并不少,要是不預習我們會跟不上老師的教學節奏,不知其所云!
4.“三敲代碼”學習法
這個詞最初來自我們項目團隊一個同學滑稽的演講,班上流傳的“笑柄”,但他是正確的,這是程序員都值得推薦學習的方法,為什么說是“三敲代碼”呢?敲代碼也并不是一味的盲敲代碼。課前預習就是將課本上的實例代碼敲一遍,先知識改變命運 www.tmdps.cn 軟件成就未來 湖南軟件職業學院
HNSERJ20080101
不管是否理解這些代碼的意思,有時候結果是很重要的,能讓你豁然開朗。第二遍敲代碼是課后的敲代碼,老師布置的或書上的作業,雖然課后我們還是沒能吸收消化當天知識,我們可以借鑒別人的代碼,但一定得有自己的思路,否則只會事倍功半,適得其反。第三遍就是敲真正屬于自己的代碼。這是完全依靠自己所學,自主的思維,來鞏固自己當日所學進行查漏補缺,那么才能保證學習效果。
5.理解+總結=記憶
認真理解和善于總結是學好java的訣竅之一。學習,就必須講求記憶,記憶知識,就必須講求方法。得道者事半功倍,失道者事倍功半。Java有很多知識點是需要記憶的,有的人常常感嘆自己的記憶力不好,羨慕那些博聞強記的人。殊不知那些人無不是善于總結和整理自己的感官印象,才記得牢固而準確,這便是理解。列夫?托爾斯泰說:“知識,只有當它靠積極的思維得來而不是憑記憶得來的時候,才是真正的知識?!笨鬃釉疲骸皩W而不思則罔,思而不學則殆?!边@些都充分證明了這一點。知識不能只停留在書本上,必須轉化為自己機能的一部分,達到“唯吾是從”。理解,必許透過現象認本質,由此及彼、由表及里,去粗取精、去偽存真。善于開動腦筋是其中的關鍵。
6.要善于積累
積累非常重要。莊子云:“水之積也不厚,則其負大舟也無力。風之積也不厚,則其負大翼也無力?!蔽覀冋n堂上老師都會講很多的實例,這些實例都是每個知識點的真實體現,我們都要即時的消化和理解。這樣日積月累,學習效率不斷提高,技術也逐步上升。有的同學認為,課堂上聽不懂關系不大,課后自己看書也能認識,或者把一些問題全部留在自習課上向老師請教,??這些想法都是錯誤的,這樣想勢必上課不求甚解,積極思考不足,既浪費了課堂時間和老師的課下時間,也變相加重自己課下的學業負擔。正確的態度是:上課專心聽講,積極思考,力求當堂消化。針對課堂思路卡殼問題,我個人理解是:千萬不要在課堂上尋找卡殼的原因,要求自己跳過去,聽下面的內容,課下再請教老師,共同分析導致自己卡殼的原因,不失為一種較好的辦法。
知識改變命運 www.tmdps.cn 軟件成就未來 湖南軟件職業學院
HNSERJ20080101
在java培訓中心也不定期開展職業素養的課程,盡管我覺得老師并不是那么專業,我們也抱著無所謂的態度,但是我們依然意識這就是問題的根源,通過開展職業素養,讓我更深層次的認識企業文化的重要性,這也是培訓中心特別的地方。人無志,不成事。提高自己的職業素養,對自身的發展會有很大的幫助。
四.職業素養的培訓
1,保持積極向上樂觀的心態。
積極很重要的一方面就是樂觀自信。而要達到自己對自己充分的肯定,概括來說可以從四個方面來講:第一,學會從另外一方面來看待事情,心態決定一切。第二,萬事在失敗前拒絕說“不行”。第三,不段給自己“充電”。“有才不怕萬事難”我們要時常提高自己的內涵和修養。第四,借鑒別人的事跡,失敗也是一種收獲。有了職業,我們還必須得有積極和強烈的進取心,這樣才能做出自己的成績。如果沒有進取心,固步自封,工作上不想精益求精,事業就沒有發展的希望。我們在開始工作時,應把積累工作經驗、提高工作能力作為目標,這是今后擴大自己事業空間的基礎。不要計較薪金薄厚,更不能自命不凡,不屑小就。而要愛自己的職業,深思研究工作改進之術,常保進取的決心。古人說:“少壯不努力,老大徒傷悲。”進取心不但是成業的要素,并且是成己的要素。
2,注重項目團隊合作。
保證一個團體生機和活力,必須使得每一個成員能夠相互支持和包容,成員間充分尊重對方意見,現在終于感受到了團隊合作重要性,項目小組花了一個星期做系統,除了個人知識的融會貫通,更重要的是成員的溝通與協調。有人說,一個融洽的工作環境就是成功的一半。尤其是從事軟件開發,團隊就是發展的根源,更是一個好的系統的前提保證,一個人的思想是有限的,多遠思維交織在一起,產生的力量是不可估量的。
知識改變命運 www.tmdps.cn 軟件成就未來 湖南軟件職業學院
HNSERJ20080101
3,腳踏實地的做事。
樹立“職業神圣”觀念。一個人對自己職業不敬,便是對這一職業的褻瀆,其結果是會把事情做壞,給社會和個人帶來雙重損失。莊子說:“用志不分,乃凝于神?!蓖ㄋ椎卣f,敬業就是把自己從事的職業加以研究,勤勉從事的意思。做事為學,有慎心,不怕勞,不虎頭蛇尾,不見異思遷。面對企業和人才之間的雙向選擇,一個敬業的員工無論走到哪里都將受到關注和重用,相反一個見異思遷的人在任何一個企業也不會有更光明的前途的,這是一個成為一個職業人的第一要素。我們不能“做一天和尚撞一天鐘”而是應該“做一天和尚撞好一天鐘”。
4,兢兢業業的工作態度。
“干一行,愛一行”——只有樂業,人才能從職業工作中得到精神享受??鬃诱f:“知之者不如好知者,好知者不如樂知者?!比松軓淖约郝殬I中領略出趣味,生活才有價值和意義。對于職業的態度不同,有的是以熱情擁抱的態度迎接職業,有的是以冷酷無聊的態度迎接職業。其結果是,前者把職業當成是親愛的永久伴侶,從中獲益;后者則只是得到煩惱,甚至是傷痛。所以,樂業對人的一生很重要。人一生做好一件事足已,何必三心二意,一事無成。
5,做人做事要有責任心。
曾經懵懂無知,不知責任心是那般,就算今天我們依然迷茫,都說責任心是做好一件事,一份工作的保證。我們將要踏進社會,我們將會面臨對工作的責任、對社會的責任、對家庭的責任,我想只有一個擁有責任心的人才能走好自己的人生旅途。古人云“一息尚存,此志不容稍懈”,“鞠躬盡瘁,死而后已”。無論什么職業,責任心、責任意識是做好工作的內在動力,記得培訓中心老師曾經說過,內因決定外因,責任心是做好一件事的源動力。
知識改變命運 www.tmdps.cn 軟件成就未來 湖南軟件職業學院
HNSERJ20080101
五.個人總結
人生的每一步旅途中,總有著一道難以逾越的鴻溝,對于我們不是缺少勇氣,而是沒有思想,惰性取代了我們原本的進取心,而我們選擇了自甘墮落,碌碌無為的虛度光陰,今天之前的錯誤使我們選擇的懲罰,在軟件學院,如果只要用心去學,不說精益求精,至少可以學會謀生之道,當然不排除學院本省一些不利因素,離開軟件學院,我們無從追究對與錯,因為無法挽回失去的光陰,一寸光陰一寸金,寸金難買寸光陰。這次我想我會很用心的去學習!盡量把他做到完美,至少自己要九十分的滿意我才會交出我培訓的心得體會。
天下大事必做于細。普通人自然作一些小事,怕只怕小事也做不好,小事也做不到位。身邊有很多人總不屑于做具體的事,盲目地相信“天將降大任于斯人也”。孰不知這是及其錯誤的心態,試著去做好自己的事實屬不易。不要以為總理比村長好當。有其職斯有其責,有其責斯有其憂。如果力不及所負,才不及所任,必然禍及自身,狼狽不堪,若做錯事也難辭其咎。所以用心做好身邊的每一件小事,不積細流,何以成江海。所謂成功,就是在平凡中做出不平凡的堅持,而偉大就是平凡的積累。蒲老師曾經說過,做正確的事,正確的做事,在這個告訴信息化的時代,細節決定成敗,方法與態度決定了效率。
“博學之,審問之,慎思之,明辯之,篤行之。” 時下,IT行業對人才的需求是很大而且持續,這更加為我夢想的實現增添了砝碼,激勵自己朝著夢想的云向更大的努力奮斗,只待好風憑借力,送我上青云!“少而好學,如日出之陽”,不管是現在還是將來,我們都應不斷地加強學習,不斷地給自己“充電”,才能開拓進取,勇于創新,不至于被社會淘汰。只要在學習的過程中保持著激情,多做多思考,再加上一顆充滿夢想和遠大抱負的心,我相信人人都可以成功。
知識改變命運 www.tmdps.cn 軟件成就未來
第五篇:java學習心得
Java學習心得
Java 學習雜談
(二)鑒于上回寫的一點感想大家不嫌棄,都鼓勵小弟繼續寫下去,好 不容易等到國慶黃金周,實習總算有一個休息的階段,于是這就開始寫第二篇了。希望這次寫的仍然對志同道合的朋友們有所幫助。上回講了Java動態加載機 制、classLoader原理和關于jdk和jre三個問題。這次延續著講一些具體的類庫——
1. 關于集合框架類
相信學過 Java的各位對這個名詞并不陌生,對 java.util.*這個package肯定也不陌生。不知道大家查詢API的時候怎么去審視或者分析其中的一個package,每個包最重要的兩個部 分就是interfaces和classes,接口代表了它能做什么,實現類則代表了它如何去做。關注實現類之前,我們應該先理解清楚它的來源接口,不管 在j2se還是j2ee中,都應該是這樣。那么我們先看這三個接口:List、Set、Map。
也許有些人不太熟悉這三個名字,但相信大部分人都 熟悉ArrayList,LinkedList,TreeSet,HashSet,HashMap,Hashtable等實現類的名字。它們的區別也是滿容易理解的,List放可以重復的對象集合,Set放不可重復的對象組合,而Map則放
到底Vector和ArrayList,Hashtable和HashMap有什么區別?
很多面試官喜歡問這個問題,其實更專業一點應該這樣問:新集合框架和舊集合框架有哪些區別?新集合框架大家可以在這些包中找since jdk1.2的,之前的如vector和Hashtable都是舊的集合框架包括的類。那么區別是?
a.新集合框架的命名更加科學合理。例如List下的ArrayList和LinkedList b.新集合框架下全部都是非線程安全的。建議去jdk里面包含的源代碼里面自己去親自看看vector和ArrayList的區別吧。當然如果是jdk5.0之后的會比較難看一點,因為又加入了泛型的語法,類似c++的template語法。
那么大家是否想過為什么要從舊集合框架默認全部加鎖防止多線程訪問更新到新集合框架全部取消鎖,默認方式支持多線程?(當然需要的時候可以使用collections的靜態方法加鎖達到線程安全)筆 者的觀點是任何技術的發展都未必是遵循它們的初衷的,很多重大改變是受到客觀環境的影響的。大家知道Java的初衷是為什么而開發的麼?是為嵌入式程序開 發的。記得上一篇講到classLoader機制麼?那正是為了節約嵌入式開發環境下內存而設計的。而走到今天,Java成了人們心中為互聯網誕生的語 言?;ヂ摼W意味著什么?多線程是必然的趨勢??陀^環境在變,Java技術也隨著飛速發展,導致越來越脫離它的初衷。據說Sun公司其實主打的是J2se,結果又是由于客觀環境影響,J2se幾乎遺忘,留在大家談論焦點的一直是j2ee。
技術的細節這里就不多說了,只有用了才能真正理解。解釋這些正是為了幫助大家理解正在學的和將要學的任何技術。之后講j2ee的時候還會再討論。
多 扯句題外話:幾十年前的IT巨人是IBM,Mainframe市場無人可比。微軟如何打敗IBM?正是由于硬件飛速發展,對個人PC的需求這個客觀環境,讓微軟通過OS稱為了第二個巨人。下一個打敗微軟的呢?Google。如何做到的?如果微軟并不和IBM爭大型機,Google借著互聯網飛速發展這個客 觀環境作為決定性因素,避開跟微軟爭OS,而是走搜索引擎這條路,稱為第3個巨人。那么第4個巨人是誰呢?很多專家預言將在亞洲或者中國出現,Whatever,客觀環境變化趨勢才是決定大方向的關鍵。當然筆者也希望會出現在中國,^_^~~
2. 關于Java設計模式
身邊的很多在看GOF的23種設計模式,似乎學習它無論在學校還是在職場,都成了一種流行風氣。我不想列舉解釋這23種Design Pattern,我寫這些的初衷一直都是談自己的經歷和看法,希望能幫助大家理解。
首 先我覺得設計模式只是對一類問題的一種通用解決辦法,只要是面向對象的編程預言都可以用得上這23種。理解它們最好的方法就是親自去寫每一種,哪怕是一個 簡單的應用就足夠了。如果代碼實現也記不住的話,記憶它們對應的UML圖會是一個比較好的辦法,當然前提是必須了解UML。
同時最好能利用 Java自身的類庫幫助記憶,例如比較常用的觀察者模式,在java.util.*有現成的Observer接口和Observable這個實現類,看看 源代碼相信就足夠理解觀察者模式了。再比如裝飾器模式,大家只要寫幾個關于java.io.*的程序就可以完全理解什么是裝飾器模式了。有很多人覺得剛入 門的時候不該接觸設計模式,比如圖靈設計叢書系列很出名的那本《Java設計模式》,作者: Steven John Metsker,大部分例子老實說令現在的我也很迷惑。但我仍然不同意入門跟學習設計模式有任何沖突,只是我們需要知道每種模式的概念的和典型的應用,這 樣我們在第一次編寫 FileOutputStream、BufferedReader、PrintWriter的時候就能感覺到原來設計模式離我們如此之近,而且并不是多么 神秘的東西。
另外,在學習某些模式的同時,反而更能幫助我們理解java類庫的某些特點。例如當你編寫原型(Prototype)模式的 時候,你必須了解的是 java.lang.Cloneable這個接口和所有類的基類Object的clone()這個方法。即深copy和淺copy的區別:
Object.clone()默認實現的是淺copy,也就是復制一份對象拷貝,但如果對象包含其他對象的引用,不會復制引用,所以原對象和拷貝共用那個引用的對象。
深 copy當然就是包括對象的引用都一起復制啦。這樣原對象和拷貝對象,都分別擁有一份引用對象。如果要實現深copy就必須首先實現 java.lang.Cloneable接口,然后重寫clone()方法。因為在Object中的clone()方法是protected簽名的,而 Cloneable接口的作用就是把protected放大到public,這樣clone()才能被重寫。
那么又有個問題了?如果引用 的對象又引用了其他對象呢?這樣一直判斷并復制下去,是不是顯得很麻煩?曾經有位前輩告訴我的方法是重寫clone方法的時候直接把原對象序列化到磁盤上 再反序列化回來,這樣不用判斷就可以得到一個深copy的結果。如果大家不了解序列化的作法建議看一看 ObjectOutputStream和ObjectInputStream
歸根結底,模式只是思想上的東西,把它當成前人總結的經驗其 實一點都不為過。鼓勵大家動手自己去寫,例如代理模式,可以簡單的寫一個Child類,Adult類。Child要買任何東西由Adult來代理實現。簡單來說就是Adult里的buy()內部實際調用的是Child的buy(),可是暴露 在main函數的卻是Adult.buy()。這樣一個簡單的程序就足夠理解代理模式的基本含義了。Java 雜談
(三)這已經筆者寫的第三篇Java雜記了,慶幸前兩篇一直得到論壇朋友們的支持鼓勵,還望大家繼續指正不足之處。筆者也一直渴望通過這樣方式清醒的自審,來尋找自己技術上的不足之處,希望和共同愛好Java的同仁們一起提高。
前兩次分別講述了關于jvm、jdk、jre、collection、classLoader和一些Design Pattern的自我理解。這次仍然不準備開始過渡到j2ee中,因為覺得還有一些瑣碎的j2se的問題沒有總結完畢。
1. 關于Object類理解
大家都知道Object是所有Java類的基類,意味著所有的Java類都會繼承了Object的11個方法。建議大家去看看Object的 11個成員函數的源代碼,就會知道默認的實現方式。比如equals方法,默認實現就是用“==”來比較,即直接比較內存地址,返回true 或者 false。而toString()方法,返回的串組成方式是——
“getClass().getName()+ ”@“ + Integer.toHexString(hashCode())” 其實不用我過多的解釋,大家都能看懂這個串的組成。接下來再看看hashCode():
public native int hashCode();
由于是native方法,跟OS的處理方式相關,源代碼里僅僅有一個聲明罷了。我們有興趣的話完全可以去深究它的hashCode到底是由OS怎么樣產生 的呢?但筆者建議最重要的還是先記住使用它的幾條原則吧!首先如果equals()方法相同的對象具有相通的hashCode,但equals()對象不相通的時候并不保證hashCode()方法返回不同的整數。而且下一次運行同一個程序,同一個對象未必還是當初的那個hashCode()哦。
其余的方法呢?nofigy()、notifyAll()、clone()、wait()都是native方法的,說明依賴于操作系統的實現。最后一個有 趣的方法是finalize(),類似C++的析構函數,簽名是protected,證明只有繼承擴展了才能使用,方法體是空的,默示什么也不做。它的作 用據筆者的了解僅僅是通知JVM此對象不再使用,隨時可以被銷毀,而實際的銷毀權還是在于虛擬機手上。那么它真的什么也不做麼?未必,實際上如果是線程對 象它會導致在一定范圍內該線程的優先級別提高,導致更快的被銷毀來節約內存提高性能。其實從常理來說,我們也可以大概這樣猜測出jvm做法的目的。
2. 關于重載hashCode()與Collection框架的關系
筆 者曾經聽一位搞Java培訓多年的前輩說在他看來hashCode方法沒有任何意義,僅僅是為了配合證明具有同樣的hashCode會導致equals 方法相等而存在的。連有的前輩都犯這樣的錯誤,其實說明它還是滿容易被忽略的。那么hashCode()方法到底做什么用?
學過數據結構的課程大家都會知道有一種結構叫hash table,目的是通過給每個對象分配一個唯一的索引來提高查詢的效率。那么Java也不會肆意扭曲改變這個概念,所以hashCode唯一的作用就是為 支持數據結構中的哈希表結構而存在的,換句話說,也就是只有用到集合框架的 Hashtable、HashMap、HashSet的時候,才需要重載hashCode()方法,這樣才能使得我們能人為的去控制在哈希結構中索引是否相等。筆者舉一個例子:
曾經為了寫一個求解類程序,需要隨機列出1,2,3,4組成的不同排列組合,所以筆者寫了一個數組類用int[]來存組合結果,然后把隨機產生的組合加入 一個HashSet中,就是想利用HashSet不包括重復元素的特點。可是HashSet怎么判斷是不是重復的元素呢?當然是通過
hashCode()返回的結果是否相等來判斷啦,可做一下這個實驗:
int[] A = {1,2,3,4};int[] B = {1,2,3,4};System.out.println(A.hashCode());System.out.println(B.hashCode());這明明是同一種組合,卻是不同的hashCode,加入Set的時候會被當成不同的對象。這個時候我們就需要自己來重寫hashCode()方法了,如何 寫呢?其實也是基于原始的hashCode(),畢竟那是操作系統的實現,找到相通對象唯一的標識,實現方式很多,筆者的實現方式是:
首先重寫了toString()方法: return A[0]“+” A[1]“+” A[2]“+” A[3];//顯示上比較直觀
然后利用toString()來計算hashCode():
return this.toString().hashCode();
這樣上述A和B返回的就都是”1234”,在測試toString().hashCode(),由于String在內存中的副本是一樣的,”1234”.hashCode()返回的一定是相同的結果。
說到這,相信大家能理解得比我更好,今后千萬不要再誤解hashCode()方法的作用。
3. 關于Class類的成員函數與Java反射機制
很早剛接觸Java就聽很多老師說過Java的動態運行時機制、反射機制等。確實它們都是Java的顯著特點,運行時加載筆者在第一篇介紹過了,現在想講 講反射機制。在Java中,主要是通過java.lang包中的Class類和Method類來實現內存反射機制的。
熟悉C++的人一定知道下面這樣在C++中是做不到的: 運行時以字符串參數傳遞一個類名,就可以得到這個類的所有信息,包括它所有的方法,和方法的詳細信息。還可以實例化一個對象,并通過查到的方法名來調用該 對象的任何方法。這是因為Java的類在內存中除了C++中也有的靜態動態數據區之外,還包括一份對類自身的描述,也正是通過這描述中的信息,才能幫助我 們才運行時讀取里面的內容,得到需要加載目標類的所有信息,從而實現反射機制。大家有沒有想過當我們需要得到一個JavaBean的實例的時候,怎么知道 它有哪些屬性呢?再明顯簡單不過的例子就是自己寫一個JavaBean的解析器:
a.通過Class.forName(“Bean的類名”)得到Class對象,例如叫ABeanClass b.通過ABeanClass的getMethods()方法,得到Method[]對象
c.按照規范所有get方法名后的單詞就代表著該Bean的一個屬性
d.當已經知道一個方法名,可以調用newInstance()得到一個實例,然后通過invoke()方法將方法的名字和方法需要用的參數傳遞進去,就可以動態調用此方法。
當然還有更復雜的應用,這里就不贅述,大家可以參考Class類和Method類的方法。
4. 坦言Synchronize的本質
Synchronize大家都知道是同步、加鎖的意思,其實它的本質遠沒有大家想得那么復雜。聲明Synchronize的方法被調用的時候,鎖其實是加 載對象上,當然如果是靜態類則是加在類上的鎖,調用結束鎖被解除。它的實現原理很簡單,僅僅是不讓第二把鎖再次被加在同一個對象或類上,僅此而已。一個簡 單的例子足以說明問題:
class A{ synchronized void f(){} void g(){} }
當A的一個對象a被第一個線程調用其f()方法的時候,第二個線程不能調用a的synchronized方法例如f(),因為那是在試圖在對象上加第二把鎖。但調用g()卻是可以的,因為并沒有在同一對象上加兩把鎖的行為產生。
這樣大家能理解了麼?明白它的原理能更好的幫助大家設計同步機制,不要濫用加鎖。
PS:下篇筆者計劃開始對J2ee接觸到的各個方面來進行總結,談談自己的經驗和想法。希望大家還能一如既往的支持筆者寫下去,指正不足之處。
Java雜談
(四)不知不覺已經寫到第四篇了,論壇里面不斷的有朋友鼓勵我寫下去。堅持自己的作風,把一切迷惑不容易理清楚的知識講出來,講到大家都能聽懂,那么自己就真的 懂了。最近在公司實習的時候Trainer跟我講了很多經典事跡,對還未畢業的我來說是筆不小的財富,我自己的信念是:人在逆境中成長的速度要遠遠快過順 境中,這樣來看一切都能欣然接受了。
好了,閑話不說了,第三篇講的是反射機制集合框架之類的,這次打算講講自己對反序列化和多線程的理解。希望能對大家學習Java起到幫助——
1.關于序列化和反序列化
應該大家都大概知道Java中序列化和反序列化的意思,序列化就是把一個Java對象轉換成二進制進行磁盤上傳輸或者網絡流的傳輸,反序列化的意思就是把 這個接受到的二進制流重新組裝成原來的對象逆過程。它們在Java中分別是通過ObjectInputStream和
ObjectInputStream這兩個類來實現的(以下分別用ois和oos來簡稱)。
oos的writeObject()方法用來執行序列化的過程,ois的readObject()用來執行反序列化的過程,在傳輸二進制流之前,需要講這 兩個高層流對象連接到同一個Channel上,這個Channel可以是磁盤文件,也可以是socket底層流。所以無論用哪種方式,底層流對象都是以構 造函數參數的形式傳遞進oos和ois這兩個高層流,連接完畢了才可以進行二進制數據傳輸的。例子:
可以是文件流通道
file = new File(“C:/data.dat”);
oos = new ObjectOutputStream(new FileOutputStream(file));ois = new ObjectInputStream(new FileInputStream(file));
或者網絡流通道
oos = new ObjectOutputStream(socket.getOutputStream());ois = new ObjectInputStream(socket.getInputStream());
不知道大家是否注意到oos總是在ois之前定義,這里不希望大家誤解這個順序是固定的么?回答是否定的,那么有順序要求么?回答是肯定的。原則是什么呢?
原 則是互相對接的輸入/輸出流之間必須是output流先初始化然后再input流初始化,否則就會拋異常。大家肯定會問為什么?只要稍微看一看這兩個類的 源代碼文件就大概知道了,output流的任務很簡單,只要把對象轉換成二進制往通道中寫就可以了,但input流需要做很多準備工作來接受并最終重組這 個Object,所以ObjectInputStream的構造函數中就需要用到output初始化發送過來的header信息,這個方法叫做 readStreamHeader(),它將會去讀兩個Short值用于決定用多大的緩存來存放通道發送過來的二進制流,這個緩存的size因jre的版 本不同是不一樣的。所以output如果不先初始化,input的構造函數首先就無法正確運行。
對于上面兩個例子,第一個順序是嚴格的,第二個因為oos和ois連接的已經不是對方了,而是socket另外一端的流,需要嚴格按照另外一方對接的output流先于對接的input流打開才能順利運行。
這個writeObject和readObject本身就是線程安全的,傳輸過程中是不允許被并發訪問的。所以對象能一個一個接連不斷的傳過來,有很多人 在運行的時候會碰到EOFException, 然后百思不得其解,去各種論壇問解決方案。其實筆者這里想說,這個異常不是必須聲明的,也就是說它雖然是異常,但其實是正常運行結束的標志。EOF表示讀 到了文件尾,發送結束自然連接也就斷開了。如果這影響到了你程序的正確性的話,請各位靜下心來看看自己程序的業務邏輯,而不要把注意力狹隘的聚集在發送和 接受的方法上。因為筆者也被這樣的bug困擾了1整天,被很多論壇的帖子誤解了很多次最后得出的教訓。如果在while循環中去readObject,本 質上是沒有問題的,有對象數據來就會讀,沒有就自動阻塞。那么拋出EOFException一定是因為連接斷了還在繼續read,什么原因導致連接斷了 呢?一定是業務邏輯哪里存在錯誤,比如NullPoint、ClassCaseException、ArrayOutofBound,即使程序較大也沒關系,最多只要單步調適一次就能很快發現bug并且解決它。
難怪一位程序大師說過:解決問題90%靠經驗,5%靠技術,剩下5%靠運氣!真是金玉良言,筆者大概查閱過不下30篇討論在while循環中使用 readObject拋出EOFExceptionde 的帖子,大家都盲目的去關注解釋這個名詞、反序列化的行為或反對這樣寫而沒有一個人認為EOF是正確的行為,它其實很老實的在做它的事情。為什么大家都忽 略了真正出錯誤的地方呢?兩個字,經驗!
2.關于Java的多線程編程
關于Java的線程,初學或者接觸不深的大概也能知道一些基本概念,同時又會很迷惑線程到底是怎么回事?如果有人認為自己已經懂了不妨來回答下面的問題:
a.A對象實現Runnable接口,A.start()運行后所謂的線程對象是誰?是A么?
b.線程的wait()、notify()方法到底是做什么時候用的,什么時候用?
c.為什么線程的suspend方法會被標注過時,不推薦再使用,線程還能掛起么?
d.為了同步我們會對線程方法聲明Synchronized來加鎖在對象上,那么如果父類的f()方法加了Synchronized,子類重寫f()方法必須 也加Synchronized么?如果子類的f()方法重寫時聲明Synchronized并調用super.f(),那么子類對象上到底有幾把鎖呢?會 因為競爭產生死鎖么?
呵呵,各位能回答上來幾道呢?如果這些都能答上來,說明對線程的概念還是滿清晰的,雖說還遠遠不能算精通。筆者這里一一做回答,礙于篇幅的原因,筆者盡量說得簡介一點,如果大家有疑惑的歡迎一起討論。
首先第一點,線程跟對象完全是兩回事,雖然我們也常說線程對象。但當你用run()和start()來啟動一個線程之后,線程其實跟這個繼承了 Thread或實現了Runnable的對象已經沒有關系了,對象只能算內存中可用資源而對象的方法只能算內存正文區可以執行的代碼段而已。既然是資源和 代碼段,另外一個線程當然也可以去訪問,main函數執行就至少會啟動兩個線程,一個我們稱之為主線程,還一個是垃圾收集器的線程,主線程結束就意味著程 序結束,可垃圾收集器線程很可能正在工作。
第二點,wait()和sleep()類似,都是讓線程處于阻塞狀態暫停一段時間,不同之處在于wait會釋放當前線程占有的所有的鎖,而 sleep不會。我們知道獲得鎖的唯一方法是進入了Synchronized保護代碼段,所以大家會發現只有Synchronized方法中才會出現 wait,直接寫會給警告沒有獲得當前對象的鎖。所以notify跟wait配合使用,notify會重新把鎖還給阻塞的線程重而使其繼續執行,當有多個 對象wait了,notify不能確定喚醒哪一個,必經鎖只有一把,所以一般用notifyAll()來讓它們自己根據優先級等競爭那唯一的一把鎖,競爭 到的線程執行,其他線程只要繼續wait。
從前Java允許在一個線程之外把線程掛起,即調用suspend方法,這樣的操作是極不安全的。根據面向對象的思想每個對象必須對自己的行為負責,而對 自己的權力進行封裝。如果任何外步對象都能使線程被掛起而阻塞的話,程序往往會出現混亂導致崩潰,所以這樣的方法自然是被斃掉了啦。
最后一個問題比較有意思,首先回答的是子類重寫f()方法可以加Synchronized也可以不加,如果加了而且還內部調用了super.f()的話理論上是應該對同一對象加兩把鎖的,因為每次調用Synchronized方法都要加一把,調用子類的f首先就加了一把,進入方法內部調用父類的
f又要加一把,加兩把不是互斥的么?那么調父類f加鎖不就必須永遠等待已經加的鎖釋放而造成死鎖么?實際上是不會的,這個機制叫重進入,當父類的f方法試 圖在本對象上再加一把鎖的時候,因為當前線程擁有這個對象的鎖,也可以理解為開啟它的鑰匙,所以同一個線程在同一對象上還沒釋放之前加第二次鎖是不會出問 題的,這個鎖其實根本就沒有加,它有了鑰匙,不管加幾把還是可以進入鎖保護的代碼段,暢通無阻,所以叫重進入,我們可以簡單認為第二把鎖沒有加上去。
總而言之,Synchronized的本質是不讓其他線程在同一對象上再加一把鎖。
Java雜談
(五)本來預計J2se只講了第四篇就收尾了,可是版主厚愛把帖子置頂長期讓大家瀏覽讓小弟倍感責任重大,務必追求最到更好,所以關于J2se一些沒有提到的部 分,決定再寫幾篇把常用的部分經驗全部寫出來供大家討論切磋。這一篇準備講一講Xml解析包和Java Swing,然后下一篇再講java.security包關于Java沙箱安全機制和RMI機制,再進入J2ee的部分,暫時就做這樣的計劃了。如果由于 實習繁忙更新稍微慢了一些,希望各位見諒!
1. Java關于XML的解析
相信大家對XML都不陌生,含義是可擴展標記語言。本身它也就是一個數據的載體以樹狀表現形式出現。后來慢慢的數據變成了信息,區別是信息可以包括可變的 狀態從而針對程序硬編碼的做法變革為針對統一接口硬編碼而可變狀態作為信息進入了XML中存儲。這樣改變狀態實現擴展的唯一工作是在XML中添加一段文本 信息就可以了,代碼不需要改動也不需要重新編譯。這個靈活性是XML誕生時候誰也沒想到的。
當然,如果接口要能提取XML中配置的信息就需要程序能解析規范的XML文件,Java中當然要提高包對這個行為進行有利支持。筆者打算講到的兩個包是 org.w3c.dom和javax.xml.parsers和。(大家可以瀏覽一下這些包中間的接口和類定義)
Javax.xml.parsers包很簡單,沒有接口,兩個工廠配兩個解析器。顯然解析XML是有兩種方式的:DOM解析和SAX解析。本質上并沒有誰好誰不好,只是實現的思想不一樣罷了。給一個XML文件的例子:
A Cat
所謂DOM解析的思路是把整個樹狀圖存入內存中,需要那個節點只需要在樹上搜索就可以讀到節點的屬性,內容等,這樣的好處是所有節點皆在內存可以反復搜索重復使用,缺點是需要消耗相應的內存空間。
自然SAX解析的思路就是為了克服DOM的缺點,以事件觸發為基本思路,順序的搜索下來,碰到了Element之前觸發什么事件,碰到之后做什么動作。由 于需要自己來寫觸發事件的處理方案,所以需要借助另外一個自定義的Handler,處于org.xml.sax.helpers包中。它的優點當然是不用 整個包都讀入內存,缺點也是只能順序搜索,走完一遍就得重來。
大家很容易就能猜到,接觸到的J2ee框架用的是哪一種,顯然是DOM。因為類似Struts,Hibernate框架配置文件畢竟是很小的一部分配置信 息,而且需要頻繁搜索來讀取,當然會采用DOM方式(其實SAX內部也是用DOM采用的結構來存儲節點信息的)?,F在無論用什么框架,還真難發現使用 SAX來解析XML的技術了,如果哪位仁兄知道,請讓筆者也學習學習。
既然解析方式有了,那么就需要有解析的存儲位置。不知道大家是否發現org.w3c.dom這個包是沒有實現類全部都是接口的。這里筆者想說一下Java 如何對XML解析是Jdk應該考慮的事,是它的責任。而w3c組織是維護定義XML標準的組織,所以一個XML結構是怎么樣的由w3c說了算,它不關心 Java如何去實現,于是乎規定了所有XML存儲的結構應該遵循的規則,這就是org.w3c.dom里全部的接口目的所在。在筆者看來,簡單理解接口的 概念就是實現者必須遵守的原則。
整個XML對應的結構叫Document、子元素對應的叫做Element、還有節點相關的Node、NodeList、Text、Entity、CharacterData、CDATASection等接口,它們都可以在XML的語法中間找到相對應的含義。由于這里不是講解XML基本語法,就不多 介紹了。如果大家感興趣,筆者也可以專門寫一篇關于XML的語法規則帖與大家分享一下。
2. Java Swing
Swing是一個讓人又愛又恨的東西,可愛之處在于上手很容易,較AWT比起來Swing提供的界面功能更加強大,可恨之處在于編復雜的界面工作量實在是 巨大。筆者寫過超過3000行的Swing界面,感覺用戶體驗還不是那么優秀。最近又寫過超過6000行的,由于功能模塊多了,整體效果還只是一般般。體 會最深的就一個字:累!所以大家現在都陸續不怎么用Swing在真正開發的項目上了,太多界面技術可以取代它了。筆者去寫也是迫于無奈組里面大家都沒寫過,我不入地域誰入?
盡管Swing慢慢的在被人忽略,特別是隨著B/S慢慢的在淹沒C/S,筆者倒是很愿意站出來為Swing正身。每一項技術的掌握絕不是為了流行時尚跟 風。真正喜歡Java的朋友們還是應該好好體會一下Swing,相信在校的很多學生也很多在學習它。很可能從Jdk 1.1、1.2走過來的很多大學老師可能是最不熟悉它的。
Swing提供了一組輕組件統稱為JComponent,它們與AWT組件的最大區 別是JComponent全部都是Container,而Container的特點是里面可以裝載別的組件。在Swing組件中無論是JButton、JLabel、JPanel、JList等都可以再裝入任何其他組件。好處是程序員可以對Swing組件實現“再開發”,針對特定需求構建自己的按鈕、標 簽、畫板、列表之類的特定組件。
有輕自然就有重,那么輕組件和重組件區別是?重組件表現出來的形態因操作系統不同而異,輕組件是Swing自己提供GUI,在跨平臺的時候最大程度的保持一致。
那么在編程的時候要注意一些什么呢?筆者談談自己的幾點經驗:
a.明確一個概念,只有Frame組件才可以單獨顯示的,也許有人會說JOptionPane里面的靜態方法就實現了單獨窗口出現,但追尋源代碼會發現其實現 實出來的Dialog也需要依托一個Frame窗體,如果沒有指定就會默認產生一個然后裝載這個Dialog顯示出來。
b.JFrame是由這么幾部分組成:
最底下一層JRootPane,上面是glassPane(一個JPanel)和layeredPane(一個JLayeredPane),而layeredPane又由contentPane(一個JPanel)和menuBar構成。我們的組件都是加在
contentPane上,而背景圖片只能加在layeredPane上面。至于glassPane是一個透明的覆蓋了contentPane的一層,在特定效果中將被利用到來記錄鼠標坐標或掩飾組件。
c.為了增強用戶體驗,我們會在一些按鈕上添加快捷鍵,但Swing里面通常只能識別鍵盤的Alt鍵,要加入其他的快捷鍵,必須自己實現一個ActionListener。
d.通過setLayout(null)可以使得所有組件以setBounds()的四個參數來精確定位各自的大小、位置,但不推薦使用,因為好的編程風格不 應該在Swing代碼中硬編碼具體數字,所有的數字應該以常數的形式統一存在一個靜態無實例資源類文件中。這個靜態無實例類統一負責Swing界面的風 格,包括字體和顏色都應該包括進去。
e.好的界面設計有一條Golden Rule: 用戶不用任何手冊通過少數嘗試就能學會使用軟件。所以盡量把按鈕以菜單的形式(不管是右鍵菜單還是窗體自帶頂部菜單)呈現給顧客,除非是頻繁點擊的按鈕才有必要直接呈現在界面中。
其實Swing的功能是相當強大的,只是現在應用不廣泛,專門去研究大概是要花不少時間的。筆者在各網站論壇瀏覽關于Swing的技巧文章還是比較可信 的,自己所學非常有限,各人體會對Swing各個組件的掌握就是一個實踐積累的過程。筆者只用到過以上這些,所以只能談談部分想法,還望大家見諒!