Java 學習總結
目錄
最近因爲工作的需要,學習了java和android 的應用程序開發,費時一個多月,一個月之前,我還只是一個C程序員,在C的道路上算是積累的一些經驗,學習java除了是工作需要的因素外,另外一部分原因就是想感受下面向對象的編程思想。
第一章:Java入門(C與java的差異)
我的java學習的時間大概是1周,感覺對java的掌握還是比較深入,算是入門了吧,能夠這麼快入門,可能得益於有C語言的基礎,還有就是有一個好老師。
程序Yuan的習慣之一:一邊學習一邊練習,主要是找到編程的感覺(人的記憶分很多種,編程感覺就是屬於機械式記憶的一種)個人覺得看視頻要要比看書要形象得多,所以我最初的學習是通過看mars的Java4Android視頻來了解java,視頻學習最大的問題在於費時間,有的人直接選擇看書或者來得更快些(那些經常看書的人就比較有福了),我在看視頻的時候使用了KMplay的快速播放模式,視頻的播放速度是正常的2~3倍,對於一些冗長的細節甚至可以跳過,我將自己的java學習也分爲了三個階段:第一部分是java程序設計基礎,在這個階段主要是掌握java最基本的語法(基本的數據類型、變量、循環、選擇、數組的使用),在主觀的感受上,java的基本語法與C語言沒有什麼差別。相信C程序員可能都看過老美出過的一本叫做《C陷阱與缺陷》的書,裏面介紹了一些C語言編寫時應該注意的一些設計原則和編程技巧,java基本上可以完美的避過這些問題,舉個最常見的例子,《C陷阱與缺陷》寫到if(0 == variable)…. 可以減少編程失誤帶來的問題。可是java要求if的條件表達式必須是boolean型,如果將程序寫成if(variable =0)將是一個非法的語句。以下列出我所瞭解到的C與java在基本語法上的差異
1.基本數據類型:
Java的數據類型與C不完全一致,數據所佔內存的長度也不完全一致,大家看仔細了
2.類型轉換:
各種數據類型在進行強制類型轉換的時候保持連個原則:一是轉換前後的數據要相互兼容,而是轉換過程儘量不丟失精度。
3.運算符:
java中運算符的優先級基本保持與C一致(‘&’、‘*’、‘->’、‘.’、‘,’被java去除)
4.局部變量:
C語言所理解的局部變量和java是一致的(C語言規定在函數內存聲明的變量當跳出函數後將不再有效,static除外,java也是如此)
5.一維數組使用方法與內存分配:
java一維數組 int a[]或者int []a,內存分配與C一致,由於java不存在指針的概念,所以是a在java代表一個數組對象,可以被其他數組對象引用,說到底java中的引用就是C語言中的指針,如果你懂C的指針,你就能明白java中的引用,java封裝了C語言中指針的一些特性,避免程序員犯錯, 在C語言中,指針幾乎可以表示內存中的任意的字節地址,但是在java中被引用的只能是對象,所有的地址都已經被對象、屬性、方法封裝起來,引用是指針的一個子集。
6.多維數組內存分配:
java與C語言最明顯的特點體現在內存分配上,C語言的世界裏,內存的分配完全要靠程序員來完成(內存的名字、類型、大小、要考慮內存的對齊/泄露/釋放/越界….其中最難解決的就是內存泄露和越界),在java的世界裏面,程序員不需要關心這些繁瑣的問題(開心吧),而是把內存形象化爲具體的對象及對象的屬性(一個對象的實例化就是爲其分配內存,回收則由系統自動完成)。在C語言中二維數組是一串連續的內存,但是在java中二維數組卻是由兩個一維數據疊加起來的(系統先創建一個二維數組的空殼,然後創建兩塊內存填充到二維數組裏面)
第二章 Java 面向對象基礎
2.1對象的概念:
引用經典的語句“萬物皆爲對象”,所有的事物皆有兩個方面:對象的描述(稱爲屬性),對象能夠做什麼(對象的方法)。
以人爲例,人的屬性可以有膚色、年齡、性別、籍貫、受教育水平、身份證號、工作經驗、甚至戴不戴眼睛、生活的地區、喜好····;一個人所能做的事情就是對象的方法,比如寫作、編程、修水管····
面向對象的思想:以對象爲中心、先抽象出對象的樣子(有哪些屬性和方法,被稱爲class),之後再決定在哪裏生成這個對象,最後纔是調用對象的方式來完成具體的事情,在設計程序時自頂而下的設計方法,一次考慮的是整個程序框架、程序需要使用到的資源和需要完成的事情、最後纔是通過一定的順序整合資源來完成具體的任務、在完成具體的任務的時候才考慮具體的算法。
面向過程的思想:由過程、步驟、函數組成、以過程爲核心,在程序設計的時候依次考慮的是完成任務需要哪些過程、需要用到的算法、函數,很多時候都是在程序設計的後期纔去添加新的數據結構、變量,變量和數據結構很有可能是散亂的擺列在代碼的任意一個可能的地方。
2.2類的概念
如果非要同C語言做對比,java 中的類對應的是C語言中的結構體。類的出現能夠實現代碼的高內聚和低耦合,個人覺得高內聚和第耦合實際是一個統一的整體,通常在編程的時候其中的一個設計原則就是寫要有高的可讀性,尤其是在大型的軟件項目中,這一點顯得尤爲重要,因爲你寫的代碼不可能只有一個人來維護,當你離開一個項目或者一個公司的時候,能夠讓接替你的人儘快掌握你的代碼的含義是首要的事情,如果你寫的代碼很糟糕,維護一段代碼的成本會很高。提高可讀性的其中一個方法就是將你代碼要表達的意思能夠像類一樣集中起來,有類名,屬性,變量就能夠做到讓你寫的這塊代碼作用更明確些。java 的終極目標是消除重複的代碼,如果掌握了一個類的作用,那麼就能夠很清晰的知道在什麼地方可以使用到這個類。
2.3封裝的概念
封裝的目的是要展示給外界它希望外界看到的,屏蔽不希望外界看到的,如此一個對象與外界聯繫的接口就比較統一,外界只能通過某個方法去訪問和指揮對象完成某些工作,而具體要怎麼做則有由對象來決定。
2.4 繼承的概念
繼承的目的比較明顯:一是提高可擴展性,二是提高複用性。代碼的設計和編寫總是有時代背景,時代的等衆多要素的變化會帶來的新的需求,而原有的代碼架構已經成型,採用繼承的方式則不需要重寫原有代碼,相當於是在原來的基礎上抽象出新的類,而新的類除了包含父類的屬性和方法外,還包含了自己獨有的功能。
2.5 多態的概念
多態是指編譯時類型變化,運行時類型不變。所以多態分爲兩種:一是“編譯時”多態,而是“運行時”多態。所謂人的認識是主觀的,對象是客觀的。多態是一種數據類型的強制轉換。
編譯時多態是指:在加載對象的時候根據你強制轉換的類型來決定能夠訪問的屬性和方法。
運行時多態是指:一個對象可以被轉換成多種類型,但是其原始的內存塊(大小/位置)並不會發生變化。
從C語言的角度上分析,是否能轉換成功取決於你最初new 一個對象時分配的內存模型。例如生成了對象student,該對象的類型是B,而B又是A的子類,在內存模型上,student包含了B和A的所有內存,所以student要強制轉換成A也是可以的,且student 所佔用的內存模型並沒有因爲強制轉換成A類之後而丟失,所以之後student還可以再從A類型強制轉換成B類型。如果最初new的對象就是A類型,其內存就只包含A,之後又想轉換成B類型是出錯滴。
使用instanceof 關鍵字可以判斷出一個類是否是某個類的實例
2.6類的創建於使用
創建一個類:使用class關鍵字,定義一個類不會分配內存(類似於定義C中的結構體)
創建一個對象:使用new關鍵字實現,如果定義了一個student類,new studet()就會生成一個對象(就是爲這個類分配內存),很簡單吧。
構造方法:一個特殊的方法,當一個對象被創建的的時候一定會調用的方法(其作用相當於C中對一個數據結構的初始化),java是抽象出了內存的一個生命週期,就是初始化時期,調用構造方法就是告訴系統要如何初始化這塊內存。這個大多數C 創建內存時需要做的事情,java就乾脆將這個過程提出來。
構造方法與其他方法不同點在與構造方法沒有返回值,方法的名字必須要和類的名字一致。
2.7 重載的概念(overloading)
這裏講的重載是指方法的重載,意思是一個類或者子類中包含的方法名字可以重複,但是方法的參數可以不一致,調用該方法時只要傳入的參數不一致就能實現調用不同的方法。
2.8 複寫的概念(overriding)
複寫是指子類中可以編寫了一個與父類名字和參數都一樣的方法,可能是父類的方法不能滿足子類的需要,也有可能是父類本來就希望子類來實現這個方法。
2.9 抽象類的概念(abstract)
抽象類是指在定義一個類的時候並不實現類中的方法,只聲明這個方法的返回值,方法的名字和所需要傳遞的參數,要求子類在繼承的時候要去實現這些抽象的方法。用處:當在定義一個類的方法時,可能這個方法在不同的環境下需要寫不同的代碼,但實現的總體功能是不變的。
抽象類的四條規則:
·抽象類和抽象類的方法必須使用abstract來聲明
·抽象類不能被實例化,也就是不能使用new 關鍵字來產生一個對象
·抽象類只需要聲明,而不需要具體的實現
·含有抽象類的方法必須聲明爲抽象類,抽象類的子類必須是想抽象類中的所有方法,否則這個子類還是一個抽象類
2.10 接口的概念(interface)
接口是一種特殊的抽象類,相當於是抽象類的子集,所以必須滿足抽象類中的規則。
接口中也存在類和方法,只是在接口中要求接口的屬性全部都是final 類型且必須初始化屬性的值,,所有的類也都是抽象類,不會包含有一般方法。接口的 abstract、final關鍵字是可以省略的。(原因你懂的)
與抽象類不同的是一個子類只能同時繼承一個抽象類,但是卻可以同時實現多個接口。
在打造一個新類的過程被稱爲接口的事項,使用implements關鍵字標識。
2.11內部類
內部類就是定義在一個類裏面的類,內部類的使用非常廣泛(定義內部類的原則應該是,當一個類A只能被其他一種類B使用到的時候,那這個A類就可以定義在B類的內部)。內部類一共有四種類型:
·成員內部類
·局部內部類
·靜態內部類
·匿名內部類
成員內部類是指非靜態的定義在一個類的內部但不定義在任何方法當中的類,成員內部類中不能有靜態屬性。
局部內部類是指定義在一個類的方法中的內部類,如果這個局部內部類要訪問所在方法中的局部變量,那這個局部變量的屬性必須是final。
靜態內部類是指靜態的定義在一個類的內部但不定義在任何方法中的內部類。
匿名內部類是一種特殊的局部內部類,它是通過匿名的方式去實現一個接口。
2.12異常的概念
Java中的異常類似於C中的宕機,常見的異常有:
·算術異常(ArithmeticException)。
·沒有給對象開闢內存空間時會出現空指針異常(NullPointerException)。
·找不到文件異常(FileNotFoundException)。
異常的處理
Java 中異常是以類的形式存在的,類的繼承結構如下
有了對異常的捕捉和處理,當發生異常的時候,系統就還能正常運行,不至於系統崩潰。
2.13 包的概念(package)
當開發一個大型項目的時候,不同的開發人員有可能會定義出相同的類名,如果希望這些相同的類名能夠正常的工作,就可以使用package來幫忙。
當在一個類文件開始的地方聲明包名的時候,那這個內會被納入到當前的包中。在實際存放代碼的時候,Constant會被放置在com/bn/rcgl/目錄下
當在某個類中要使用到其他包中的類時,可以使用import 關鍵字來導入這個包到當前類中。
2.14 訪問權限
訪問權限一共四種:public、protected、default、private
·public
當一個屬性或者方法被聲明爲public的時候,那麼它將可以被所有的類訪問
·protected
當一個屬性或者方法被聲明爲protected的時候,那麼它將可以被當前包的所有類和其他包中的子類訪問
·default
當一個屬性或者方法被聲明爲default的時候,那麼它將只能被當前包中的所有類使用
·private
當一個屬性或者方法被聲明爲private的時候,那麼它將只能在當前內的內部使用,且其子類也不能訪問。
第三章 java應用程序
3.1 多線程
3.1.1 多線程與多進程的概念
Java 中多線程和多進程的概念與C語言是一致的。每個獨立的進程會使用獨立的內存空間,一個進程中可能多個進程,這些線程共享該進程的一塊地址空間。
3.1.2 線程的創建
第一種是繼承Thread類(extends Thread)
第二種是實現Rnnnanle接口
兩種創建方式的差別
- implements 相當於回調函數,在不同的線程中使用的是相同的方法和屬性
- extends 相當於是在不同的線程中使用各自獨立的方法和屬性
3.1.3 線程的操作方法
線程操作方法
- Thread.currentThread().getName();
獲取當前線程的名字
- thread.isAlive()
檢查當線程是否被激活
- setDaemon(true)
將線程設置爲後臺線程,對java來說,只要有一個前臺線程正在運行這個進程就不會結束。
由於將myThread設置爲後臺線程,所以當執行完main函數之後整個進程就結束了。
- thread1.join();
強制運行thread1所引用的函數,join還可以帶參數以決定運行的時間。
- Thread.sleep(millsecond);
線程的休眠,以毫秒爲單位。
- thread1.interrupt();
用來中斷thread1的運行。
3.1.4線程的同步 (synchronized)
- 同步代碼塊
- 同步方法
- 死鎖
當幾個不同的線程需要使用到兩個以上的相同“同步資源”的時候,應該保證獲取資源的順序是的一致性或釋放資源的逆序。
比如線程th1 和th2 都要使用到同步資源A、B,那麼要保證th1和th2在獲取A/B是的順序都是A->B(或者是B->A),釋放資源時的順序要和獲取資源要一致。
否則當th1先獲得A ,而B此時已經被th2獲得,此時th1需要獲取資源B,而th2需要獲取資源A,就會造成一直等待對方線程釋放資源的情況,從而導致死鎖。
3.1.5線程間的同步通訊方法
- wait()
- notify()
- notifyall()
3.2文件I/O操作
3.2.1 摘要
·Java中要進行IO操作,需要導入java.io包。
·Java中的File類是唯一操作磁盤文件的類。
·Java中的數據操作主要分爲兩種:
1)、 字節流(OutputStrea、InputStream)
2)、 字符流(Writer、Reader)
這四個類都是抽象類,使用時,都必須依靠其子類實例化。
·Java定義了兩個特殊的流對象:System.in和System.out。System.in對應鍵盤,是InputStream類型的,程序使用System.in可以讀取從鍵盤上輸入的數據;System.out對應顯示器,可以向顯示器上輸出內容。
·InputStreamReader和OutputStreamWriter,這兩個類是字節流和字符流之間轉換的類,InputStreamReader可以將一個字節流中的字節解碼成字符,OuputStreamWriter將寫入的字符編碼成字節後寫入一個字節流。
·一個類實現了Serializable接口之後,此類的對象可以被序列化,就表示可以保存在文件之中、或網絡傳輸之中。如果不希望類中的某個屬性被保存下來,可以用transient關鍵字聲明屬性。
3.2.2 繼承關係圖
3.2.3 知識要點
- File 類
- RandomAccessFile類
- 流類
- 字節流
- InputStream(輸入字節流)
- FileInputStream(文件輸入流)
- DataInputStream
- PipedInputStream(管道輸入流)
- ByteArrayInputStream(虛擬文件輸入流)
- BufferedInputStream
- FileInputStream(文件輸入流)
- OutputStream(輸出字節流)
- FileOutputStream(文件輸出流)
- PrintStream(打印)
- DataOutputStream
- PipedOutputStream(管道輸出流)
- ByteArrayOutputStream(虛擬文件輸出流)
- BufferedOutputStream
- FileOutputStream(文件輸出流)
- InputStream(輸入字節流)
- 字符流
- Reader
- FileReader(文件)
- PipedReader(管道)
- BufferedReader
- Writer
- FileWriter(文件)
- PipedWriter(管道)
- PrintWriter(打印)
- BufferedWriter
- Reader
- 其他流
- 管道流
- PipedInputStream
- PipedWriter
- PipedOutputStream
- PipedReader
- 虛擬文件流
- ByteArrayOutputStream
- ByteArrayInputStream
- 打印流
- PrintStream
- PrintWriter
- 數據處理流
- DataInputStream
- DataOutputStream
- 合併流
- SequenceInputStream
- 管道流
- IO包中類的層次關係
- 字節流
- 字符編碼
- 對象序列化
- ObjectlnputStream
- ObjectOutputStream
- Serializable
- 字符編碼
- GBK
- Unicode
- ASCII