JAVA SE基礎筆記

第一天  JDK安裝、快捷鍵、JAVA語言特點

1.Java語言的概述

1.1 Java語言的背景

   Java語言誕生於1995年,在編程語言排行榜佔據重要的地位。                 

   Java語言之父是高斯林,以前隸屬於sun公司,現在隸屬於oracle-sun公司(甲骨文)。

1.2 Java語言的主要版本

(1)JavaSE版本

   - Java Platform, Standard Edition)稱之爲“Java平臺標準版”。

   - 主要用於編寫桌面應用程序。

(2)JavaEE版本

   - Java Platform,Enterprise Edition)稱之爲“Java平臺企業版”。  

   - 主要用於編寫具有B/S結構的電子商務網站、門戶網站以及電信計費系統等。

(3)JavaME版本

   - Java Platform,Micro Edition)稱之爲Java 平臺微型版。 

   - 隨着Android系統的普及,該技術已經走向淘汰。

2.開發環境的搭建和使用(重點)

2.1 jdk的下載和安裝

(1)jdk的下載

   下載方式一:直接去官網下載 -ww.sun.com/www.oracle.com

   下載方式二:直接用谷歌/百度/搜狗搜索 jdk1.764位 下載和安裝  

(2)jdk的安裝

   若下載的是綠色版,則直接解壓即可。

   若下載的是安裝版,根據提示一步步點擊下一步即可,切記不要有中文路徑。

3.2 相關的概念

   javac.exe - Java語言的編譯器,用於將高級源代碼文件翻譯成字節碼文件。

   java.exe - Java語言的解釋器,用於啓動java虛擬機進行字節碼文件的解釋並執行

   jre - Java運行時環境信息,只要運行java程序就必須安裝jre。

   jdk - Java開發工具包,只要編寫/開發Java語言程序就必須安裝jdk,jdk自帶jre。

   JVM - Java虛擬機,並不是真實存在的主機,作爲java程序和計算機之間的橋樑。

3.3 環境變量的概念和配置

(1)基本概念

   環境變量就是指用於存放環境信息並且數值可以改變的量。

   通常情況下若啓動一個可執行文件需要增加路徑纔可以,當把路徑放入環境變量中後,只需要通過可執行文件的名稱就可以啓動該程序。

(2)配置方式

   計算機=> 右鍵,選擇屬性 => 高級系統設置 => 高級=> 環境變量 => 系統變量 => 找到Path變量點擊編輯,將javac.exe所在的路徑信息加入到該變量值的最前面,添加英文版的分號=> 一路點擊確定即可。

   切記Path變量值原來的內容不要改動,以避免帶來災難性的後果!!!

3.4 Java程序的開發流程

   (1)新建文本文檔,將默認的xxx.txt重命名爲xxx.java。

   (2)使用記事本的方式打開該文件,並編寫Java代碼保存。

   (3)啓動dos窗口,使用cd命令將路徑切換到xxx.java所在的目錄中。

   (4)使用javac編譯器根據xxx.java生成xxx.class文件。    

   (5)使用javaxxx解釋並執行該文件。

3.5 常用的快捷鍵

   ctrl+s - 保存

   ctrl+a - 全選

   ctrl+c - 複製

   ctrl+x - 剪切

   ctrl+v - 粘貼

   ctrl+f - 查找

   ctrl+z - 撤銷

  alt+tab - 切換任務窗口

   windows+tab - 切換任務窗口

   windows+d  - 顯示桌面

   windows+e  - 打開計算機的磁盤界面

   windows+l  - 實現鎖屏

   windows+r  - 啓動運行窗口,輸入cmd再回車啓動dos窗口

   ctrl+alt+delete - 啓動任務管理器

   使用shift鍵可以進行中英文的切換。

3.6 常用的dos命令

   d:  - 表示切換到D盤

   cd 目錄名 - 表示切換到指定的目錄中

   cls - 表示清屏

   dir  -表示查看當前目錄中的所有內容

   cd .. - 表示切換到上一級目錄

3.7 Java語言的特點

  (1)Java語言是一門純面向對象的編程語言。

  (2)Java語言具有跨平臺的特性,也就是同一份字節碼文件可以在不同的平臺上執行,

     是因爲有Java虛擬機負責翻譯工作。

  (3)Java語言具有自動垃圾回收機制。

 

 

 

 

 

 

 

 

第二、三天   變量和註釋、數據類型及轉換、運算符

1.變量和註釋(重點)

1.1 變量的基本概念以及分類

   當需要在程序中記錄一個數據內容時,則需要聲明一個變量來保存,變量本質上就是內存條中的一塊區域。

   由於記錄的數據內容不同導致所需要的內存空間大小不同,在Java語言使用數據類型加以描述,而使用變量名來描述該內存空間的地址信息。

 

變量分類:按照被聲明位置劃分:局部變量、成員變量(也叫“實例變量”、“域”)、 靜態變量(也叫類變量)。

http://blog.chinaunix.net/uid-26434689-id-3328442.html

靜態變量(也叫類變量)是類中獨立於方法之外的變量,static 修飾。(static表示全局的靜態的,用來修飾成員變量和成員方法,或靜態代碼塊(靜態代碼塊獨立於類成員,jvm加載類時會執行靜態代碼塊,每個代碼塊只執行一次,按順序執行))。

成員變量(也叫實例變量)也是類中獨立於方法之外的變量,不過沒有static修飾。

局部變量是類的方法中的變量。

看下面的僞代碼說明:

public class Variable{ 類名

     static int allClicks=0;//靜態變量也叫類變量

     String str="hello world";//實例變量也叫成員變量

     public void method(){方法名

        int i =0;//局部變量

     }

}

成員變量也稱爲:實例變量,在實體類或數據類中被稱爲屬性字段。當成員變量可以改變時,被稱爲對象的狀態。

常量:final修飾,值一旦給定就不能修改

 

   

1.2 變量的聲明和初始化

   數據類型 變量名 = 初始值;   - 其中=初始值是可以省略的,但分號不可以省略

如:

   int id = 1001; - 推薦使用該方式

   int id;   

1.3 使用變量的注意事項

  (1)使用變量之前必須聲明。

  (2)使用變量之前必須指定初始值。

  (3)不允許聲明同名的變量。

  (4)每個變量都擁有自己獨立的作用域(有效的範圍)。

補充:

   在方法體中聲明的變量叫做局部變量,局部變量的作用域爲:聲明開始到方法體結束

1.4 標識符(變量名)的命名規則

  (1)必須由字母、數字、下劃線_以及美元$組成,其中數字不能開頭。

     如:id、name、name2等。

  (2)不能使用Java語言中的關鍵字/保留字,也就是Java語言中用來代表特殊含義的單詞

     如:class、public、void、int等

  (3)區分大小寫,長度沒有限制但不宜過長。

     如:day 和 Day代表不同的標識符,不推薦使用。

  (4)儘量使用英文單詞的組合做到見名知意,雖然支持中文,但不推薦使用。

     如:sendMsgToAll、minute、time、length  年齡

1.5 常見的編程規範

  (1)儘量使用空格、縮進以及空行來提高代碼的可讀性和層次感。

  (2)當類名由多個單詞組成時,要求每個單詞的首字母都要大寫。

  (3)當變量名由多個單詞組成時,要求從第二個單詞起每個單詞的首字母要大寫。

1.6 註釋

   單行註釋 - 從//開始一直到本行的末尾之間的內容都是註釋內容。

   多行註釋 - 從/*開始一直到*/結尾之間的內容都是註釋內容。

   其中多行註釋要求不允許嵌套使用,如:/* /**/ */ 是錯誤的。

2.數據類型(重點)

2.1 數據類型的分類

  在Java語言中將數據類型分爲兩大類:基本數據類型 和 引用數據類型。

  其中基本數據類型主要有(8種):

      byte/short/int/long - 用於描述整數數據的類型,如:666。

      float/double        - 用於描述小數數據的類型,如:3.14。

      char                - 用於描述字符數據的類型,如:'a'。

      boolean             - 用於描述真假信息的類型,如:true 和 false。

  其中引用數據類型主要有:

      數組、類、接口、枚舉以及標註(瞭解)。

 

2.2 常用的進制(數學、理解基本數據類型)

  日常生活中採用十進制加以描述,逢十進一,權重爲:10^010^1 10^2 ...

  計算機中採用二進制加以描述,逢二進一,權重爲:2^02^1 2^2 ...  

  八進制和十六進制爲了簡化二進制的表示形式。

  在計算機中採用二進制的最高位(最左邊)來代表符號位,若該位是0則表示非負數,若該位是1則表示負數。

2.3 進制之間的轉換(數學、理解基本數據類型)

(1)十進制和二進制之間的轉換(要求每個人掌握)

   a.正十進制轉換爲二進制的方式

     1)除2取餘法,讓十進制整數不斷地除以2取出餘數,直到商爲0將所有餘數逆序排列

     2)拆分法,將十進制整數拆分爲若干個二進制權重的和,若該權重出現則下面寫1,

               若該權重沒有出現則下面寫0(推薦)。

   如:12

       128 64 32 16    8 4 2 1       12 = 8 + 4

          0   0   0    0     1 1 0 0      12轉換爲二進制的結果是:00001100  

   b.正二進制轉換爲十進制的方式

     1)加權法,讓二進制的每個數字乘以當前位的權重最後相加。

   如:00001100

    0000 1100 => 0*2^7 + 0*2^6 + 0*2^5 +0*2^4 + 1*2^3 + 1*2^2 + 0*2^1 + 0*2^0

              => 0 + 0 + 0 + 0 + 8 + 4 + 0 +0

              => 12 

  

   c.負十進制轉換爲二進制的方式

     1)先將該整數的絕對值轉換爲二進制,然後進行按位取反再加1.

   如:-12

       12轉換爲二進制:00001100      12的二進制:0000 1100  

       按位取反:      1111 0011     -12的二進制:11110100 +

       再加1:          1111 0100     --------------------------   

                                               1 0000 0000(最高位溢出)

   d.負二進制轉換爲十進制的方式

    1)先進行按位取反加1,然後轉換爲十進制整數,最後添加負號

   如:11110100

       1111 0100進行按位取反:00001011

       加1:                  0000 1100

       轉換爲十進制整數:     12

       最後添加負號:         -12

2.3原碼反碼補碼擴展:

原碼、反碼以及補碼的概念。

http://blog.csdn.net/u011080472/article/details/51280919

http://blog.csdn.net/liushuijinger/article/details/7429197

機器數:一個數在計算機中的二進制表示形式, 叫做這個數的機器數。機器數是帶符號的,在計算機用一個數的最高位存放符號, 正數爲0,負數爲1。

真值:將帶符號位的機器數對應的真正數值稱爲機器數的真值。

例:0000 0001的真值 =+000 0001 = +1,10000001的真值 = –0000001 = –1

原碼:如果機器字長爲n,那麼一個數的原碼就是用一個n位的二進制數,其中最高位爲符號位:正數爲0,負數爲1。剩下的n-1位表示概數的絕對值。

例如: X=+101011 , [X]原=00101011    X=-101011 , [X]原=10101011 

位數不夠的用0補全。

PS:正數的原、反、補碼都一樣:0的原碼跟反碼都有兩個,因爲這裏0被分爲+0和-0。

反碼:反碼就是在原碼的基礎上,符號位不變其他位按位取反(就是0變1,1變0)。

補碼:

補碼就是在反碼的基礎上按照正常的加法運算加1。

例如:X=-101011 , [X]原=10101011 ,[X]反=11010100,[X]補=11010101

PS:0的補碼是唯一的,如果機器字長爲8那麼[0]補=00000000。

 

移碼:

移碼最簡單了,不管正負數,只要將其補碼的符號位取反即可。

例如:X=-101011 , [X]原=10101011 ,[X]反=11010100,[X]補=11010101,[X]移=01010101

 

 

(2)八進制和二進制之間的轉換(熟悉)

   a.二進制轉換爲八進制的方式

     1)將每三位二進制合併爲一位八進制,並使用0作爲前綴代表八進制。

    如:

       010 110 => 026

   b.八進制轉換爲二進制的方式

     1)將每一位八進制拆分爲三位二進制,並使用0b作爲前綴代表二進制(jdk1.7)。

    如:

       075 => 0b111 101

 

(3)十六進制和二進制之間的轉換(熟悉)

   a.二進制轉換爲十六進制的方式

    1)將每四位二進制合併爲一位十六進制,並使用0x作爲前綴代表十六進制。

    如:

       1010 0011 => 0xa3(十六進制中使用a~f來代表10 ~15).

   b.十六進制轉換爲二進制的方式

    1)將每一位十六進制拆分爲四位二進制,並使用0b作爲前綴代表二進制。

    如:

       0xab => 0b1010 1011

2.4 單個字節表示的整數範圍(重中之重)

    在計算機中單個字節表示八位二進制位,最高位(最左邊)的二進制位代表符號位,若該位是0則表示非負數,若該位是1則表示負數,具體如下:

    非負數的表示範圍是:00000000 ~ 0111 1111  => 0 ~ 127 => 0 ~2^7-1 

其中0000 0000轉換爲十進制整數就是0;

其中0111 1111轉換爲十進制整數:64 +32 + 16 + 8 + 4 + 2 + 1 = 127;

    負數的表示範圍是:  1000 0000 ~ 1111 1111 => -128 ~ -1 =>-2^7 ~ -2^0

其中1000 0000轉換爲十進制整數:

    按位取反:01111111  => 加1:10000000 => 128  => -128;

其中1111 1111轉換爲十進制整數:

    按位取反:00000000  => 加1:00000001 => 1    => -1;

 

綜上所述:

    對於單個字節的二進制來說,所能表示的十進制整數範圍是:-128~ 127.

                                                         -2^7 ~ 2^7-1.

2.5 整數類型

   在Java語言中用於描述整數的類型有:byte/short/int/long,推薦使用int類型。

   其中byte類型在內存空間佔1個字節的大小,表示範圍是:-128 ~127(-2^7 ~ 2^7-1)

   其中short類型在內存空間佔2個字節的大小,表示範圍是:-2^15 ~2^15-1。

                                                      (-32768 ~ 32767)。

   其中int類型在內存空間佔4個字節的大小,表示範圍是:-2^31 ~2^31-1.

                                                      (正負二十一億之間)

   其中long類型在內存空間佔8個字節的大小,表示範圍是:-2^63 ~2^63-1.

                                                      (比int類型範圍還大)

   在程序中直接寫出的整數數值叫做 直接量/常量/字面值,默認爲int類型,如:666,若希望表示long類型的直接量,則需要在直接量的後面加上L或者l,推薦使用L。

 

擴展:

   若希望表示比long類型範圍還大的整數,則藉助java.math.BigInteger類。

2.6 浮點類型

   在Java語言中用於描述小數數據的類型有:float/double,推薦使用double類型。

   其中float類型在內存空間中佔4個字節的大小,叫做單精度浮點數。

   其中double類型在內存空間中佔8個字節的大小,叫做雙精度浮點數。

   在程序中直接寫入的小數數據叫做直接量/常量/字面值,默認爲double類型,若希望表示float類型的直接量,則需要在直接量的後面增加F或者f。

 

Floatdouble擴展:

   float類型和double類型是不能實現精確計算的,爲了得到精確的結果需要藉助java.math.BigDecimal類加以描述。

   有餘力的同學課下可以查詢float和double存儲結構。

http://blog.csdn.net/zq602316498/article/details/41148063

float:4字節 32位

       1bit(符號位)8bits(指數位) 23bits(尾數位)     a = r^3其中r爲底數 3是指數 

double:8字節 64位
        1bit(符號位)11bits(指數位) 52bits(尾數位)

 

2.7 布爾類型

  在Java語言中用於描述真假信息的類型有:boolean,該類型的數值:true 和 false.

  由於布爾類型只有兩個數值因此使用一個二進位制就足夠描述,但通常認爲是1個字節

2.8 字符類型(熟悉)

  在Java語言中用於描述字符信息的類型有:char,在內存空間中佔2個字節的大小,通常用於描述單個字符,如:'a' '1''中'等。

  在現實生活中使用更多的是多個字符組成的字符串,使用String類型加以描述,並且使用雙引號括起來,如:"xiaomage"。

  要求大家記住的ASCII數值有:

       'A' - 65   'a' - 97  '0' - 48   空格 - 32   換行 - 10

  要求大家記住的轉義字符有:

       \" - "   \' - '  \\  - \   \t - tab鍵  \n - 換行符

 

 

 

 

 

 

 

 

 

3.基本數據類型之間的轉換(熟悉)

複習:

   Java語言基本數據類型有:byte、short、int、long、float、double、charboolean    byte b = 10;  - 10叫直接量,默認是int類型

 

   基本數據類型之間的轉換分爲:自動類型轉換 和 強制類型轉換。

   其中自動類型轉換主要指:小範圍向大範圍之間的轉換。

   其中強制類型轉換主要指:大範圍向小範圍之間的轉換。

       語法格式:目標類型 變量名 = (目標類型)源類型變量名;

              如:byteb1 = (byte)s1;

 

經驗:

   當程序中出現大範圍向小範圍轉換的代碼時編譯報錯,若希望編譯能夠通過則需要按照上述方式進行強轉,但強轉帶來的結果會改變原始數據,因此能不用則不用。

double sum = 0.0;    int i =1;//sum如果聲明爲double則報錯損失精度

              for(  i  =  1;  i  <=  num;  i++  ){

              System.out.println("數字:"+i);

              sum = sum + 1.0/i;(推薦) //sum =  sum +((double)1)/i;;//也可以

              }

4.運算符(重點)

4.1 算數運算符

  + 表示加法運算符   - 表示減法運算符    * 表示乘法運算符    /  表示除法運算符

  % 表示取模/取餘運算符

 

注意事項:

  (1)兩個整數相除時結果取整數部分,丟棄小數部分。

  (2)若希望結果是浮點數據,則需要進行處理,方式如下:

      a.將其中一個操作數強轉爲double類型,則結果不會丟棄小數部分。

      b.將其中一個操作數乘以1.0提升爲double類型,則結果不會丟失小數部分(推薦)

  (3)0不能做除數,0.0可以做除數,但結果是無窮大,因此以後編程不要使用0和0.0

     作爲除數。

 

經驗:

  運算符+ 既可以當做算數運算符處理,也可以當做字符串連接符處理,區分方式如下:

     a.當運算符+兩側的操作數都不是字符串時,則看做算數運算符處理。

     b.當運算符+兩側的操作數中只要有一個是字符串時,則看做字符串連接符處理。

       System.out.println(100+200+"300");//輸出300300

       System.out.println("300"+100+200);//輸出300200100

4.2 比較/關係運算符

   > 表示是否大於  >= 表示是否大於等於  < 表示是否小於  <= 表示是否小於等於

   == 表示是否等於  != 表示是否不等於

 

   關係運算符參與的表達式結果爲boolean類型,只有兩種:true 和 false

4.3 自增減運算符

   + 表示加法運算符   ++ 表示自增運算符,也就是讓變量自己的數值加1.

   - 表示減法運算符   -- 表示自減運算符,也就是讓變量自己的數值減1.

 

經驗:

   在以後的編程中儘量單獨使用自增減運算符,不要和其他運算符搭配使用,以避免錯誤的發生。如:ia++;

4.4 邏輯運算符

   && - 表示邏輯與運算符,相當於"並且",同真爲真,一假爲假。

   || - 表示邏輯或運算符,相當於"或者",一真爲真,同假爲假。

   !  - 表示邏輯非運算符,相當於"取反",真爲假,假爲真。

  

短路特性:

    對於邏輯與運算符來說,若第一個條件爲假則整個表達式的條件一定爲假,此時第二個條件可以跳過不執行。

    對於邏輯或運算符來說,若第一個條件爲真則整個表達式的條件一定爲真,此時第二個條件可以跳過不執行。 

4.5 條件/三目運算符

   ?: - 條件/三目運算符

   條件表達式? 表達式1: 表達式2;

       - 判斷條件條件表達式是否成立

            => 若成立,則執行表達式1;

            => 若不成立,則執行表達式2;

4.6 賦值運算符

 (1)簡單賦值

    =  表示將=右邊的數據賦值給=左邊的變量,去覆蓋該變量原來的數值。

如:

    ia = 10;

    ia = ib = ic = 20;   => ia、ib、ic最終的結果都是20.

 

筆試題:

   分析以下四種形式的區別?

       ia = 10; - 將數據10賦值給ia,覆蓋ia原來的數值。

       10 = ia; - 編譯報錯

       ia == 10; - 判斷ia是否等於10

       10 == ia; - 判斷10是否等於ia

 

(2)複合賦值   

   += -=  *=  /=  ......

如:

   ia = ia + 10;(推薦,可讀性更強)  

   => ia += 10;   

 

筆試題:

   分析以下兩種形式的區別?

   byte b1 = 5; b1 += 2;     //ok

   byte b1 = 5; b1 = b1 + 2; //error

解析:

   b1 += 2 真正等價的是:b1 =(byte)(b1 + 2);  

 

4.7 移位運算符(瞭解)

   <<  表示左移運算符,也就是按照二進制位向左移動,右邊添加0.

   >>  表示右移運算符,也就是按照二進制位向右移動,左邊添加符號位.

   >>> 表示無符號右移運算符,也就是按照二進制位向右移動,左邊添加0.

 

4.8 位運算符(瞭解)

   &  表示按位與運算符,同1爲1,一0爲0.(1看做真,0看做假)

   |   表示按位或運算符,同0爲0,一1爲1.

   ~   表示按位取反運算符,1爲0,0爲1.

   ^   表示按位異或運算符,相同爲0,不同爲1.

 

4.9 運算符的優先級

   (1)()的優先級極高。

   (2) =的優先級極低。

   (3) * / % 的優先級高於 + -,同級的運算符(從左到右)哪個在前先算哪個。

 

 

第四天  程序結構

三種程序結構:順序、分支、循環結構

 

1.分支結構

1.1基本概念

   當需要進行條件的判斷和選擇時,需要使用分支結構來進行處理。

1.2 if分支結構

(1)語法格式

   if(條件表達式){

      語句塊1;

   }  

   語句塊2;

 

(2)執行流程

   判斷條件表達式是否成立

       => 若成立,則執行語句塊1;  => 執行語句塊2;

       => 若不成立,則執行語句塊2;

1.2.1if-else分支結構

(1)語法格式

   if(條件表達式){

      語句塊1;

   }

   else{

      語句塊2;

   }

   語句塊3;

 

(2)執行流程

   判斷條件表達式是否成立

       => 若成立,則執行語句塊1;  => 執行語句塊3;

       => 若不成立,則執行語句塊2;=> 執行語句塊3;

1.2.2if-else if-else分支結構

(1)語法格式

   if(條件表達式1){

      語句塊1;

   }

   else if(條件表達式2){

      語句塊2;

   }

   ... ...

   else{

      語句塊3;

   }

   語句塊4;

 

(2)執行流程

   判斷條件表達式1是否成立

       => 若成立,則執行語句塊1=> 執行語句塊4;

       => 若不成立,則判斷條件表達式2是否成立

               => 若成立,則執行語句塊2 => 執行語句塊4;

               => 若不成立,則執行語句塊3 => 執行語句塊4;

1.3 switch-case結構(熟悉)

(1)語法結構

   switch(變量/表達式){// switch(byteshortcharint、枚舉、String )

 

       case 字面值1: 語句塊1; break;

       case 字面值2: 語句塊2; break;

       ... ...

       default:語句塊3; 

   }

   語句塊4;

若不加break,會從滿足case條件的語句一直執行,直到default語句執行完,退出循環。

(2)執行流程

   計算變量/表達式的結果

      => 判斷結果是否等於字面值1 

         => 若成立,則執行語句塊1=> 執行break=> 執行語句塊4;

         => 若不成立,則判斷是否等於字面值2

               => 若成立,則執行語句塊2 => 執行break=> 執行語句塊4;

               => 若不成立,則執行語句塊3 => 執行語句塊4;

 

(3)注意事項

   switch()中支持的類型:byteshortcharint,從jdk1.5開始支持枚舉類型,從jdk1.7開始支持String類型。

 

2.循環結構(重中之重)

2.1 基本概念

   當需要重複做一件事時,可以使用循環結構來解決。

2.2 for循環 空語句

(1)語法結構

   for(表達式1; 條件表達式2; 表達式3){

      語句塊1;(循環體)

   }  

   語句塊2;

 

(2)執行流程

   執行表達式1=> 判斷條件表達式2是否成立

       => 若成立,則執行語句塊1  => 執行表達式3=> 判斷條件表達式2是否成立

       => 若不成立,則執行語句塊2

(3)for(;;)格式:1.必須要有兩個分號”;”2.裏面的條件表達式能計算出正確結果就行

(4)空語句for(;;);等同於for(;;){;}括號裏面只有“;”的語句,啥也不執行。

2.3 break和continue關鍵字

實例:TestForBreakContinue.java 

break關鍵字用在循環中表示跳出當前循環,用在switch-case結構表示跳出當前結構。

continue關鍵字只能用在循環中,表示結束本次循環繼續下一次循環(熟悉)。

break嵌套:break用於退出所在循環體。如果退出外層循環體,需要用標號的方式。

  

2.4 特殊的循環

  for(;;) - 該循環中沒有明確的循環條件,這樣的循環叫做無限循環,俗稱"死循環"。

  該循環通常情況下與break關鍵字搭配使用

              for(;;){

                     if(i>3) break;

                     i++;                            

              }//i>4的時候跳出循環

2.5 for循環嵌套

1)語法格式

   for(表達式1; 條件表達式2; 表達式3){

      for(表達式4; 條件表達式5; 表達式6){

          語句塊7(循環體);

      }

   }

 

(2)執行流程  

   執行表達式1=> 判斷條件表達式2是否成立

      => 若成立,則執行表達式4=> 判斷條件表達式5是否成立

            => 若成立,則執行語句塊7 => 執行表達式6=> 判斷條件表達式5是否成立

            => 若不成立,則執行表達式3=> 判斷條件表達式2是否成立

     => 若不成立,則結束整個循環

2.6 while循環

(1)語法格式

   while(條件表達式){

      循環體;

   }

   語句塊;

 

(2)執行流程

   判斷條件表達式是否成立

      => 若成立,則執行循環體=> 判斷條件表達式是否成立

      => 若不成立,則執行語句塊;

 

(3)注意事項

   a.while循環和for循環是完全可以互換的。

   b.while循環通常使用在明確循環條件但不明確循環次數的場合中。

     for循環通常使用在明確循環次數/範圍的場合中。

   c.while(true)等價於for(;;),都表示無限循環,俗稱"死循環"。

 

(4)while(boolean)格式:1.()內可以使TRUE或者FALSE  2.可以是條件表達式,但是表達式結果只能是布爾類型。

2.7 do-while循環(熟悉)

(1)語法格式

   do{

      循環體;

   }while(條件表達式);//注意分號

   語句塊;

 

(2)執行流程

   執行循環體=> 判斷條件表達式是否成立

       => 若成立,則執行循環體=> 判斷條件表達式是否成立

       => 若不成立,則執行語句塊

 

(3)注意事項

   a.do-while循環通常使用在至少執行一次循環體的場合中。

   b.do-while循環的條件表達式後面有分號,其他循環沒有。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第五天  數組

1.一維數組

1.1 基本概念

   變量本質上就是一塊內存空間,用於記錄單個數據,而且內容可以改變。

   一維數組本質上就是一段連續的內存空間,用於記錄多個數據類型相同的數據,內容可以發生改變,換句話說,一維數組就是一個容器。

   數組名 - 主要指數組的名稱,用於記錄該連續內存空間的首地址信息。

   數組元素 - 主要指存放在數組中的數據內容。

   數組長度 - 主要指數組中存放的元素個數,通常使用 數組名.length來獲取。

   數組下標 - 主要指數組中元素的編號,從0開始一直到 數組名.length-1。

 

1.2 數組的聲明

(1)數組聲明的語法格式

   數據類型[] 數組名稱 = new 數據類型[數組的長度]; - 動態方式

如:

   int[] arr = new int[5]; - 聲明一個長度爲5,元素類型爲int的一維數組

   int num = 5;            - 聲明一個初始值爲5的變量

  

   int arr[] = new int[5]; - 不推薦使用該方式

 

(2)注意事項

   a.只有數組在聲明的時候,[]中的數字代表數組的長度,否則一律代表下標。

   b.當創建數組沒有指定初始值時,採用默認初始化(參考ppt)。

 

(3)數組元素的初始化

   數據類型[] 數組名稱 = {初始值1,初始值2, ...}; - 靜態方式

如:

   int[] arr = {10, 20, 30, 40, 50}; - 聲明一個長度爲5元素類型爲int的數組

   arr[0] = 10;

   arr[1] = 20;

   arr[2] = 30;

   arr[3] = 40;

   arr[4] = 50;

注意:基本類型的數組(數據元素爲基本類型)創建後。元素類型爲:BYTESHORTCHARINTLONG0FLOATDOUBLE0.0BOOLEANFalse

1.3 數組的聲明size()  length length()方法:

1.length屬性是針對Java中的數組來說的,要求數組的長度可以用其length屬性;

2.length()方法是針對字符串來說的,要求一個字符串的長度就要用到它的length()方法;

3.java中的size()方法是針對泛型集合說的,如果想看這個泛型有多少個元素,就調用此方法來查看!

 

1.二維數組(熟悉)

1.1 基本概念

   一維數組本質上就是一段連續的內存空間,用於記錄多個類型相同的數據內容。

   二維數組本質上就是由一維數組組成的數組,也就是說二維數組中的每個元素都是一個一維數組。

 

1.2 二維數組的聲明

(1)語法格式

   數據類型[][] 數組名稱 = new 數據類型[行數][列數];

如:

   int[][] arr = new int[2][5]; - 聲明一個具有2行5列存放int類型元素的二維數組

   其中行下標的範圍是:0 ~1;

   其中列下標的範圍是:0 ~4;

 

   arr代表什麼?  arr[0]代表什麼? arr[0][0]代表什麼?

解析:

   arr代表二維數組的名稱,用於記錄該二維數組的首地址。

   arr[0]代表二維數組的第一行,也就是一個一維數組。

   arr[0][0]代表二維數組中的第一行第一列,也就是第一個元素值。

   int[][]a= new int a[i][j];i代表行,j代表列

   arr.length=i;代表二維數組的長度,也就是二維數組的行數。

   arr[0].length=j;代表第一行的列數,也就是一維數組的長度。

 

(2)二維數組的初始化

   數據類型[][] 數組名稱 = {{元素值1,元素值2,...},{元素值3,元素值4,...},...};

如:

   int[][] arr = {{1,2,3},{4,5,6}}; - 聲明一個2行3列的二維數組

   其中行下標就是:0 ~ 1;

   其中列下標就是:0 ~ 2;

 

 

 

 

 

 

 

 

 

 

第六天  類和對象

1.對象概念

1.1 什麼是對象?

   萬物皆對象。

 

1.2 什麼是面向對象?

   面向對象就是指以特徵和行爲的觀點去分析現實世界中事物的方式。

 

1.3 什麼是面向對象編程?

   面向對象編程就是指先用面向對象的觀點進行分析,再採用一門面向對象的編程語言進行翻譯/表達的過程。

   其中C語言是一門面向過程的編程語言。

   其中C++語言是一門既面向過程又面向對象的編程語言。

   其中Java語言是一門純面向對象的編程語言。

 

1.4 爲什麼需要面向對象編程?

   面向對象編程是軟件產業化發展的需求。

 

2.5 如何學好面向對象編程?

   深刻理解面向對象的三大特徵:封裝、繼承、多態。

 

2. 類

2.1類的基本概念

   類就是"分類"的概念,也就是對同一類事物的統稱,描述該類事物共同的特徵和行爲

   類是抽象的概念,是創建對象的模板,而對象是客觀存在的實體,佔用一塊內存空間

   類是一種引用數據類型,包含用於描述特徵的成員變量,以及用於描述行爲的成員方法(JAVA中可以忘記函數概念)。 

 

2.2 類的定義

(1)類定義的語法格式

   class 類名{

      類體;

   }

 

類定義的一般形式如下

[類定義修飾符] class  <類名>   

{   //類體

       [成員變量聲明]

 [構造函數]

      [成員方法]

}

 

注意:

   通常情況下,當類名由多個單詞組成時,每個單詞的首字母都要大寫。駝峯命名法。

 

2.3 成員變量 以及初始化

 (1)成員變量聲明的語法格式

   class 類名{

       數據類型 成員變量名 = 初始值; - 其中=初始值是可以省略的

   }

如:

  class Person{

      String name;    //用於描述姓名的成員變量

      int ageNum;        //用於描述年齡的成員變量

      double weight;  //用於描述體重的成員變量

  }  

 

注意:

  通常情況下,當成員變量名由多個單詞組成時,要求從第二個單詞起首字母大寫

 

2.X補充:局部變量 成員變量區別

   局部變量 - 主要指聲明在方法體中的變量,作用域從聲明開始一直到方法體結束。

   成員變量 - 主要指聲明在類體中的變量,作用域從聲明開始一直到類體結束。   

成員變量有兩種:
    A:一種就是類變量或靜態變量  這類變量前面加static關鍵字修飾
        這類變量一旦賦值它的值就在你new出來的任何一個實例中具有相同的值
   B:另一種叫做實例變量  前面不加static關鍵字修飾,每一個new出來的新實例都

可以對他賦予自己需要的值

 

成員變量和局部變量在內存中的分配

  對於成員變量和局部變量:成員變量就是方法外部,類的內部定義的變量;局部變量就是方法或語句塊內部定義的變量。局部變量必須初始化。 形式參數是局部變量,局部變量的數據存在於棧內存中。棧內存中的局部變量隨着方法的消失而消失。 成員變量存儲在堆中的對象裏面,由垃圾回收器負責回收。   如以下代碼:

 

(2)成員變量默認初始化

 

 

2.4 對象的創建

(1)語法格式

   new 類名();

如:

   new Person();  - 表示新建一個Person類型的對象,叫做匿(無)名對象;

 

(2)使用方式

   使用new運算創建對象的過程叫做類的實例化,也叫作構造對象,當創建對象後需要在堆區申請一塊內存空間,用於記錄該對象獨有的成員變量信息。

 

2.5 引用(引用數據類型聲明的變量名)

(1)基本概念

   引用:使用引用數據類型聲明的變量名叫做引用變量,簡稱爲"引用"。用於記錄新建對象在堆區中的內存地址信息,便於再次訪問該對象。

  

 

(2)語法格式

   類名 引用變量名;

如:

   Person p;

   Person p = new Person();  

 

注意:

   當需要訪問成員變量時,使用 引用.成員變量名 的方式進行。

   p.name = "zhangfei";

   p.age = 30;  

 

2.6成員方法 (格式返回值調用)

2.6.1語法格式

  class 類名{

      返回值類型 成員方法名(形參列表){

          方法體;

      }

  }

如:

  class Person{

     void show(){

         System.out.println("沒事出來秀一下!");

     }

  }

 

 

2.6.2成員方法的詳解

(1)返回值類型

   返回值就是指從方法體內向方法體外傳遞的數據內容。

   返回值類型就是指返回值的數據類型。

       當返回的數據內容爲66時,則返回值類型寫爲:int;

       當返回的數據內容爲3.14時,則返回值類型寫爲:double;

       當返回的數據內容爲"hello"時,則返回值類型寫爲:String;

   在方法體中使用return關鍵字返回數據並結束方法,如:return 66; return num。

   return關鍵字後面可以跟:字面值、變量、表達式以及方法的調用等

   當方法體中沒有可以返回的數據內容時,則返回值類型寫:void即可。

 

(2)形參列表

   形式參數就是指從方法體外向方法體內傳入的數據內容,語法格式:數據類型 形參名

   形參列表就是形參的集合,格式爲:數據類型 變量名1,數據類型 變量名2,...

       當傳入的數據內容爲66時,則形參列表寫爲:int i;

       當傳入的數據內容爲3.14時,則形參列表寫爲:double d;

       當傳入的數據內容爲"hello"時,則形參列表寫爲:String s;

       當傳入的數據內容爲66和"hello"時,則形參列表寫爲:inti, String s;

   當不需要傳遞任何數據到方法體內時,則形參列表位置啥也不寫即可。

 

(3)方法體

   方法體就是用於描述方法功能的語句塊,通常用於多條語句的打包,從而提高代碼的複用性和可維護性。

 

2.6.3方法的調用

(1)語法格式

   引用/對象.成員方法名(實參列表);

如:

   p.show();

 

(2)使用方式

   實參列表主要用於進行形參列表的初始化工作,因此參數的個數、類型以及順序等都必須與形參列表保持一致。

   實參可以傳遞字面值、變量、表達式、方法的調用等。

2.7構造方法

 

1.1 構造方法(重中之重)

(1)語法格式

   class 類名{

      類名(形參列表){

         構造方法體;

      }

   }

如:

   class Person{

      Person(){

         ...

      }

   }

 

(2)注意事項

   a.構造方法的方法名稱與類名完全相同。

   b.構造方法是沒有返回值類型的,連void都沒有。

   c.當new一個新對象時,會自動調用構造方法來進行該對象成員變量的初始化工作。

d.構造方法只能被publicprivate等訪問修飾符修飾

   e.構造方法只能在new的時候被調用。其他情況不能用。參考下圖

 

 

(3)默認構造方法

   當一個類中沒有自定義任何形式的構造方法時,編譯器會自動添加一個無參的空構造方法,該構造方法叫做默認/缺省構造方法,如:Person(){}

   當類中出現了自定義構造方法後,則編譯器不再提供任何版本的構造方法。

(4)構造方法重載

 

(5)建議:

1、建議自定義無參數構造方法,不要依賴編譯器,防止出現錯誤。

2、當類中無成員變兩個或者變量都爲常量(final)時,建議不提供任何版本的構造。

3、當類中有非常量成員變量時。建議提供兩個構造方法:一個無參數、一個全參數。

 

2.8 方法的重載(Overload)

(1)基本概念

   在同一個類中,方法名相同參數列表不同之間的方法構成重載關係。

原理:編譯器根據參數列表不同,底層生成綁定到不同名稱的方法。

 

(2)重載的主要形式

   方法重載的形式有:參數的個數不同、參數的類型不同以及參數的順序不同。

   與參數的變量名和返回值類型無關,但建議返回值類型最好相同。

 

   判斷方法能否構成重載的依據:調用該方法時能否區分即可。

   java.io.PrintStream類中提供了大量的重載方法,print()和println()方法。

 

 

(3)重載的主要作用

   重載的作用在於:調用者只需要記住一個方法名就可以調用不同版本的方法,從而達到不同的效果,具體調用的版本由實際參數來決定。

3. This關鍵字(指針)

 

3.1調用對象參數對象

如:

   class A{}

   class B{

      void show(A a){ ... }

   }

  

   A a = new A();

   B b = new B();

   b.show(a);

   調用對象:其中對象b是用於調用show()方法的,因此叫做調用對象

   參數對象:其中對象a是用於作爲實參傳遞給show()方法的,因此叫做參數對象

3.2 基本概念(當前對象)

   對於構造方法來說,this關鍵字代表當前正在構造的對象。

   對於成員方法來說,this關鍵字代表當前正在調用的對象。

  

原理解析:

   當使用不同的對象調用同一個方法時,那麼方法體中的this代表的對象也就不同,當訪問成員變量時相當於使用this.的(我的)方式訪問,因此最終的結果也就不同。

 

3.3 使用方式(就近原則)

  (1)當形參變量名和成員變量名相同時,在方法體中(就近原則)會優先選擇形參變量名,若希望使用成員變量名,則需要在變量名的前面加上this.明確要求使用成員變量(掌握)。

  (2)使用this.的方式調用成員方法(瞭解)。

  (3)在構造方法的第一行使用this(實參)的方式調用本類中的其他構造方法(瞭解)。

3.4 This構造方法

下圖:this("name",  67, true);this(); 只能同時出現一個。否則構造器陷入死循環編譯報錯。

 

 

3.5 空指針類型異常

 

4. 方法的傳參和參數數目不確定

1.1 方法的傳參過程(原理、儘量理解)

 

publicint max(int a,int b){......}

int a = 5; int b = 6;

int res = m.max(a,b);

 

  (1)main()方法是程序的入口,爲main()方法分配變量的內存空間並初始化。

  (2)調用max()方法,爲max()方法的形參變量分配內存空間。

  (3)使用實際參數爲形式參數進行初始化,也就是將實參的數值賦值給形參的內存空間

  (4)執行max()方法的方法體,執行完畢後釋放形參變量的內存空間

  (5)main()方法得到max()方法的返回值並繼續向下執行。

 

參數數目變化:

返回值  方法名(數據類型…  變量名)    eg: int num(int… a) 

其中變量名a是數組通過下標訪問元素

 

public static int num(int... a) {

       intsum = 0;

       for(int i = 0; i < a.length; i++) {

              sum+= a[i];

       }

       returnsum;

}

 

要求大家重點掌握的內容:

  a.當使用基本數據類型作爲形參時,在方法體中改變形參變量的數值不會影響到實參;

  b.當使用引用數據類型作爲形參時,在方法體中改變形參變量指向的數值時,則

影響到實參指向的數值,因爲形參和實參指向同一塊區域。

 

  c.當使用引用數據類型作爲形參時,在方法體中改變形參變量的指向後在更改指向的

內容,則不會對實參指向的內容產生影響,因爲形參和實參指向不同的區域。

 

5. 遞歸和遞推

(1)基本概念

   遞歸就是指在方法體中調用該方法自身的形式。

(2)使用原則

   a.尋找遞歸的規律,並指定退出條件。

   b.遞歸使得問題簡單化,而不是複雜化。

   c.遞歸可能會影響程序的執行性能,此時需要使用遞推替代之。

斐波那契數列遞歸:

 

斐波那契數列遞推:

 

 

 

 

 

 

 

 

 

第七、八天  封裝、繼承、重寫、static、 super、this、單例、構造塊、靜態語句塊

1. 封裝

1.1 基本概念

   當一個類中沒有做任何處理時,則測試類中可以任意訪問該類中的成員,此時就有可能帶來一些合法但不合理的數值,

   爲了避免該問題的發生就需要對類中的成員進行保護處理,而這種處理方式就叫做類的封裝。

   換句話說,封裝就是一種爲了保證成員變量值合理的機制。

 

1.2 封裝的流程

  (1)使用private關鍵字修飾成員變量,表示私有化。

  (2)提供公有的get成員變量/set成員變量方法供外界使用,在方法體中進行合理性判斷

  (3)在構造方法體中調用set成員變量的方法進行合理性判斷。

如下圖:

 

2.static關鍵字(重點)

1.1 基本概念

 通常情況下,類中的成員變量都隸屬於對象層級,也就是每創建一個對象都會擁有獨立的一份,當所有對象共享同一份數據時並單獨記錄時會導致內存空間的浪費,此時可以使用static關鍵字修飾該成員變量表達靜態的概念,當使用static關鍵字修飾之後該成員變量就從對象層級提升到類層級,被所有對象共享與對象是否創建無關。

訪問方式:推薦類名.的,不建議使用對象/引用.的方式訪問。static修飾的加載到方法區

 

 

1.2 使用方式

   (1)在非靜態的成員方法中既可以訪問非靜態的成員,也可以訪問靜態的成員;

      (成員:成員變量 + 成員方法   類層級的內容被所有對象共享) 下圖show()方法。

   (2)在靜態的成員方法只能訪問靜態的成員,不能訪問非靜態的成員;下圖test()方法。

      (成員:成員變量 + 成員方法   調用靜態方法時可能還沒有創建任何的對象)

      (靜態的成員方法中是沒有this關鍵字的)

   (3)只有隸屬於類層級被所有對象共享的內容才能使用static關鍵字修飾;

       (不能濫用static)

示例代碼:

D:\兄弟連視頻\day09\code\ TestStatic.java

 

3. 構造塊和靜態語句塊(熟悉)

  a. 構造塊就是指在類中直接使用{}括起來的語句塊;

  b. 靜態語句塊就是指在類中直接使用static{}括起來的語句塊;

c.抽象類裏面可以用構造塊{}和static{}(JDK1.7語法不報錯 但是沒意義)

d.接口裏面不可以用構造塊和{}static{}(JDK1.7語法上報錯)

d. static{;} 靜態語句塊 前面不能加任何修飾符。

 

執行流程:   靜態語句塊  => 構造塊  => 構造方法體;

 

4. 單例設計模式

(1)基本概念

   在某些特殊場合中,當一個類對外提供一個對象且只能提供一個對象時,這樣的類叫做單例類,而編寫單例類的設計形式和編程套路就叫做單例設計模式。實例:任務管理器只能開一個。

 

(2)實現流程

   a.私有化構造方法,使用private關鍵字修飾;

   b.提供本類的引用指向本類的對象,並使用privatestatic共同修飾;

   c.提供公有的get成員方法負責將對象返回出去,並使用static修飾;

 

(3)實現方式

   單例設計模式的實現方式有兩種:餓漢式 和 懶漢式,以後的開發中推薦餓漢式;

示例代碼:

D:\兄弟連視頻\day09\code\ Singleton.java和TestSingleton.java

 

 

 

 

 

 

 

5. 繼承

5.1繼承的由來和概念

   示例代碼:

D:\兄弟連視頻\day09\code\ Person.java和Student.java

當多個類中有相同的特徵和行爲時,就可以將相同的內容提取出來組成一個新的類,在編寫這多個類時只需要繼承這個新的類就可以複用相同的特徵和行爲,從而提高代碼的複用性和可維護性

   換句話說,繼承就是一種實現代碼複用和提高可維護性的機制。

   在Java語言中使用extends(子類父類繼承)( implements(實現接口) )關鍵字來表達繼承關係。

如:

   class Student extends Person{ ... ...} 

   其中Person類叫做超類/父類/基類。

   其中Student類叫做派生類/子類。

 

5.2 注意事項

  (1)子類可以繼承父類中的成員方法以及成員變量

     (私有的成員變量也可以繼承但不能直接訪問)

     子類不能繼承父類的內容有:構造方法和私有成員方法

父類中的構造方法是不能繼承的,但是在實例化子類的時候會調用父類的構造方法。

http://blog.csdn.net/wangyl_gain/article/details/49366505  

http://www.cnblogs.com/H-BolinBlog/p/5331195.html

  (2)無論使用何種形式構造子類的對象,都會默認調用父類的無參構造方法來構造

     子類對象中包含的父類對象,也就是對父類中成員變量進行初始化,相當於

     super()調用的效果。

  (3)Java語言只支持單繼承不支持多繼承,也就是說一個子類只能有一個父類,

     但一個父類可以有多個子類。

  (4)不能濫用繼承,必須滿足邏輯關係:子類 is a父類。比如:狗是動物。

5.3 extends關鍵字

 

5.4繼承中的構造方法

 

6. super、this關鍵字(熟悉)

6.1基本概念

   this關鍵字 可以代表本類的對象;

   super關鍵字 可以代表父類的對象;

 

6.2使用方式

   使用this.的方式可以訪問本類的成員變量和成員方法;

   使用super.的方式可以訪問父類的成員變量和成員方法;

 

   使用this(實參)的方式可以調用本類中的其他構造方法;

   使用super(實參)的方式可以調用父類中的構造方法;

 

要求大家掌握的內容:

   a.使用this.的方式可以用於區分同名的成員變量和局部變量;

   b.使用super.的方式可以調用父類中被覆蓋的方法;

   c.使用super(實參)的方式可以調用父類的構造方法;

 

7.方法的重寫(Override重點)

示例代碼:

D:\兄弟連視頻\day09\code\ Student.java和Person.java的show()方法

 (1)基本概念

   當子類繼承父類中的方法不足以滿足子類的需求時,就可以在子類中重新寫一個和父類中方法一模一樣的方法,這種形式叫做方法的重寫/覆蓋。

(2)方法重寫的原則(拷貝方法名稱列表就行了)

   a.要求方法名相同、參數列表相同、返回值類型相同,從jdk1.5開始允許返回子類.

   b.訪問權限不能變小,可以相同或變大。  

   c.不能拋出更大的異常(異常機制)。

(3)Java中靜態屬性和方法可以被繼承,不可以被重寫(Override)而是被隱藏。靜態方法推薦用 (類名.方法名)的方式來調用。(不推薦 對象.方法名的方式)

實例:

 

 

第九天 包、訪問控制符、final、 對象創建的過程

1. 訪問控制

1.1 包的定義

   package 包名;   - 表示指定單層目錄 

   package 包名1.包名2.包名3....;  - 表示指定多層目錄

        - 用於管理文件方便,更重要的是可以避免同名文件導致的錯誤發生。

命名格式:org.apache.(公司名稱)commons(項目名).lang(模塊).StringUtil(類名)

1.2 常用的訪問控制符(權限修飾符)

   public - 表示公有的/公開的

   protected - 表示保護的

   默認訪問符 - 表示默認的

   private - 表示私有的  

 

1.3 訪問控制符的權限信息

   訪問控制符  訪問控制權限  本類   本包中的類   子類   其他類

-------------------------------------------------------------------

     public                公開的       ok           ok           ok      ok

     protected         保護的       ok           ok           ok      no

     默認控制符         默認的       ok           ok           no      no

     private              私有的       ok            no          no      no

要求大家掌握的內容:

    a.public關鍵字修飾的內容表示可以在任意位置訪問。

    b.private關鍵字修飾的內容表示只能在本類的內部訪問。

    c.通常情況下,成員變量都是用private修飾,成員方法都使用public修飾。

d. 訪問控制符不能修飾static{;}靜態語句塊

1.4類的修飾  修飾詞順序

修飾詞順序:[訪問權限] [abstract] [static] [final] [transient][volatile] [synchronized] [native] [strictfp]

 

2.final關鍵字(重點)

2.1 基本概念

   final本意爲“最終的,不可更改的”,修飾類、成員方法以及成員變量。

 

2.2 使用方式:不能重寫、不能繼承、必須初始化

   final關鍵字修飾類,表示該類是最終的,體現在該類不能被繼承。

        - 防止濫用繼承,如:java.lang.System類/String類等  

   final關鍵字修飾成員方法,表示該方法是最終的,體現在該方法不能被重寫。

        - 防止不經意間造成的方法重寫,

          如:java.text.SimpleDateFormat類中的format()方法

   final關鍵字修飾成員變量,表示該成員變量必須初始化而且不能更改。

        - 防止不經意間造成的修改,如:java.lang.Thread類中的MAX_PRIORITY。

 

補充:

   在Java語言中很少單獨使用static和final關鍵字修飾成員變量,通常都是使用public static final共同修飾成員變量表示常量的概念。

   通常的命名規範是:所有字母都大寫,不同單詞之間使用下劃線連接。

   如:

      public static final double PI = 3.14;

 

3.對象創建的過程

3.1 單個對象創建的執行過程

示例代碼:

D:\兄弟連視頻\day10\code\ TestObjectCreate.java

   (1)在執行代碼之前需要將類的字節碼信息讀入內存空間中的方法區,叫類的加載。

   (2)main()方法時程序的入口,當執行new TestObjectCreate()時表示在堆區申請空間

   (3)若成員變量沒有指定初始值時,則採用默認初始化方式進行,否則採用指定的

      初始值進行初始化。         

   (4)執行構造塊中的語句,可以對成員變量進行再次修改。

   (5)執行構造方法體中的語句,可以對成員變量進行再次修改。

   (6)此時對象構造完成,繼續執行main()方法中的後續代碼。

 

3.2 子類對象創建的執行過程

示例代碼:

D:\兄弟連視頻\day10\code\ TestSubObject.java  TestSuperObject.java

                          Father.java和sun.java

   (1)先加載父類的字節碼信息,因此先執行父類的靜態語句塊。

   (2)再加載子類的字節碼信息,因此執行子類的靜態語句塊。

   (3)執行父類的構造塊,再執行父類的構造方法體,此時父類的對象構造完成。

   (4)執行子類的構造塊,再執行子類的構造方法體,此時子類的對象構造完成。

   (5)繼續執行main()方法中後續的代碼。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第十、十一天 多態、接口、 內部類  Object類、包裝類

1.多態(重中之重、難點)

1.1 基本概念

   多態就是指同一種事物表現出來的多種形態。

   寵物:狗、貓、鳥、小強、...

   整數:byteb1 = 10;  short s1 = 10; int l1 = 10;

多態:Pet p= new Dog(); Pet p = new Cat();//Cat Dog都是Pet子類 。

父類變量/引用指向子類對象

 

1.2 語法格式

示例代碼:

D:\兄弟連視頻\day10\code\ Person.java  Student.java

 

 父類類型 引用變量名 = new 子類類型();  - 父類的引用指向了子類的對象

如:

   Person p = new Student();

   p.show();

 

解析:

   a.在編譯階段pPerson類型的,只能調用Person類中的show()方法,否則編譯報錯;

   b.在運行階段p真正指向的對象是Student類型的,最終調用Student類的show()方法;

  

 

 

 

1.3 多態的效果

   (1)父類的引用能直接調用父類中的成員方法。

   (2)父類的引用不能直接調用子類中的成員方法。

   (3)父類的引用可以直接調用父子類都有的成員方法。

        對於非靜態的成員方法來說,父類的引用最終調用子類重寫以後的版本;

        對於靜態的成員方法來說,父類的引用最終調用父類自己的方法,與對象無關;

調用靜態方法:建議用    類名.靜態方法

 

1.4 引用數據類型之間的轉換

   (1)當子類類型向父類類型轉換時,只需要發生自動類型轉換即可。

Person ps  =  new Student(“A”,11,1001);//(小到大)自動轉換

   (2)當父類類型向子類類型轉換時,需要進行強制類型轉換,語法格式如下:

        子類類型 引用變量名 = (子類類型)父類類型的引用名;

Person ps = new Person();      Students = (Student) ps;

 

 

 (3)引用類型之間的轉換必鬚髮生在父子類之間,否則編譯報錯;

Person ps = new Person();   String s1 = (String) ps;//報錯

   (4)當父類類型的引用被強制轉換爲子類類型時,編譯階段不會報錯,但若轉換的

      子類類型並不是該引用真正指向的類型,則運行階段產生類型轉換異常。  

類型轉換異常:java.lang.ClassCastException

   (5)爲了避免上述錯誤的發生,建議只要進行強制類型轉換則應該先使用instanceof

      進行判斷只有條件成立時再進行強制類型轉換。

1.5 instanceof運算符 區分==equals

語法格式如下:

         if(父類引用 instanceof 子類類型) - 判斷父類引用是否真正指向該子類類型

        instanceof爲一個操作符 可以理解爲       - 若是則返回true,否則返回false。

實例:class Animal{}; class Dog extends Animal{}; class Cat extendsAnimal{};

Animalanimal = new Dog();

animal  instanceof Animal = = True;

animal  instanceof Dog = = True;

animal  instanceof Cat = = False;

 

區分==和equals:

 https://www.cnblogs.com/dolphin0520/p/3592500.html

http://blog.csdn.net/t12x3456/article/details/7341515

==就是用來比較值是否相等。equals方法是用來比較兩個對象的引用是否相等。

1)對於 = =運算符,如果作用於基本數據類型的變量,則直接比較其存儲的 “值”是否相等;   如果作用於引用類型的變量,則比較的是所指向的對象的地址。

2)對於equals方法,注意:equals方法不能作用於基本數據類型的變量。

 如果沒有對equals方法進行重寫,則比較的是引用類型的變量所指向的對象的地址;    

諸如String、Date等類對equals方法進行了重寫的話,比較的是所指向的對象的內容。

3)對於instanceof: (class A實例)instanceof (class B)  A顯式聲明的類型與右邊類B必須是同種類或者是B的子類才返回TRUE;

1.6實際應用

示例代碼:

D:\兄弟連視頻\day10\code\ Rect.javaShape.java和Circle.java和 TestShape.java

    使用父類的引用作爲方法的形參時,可以屏蔽不同子類的差異性實現通用的編程,換句話說,就是編寫一份通用的代碼可以處理不同的子類對象,而且打印不同的結果。

2.抽象類(重點)

2.1 什麼是抽象方法?

示例代碼:

D:\兄弟連視頻\day10\code\ TestAbstract.java 和 SubTestAbstract.java

   抽象方法就是指不能具體實現的方法,也就是沒有方法體,並使用abstract修飾。

   語法格式:

       訪問控制符abstract 返回值類型 方法名稱(形參列表); 

   如:

       public abstract void cry();

 

2.2 什麼是抽象類?

   抽象類就是使用abstract關鍵字修飾的類,抽象類是不能構造對象的。看下圖

 

2.3 注意事項

   (1)抽象類中可以有成員變量、構造方法以及成員方法。

   (2)抽象類中可以沒有抽象方法,也可以有抽象方法。

   (3)擁有抽象方法的類必須是抽象類。

(4)抽象類中有非抽象的構造方法(構造方法只能被public private等訪問修飾),但是無法實例化(無法new抽象類),是爲了防止生成抽象類後調用抽象方法(所以封死了構造方法)。

 

2.4 實際意義

   抽象類的實際意義不在於實例化對象而在於被繼承,當一個類繼承抽象類就必須要重寫抽象類中的抽象方法,否則該類也得聲明爲抽象類。

   因此抽象類對子類具有強制性和規範性,叫做模板設計模式。

 

經驗分享:

   在以後的開發中推薦使用多態的語法格式在方法體中使用,因爲當使用多態的語法時則調用的所有方法一定是父類中擁有的方法,若希望更換子類對象時,只需要將new後面的類型加以改變而其他代碼立刻生效,因此提高了代碼的可維護性和可擴展性。

   該方式的缺點在於父類的引用不能直接訪問子類的獨有成員變量和成員方法。

推薦:TestAbstract ta = new SubTestAbstract(); ta.show();

3. 接口

3.1 基本概念

   示例代碼:

D:\兄弟連視頻\day11\code\ Money.java和Metal.java和Gold.java和TestInterface.java(public static final double PI = 3.14;)

 

接口就是一種比抽象類還抽象的類,該接口是不能實例化對象,更重要的是,接口中的所有方法都是抽象方法。

   聲明類的關鍵字是class,而聲明接口的關鍵字是interface。

   繼承類的關鍵字是extends,而實現接口的關鍵字是implements。

 

3.2 注意事項

   (1)接口中的所有變量都必須由public static final共同修飾(可省略不報錯但是極不推薦),也就是常量

   (2)接口中的所有方法都必須由public abstract共同修飾(可以省略其中任何一個關鍵字也可以都省略),也就是抽象方法

 

3.3 類和接口之間的關係

   類和類之間的關係     使用extends關鍵字表達繼承的關係     支持單繼承

   類和接口之間的關係   使用implements關鍵字表達實現的關係  支持多實現

   接口和接口之間的關係 使用extends關鍵字表達繼承的關係     通常認爲單繼承

 

3.4 接口和抽象類之間的區別(筆試題)

   (1)聲明抽象類的關鍵字是class,聲明接口的關鍵字是interface。

   (2)繼承抽象類的關鍵字是extends,實現接口的關鍵字是implements。

   (3)繼承抽象類只支持單繼承,而實現接口可以支持多實現。

   (4)抽象類中可以有構造方法,而接口中沒有構造方法。

   (5)抽象類中可以有成員變量,而接口只允許有常量。

   (6)抽象類中可以有成員方法,而接口只允許有抽象方法。

   (7)抽象類中增加方法可以不影響子類,但接口中增加方法一定會影響子類。

4.內部類(瞭解)

4.1 基本概念

   當把一個類的定義寫在另外一個類的類體中時,那麼把寫在內部的類叫做內部類,該內部類所在的類叫外部類。

   類中的內容主要有:成員變量、構造方法、成員方法、構造塊、靜態語句塊、內部類

 

4.2 語法格式

   class 外部類名{

      class 內部類名{

 

      }

   }

 

4.3 主要作用

   當一個類存在的價值僅僅是爲某一個類單獨服務時,就可以將該類定義爲所服務類的內部類,內部類可以直接訪問所在類的私有成員,而不再需要公有的get/set方法等。

內部類一般情況下對外不可見,除了包含它的外部類其他類無法訪問到它。

 

4.4 內部類的主要分類

   普通內部類 - 將一個類的定義直接寫在另外一個類的內部(瞭解)。

   靜態內部類 - 使用static關鍵字修飾的內部類(瞭解)。

              - 普通的外部類是不允許使用static關鍵字修飾。

   局部內部類 - 將一個類的定義直接寫在一個方法體的內部(瞭解)。

              - 該類的作用域僅限於方法體的內部。

   匿名內部類 - 指沒有名字的內部類,用於構造父類/接口類型的對象(重點)。

 

4.5 匿名內部類(重點、難點) 回調模式:略

示例代碼:

D:\兄弟連視頻\day11\code\ SubA.java 和A.java和TestA.java

 

 

(1)語法格式

   父類/接口類型 引用名 =new 父類/接口類型(){

       進行方法的重寫

   };

 (2)經驗分享

   當使用接口類型的引用作爲方法的形參時,實參的傳遞方式有兩種:

a.自定義類實現接口,並創建該類的對象作爲實參傳遞給形參。

b.自定義匿名內部類來構造接口的引用,使用接口引用作爲實參傳遞給形參。

 

A是一個interface

5. Object類(重點)

5.1基本概念

java.lang.Object類是類層次結構的根類,任何類向上查找父類總是可以找到Object

5.2 常用的包

   java.lang包 - 該包是Java核心包,包中的所有類和接口等由JVM自動導入。

               - 如:java.lang.System/String類等

   java.util包 - 該包是Java工具包,包中提供了大量的工具類。

               - 如:java.util.Scanner/Random類等

   java.io包   - 該包是Java中的輸入輸出包,包中提供了大量操作文件的類等。

               - 如:java.io.FileInputStream類等。

   java.net包  - 該包是Java中網絡包,包中提供了大量進行網絡通信的類等。

               - 如:java.net.ServerSocket類等。

 

5.3常用的方法

示例代碼:

D:\兄弟連視頻\day11\code\ Student.java  TestStudent.java

 

   Object() - 使用無參形式構造對象。

   boolean equals(Object obj) - 用於判斷調用對象是否與參數對象obj相等。

       - 該方法默認比較兩個對象的地址信息是否相等,等價於 = = 的效果。

       -重寫equals最好要重寫hashCode()方法

   int hashCode() - 用於返回調用對象的哈希碼值(對象內存地址的編號)。

       - 當兩個對象調用equals()方法相等時,則各自調用該方法的返回值必須相同。

       - 當兩個對象調用equals()方法不相等時,各自調用該方法的返回值可以相同,

         但最好不相同。

       - 要求只要重新equals()方法就一定要重寫hashCode()方法來保證上述約定。

   String toString() - 用於返回調用對象的字符串形式。

       - 通常該方法返回的字符串內容有:包名.類名@哈希碼的十六進制。

       -  System.out.println(裏面內容編譯器自動轉換爲String類型);

6.包裝類和數學處理類

6.1 包裝類的由來

   Java語言是一門純面向對象的編程語言,萬物皆對象。

   Person p = new Person();

   int num = 10;

 

   在某些特殊場合(集合)中要求所有的數據都是對象,那麼對於基本數據類型的變量來說若要使用則需要進行對象化的處理,此時就需要藉助包裝類將變量包裝成對象。

 

6.2 常用的包裝類

   int     =>  java.lang.Integer類(重點)

   double  =>  java.lang.Double類

   byte    =>  java.lang.Byte類

   short   =>  java.lang.Short類

   long    =>  java.lang.Long類

   float   =>  java.lang.Float類

   boolean =>  java.lang.Boolean類

   char    =>  java.lang.Character類

 

6.3 Integer類(重點)

示例代碼:

D:\兄弟連視頻\day11\code\ TestInteger.java

 

(1)基本概念

   java.lang.Integer類是對int類型的包裝類,該類的內部提供了int類型的成員變量。

   該類被final關鍵字。

 

(2)常用的方法  

   該類是Object類的間接子類,並且在該類的內部重寫了equals()、hashCode()、toString()方法

   Integer(int value) - 根據參數指定的整數值構造對象。

   Integer(String s) - 根據參數指定的字符串構造對象。

   int intValue() - 表示以int類型返回該對象的數值。

   static int parseInt(String s) - 用於將參數指定的字符串轉換爲int類型並返回。

 

(3)裝箱和拆箱

   從int類型向Integer類型的轉換過程 叫做裝箱。

   從Integer類型向int類型的轉換過程 叫做拆箱。

   從jdk1.5開始提供了自動裝箱和自動解箱的機制,也就是說不需要方法直接轉換。

 

6.4 BigDecimal類(瞭解)

示例代碼:

D:\兄弟連視頻\day11\code\ TestBigDecimal.java

 

(1)基本概念

   java.math.BigDecimal類用於實現浮點數據的精確計算。

 

(2)常用的方法

   BigDecimal(String val) - 根據參數指定的字符串內容來構造對象。

   BigDecimal add(BigDecimal augend)

        - 用於計算調用對象和參數對象的和並返回。

   BigDecimal subtract(BigDecimal subtrahend)

        - 用於計算調用對象和參數對象的差並返回。

   BigDecimal multiply(BigDecimal multiplicand)

        - 用於計算調用對象和參數對象的積並返回。

   BigDecimal divide(BigDecimal divisor)

        - 用於計算調用對象和參數對象的商並返回。

 

6.5 BigInteger類(瞭解)

示例代碼:

D:\兄弟連視頻\day11\code\ TestBigInteger.java

(1)基本概念

   java.math.BigInteger類主要用於描述long類型不足以表示的數據。

 

(2)常用的方法

   BigInteger(String val) - 根據參數指定的字符串來構造對象。

   成員方法與上述類中的方法同名。

 

     

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第十二天 String類 正則表達式StringBuilder 日期類

1.String類

示例代碼:

D:\兄弟連視頻\day12\code\

1.1 基本概念 常量池

   java.lang.String類用於描述字符串,在Java程序中的所有字符串字面值都可以作爲該類的實例描述,如:“hello”。

   該類描述的字符串是個常量,字符串的內容不可改變。

如:

   String     name    =   "zhangfei";

     |          |              |

引用數據類型 引用變量名    字符串字面值

 

   name = "guanyu"; - 表示修改引用變量名name的指向,而不是指向的內容。

 

筆試題:

   String str = ""; 和 String str = null;之間有區別嗎?

解析:

   有區別,前面的表示有字符串對象,但裏面沒有內容;後面的表示連字符串對象都沒有

 

 

常量池:http://blog.csdn.net/dajunxing/article/details/48056419

http://www.cnblogs.com/javaminer/p/3923484.html

http://www.cnblogs.com/SaraMoring/p/5687466.html

1.2 常用的方法(練熟、記住)

(1)常用的構造方法

   String() - 使用無參的方式構造對象。

   String(byte[] bytes) - 根據參數指定的byte數組來構造對象。

   String(byte[] bytes, int offset, int length)

      - 根據參數指定byte數組中從offset位置開始的length個字節來構造對象。

   String(String original) - 根據參數指定的字符串來構造對象。

   String(StringBuffer buffer) - 根據參數指定的引用來構造對象。

   String(StringBuilder builder) - 同上

 

(2)常用的成員方法

   char charAt(int index) - 根據參數指定的下標返回對應的字符。

   int length() - 用於返回字符串的長度。

   

   int compareTo(String anotherString) - 用於比較調用對象和參數對象的大小。

        - 若調用對象和參數對象相等,則返回0;若大於則返回正數;若小於返回負數

        -分別使用兩個字符串中對應位置的字符從頭開始進行比較,若第一個字符能夠

          區分大小則比較結束,否則使用下一個位置的對應字符進行比較。

        - 當字符串的前面內容相同時,則長度更大的字符串比較大。

如:

   "hello"  'h' 'e' 'l'  'l' > 'h'  返回正數,證明"hello"字符串比較大

   "hehe"   'h' 'e' 'h'

  

   "hello"       'h' 'e' ...  存在的字符串內容相同時,則大小取決於長度

   "helloworld"  'h' 'e' ...    

 

   int compareToIgnoreCase(String str) - 比較字符串的大小,不考慮大小寫。

        - 也就是相同字母的大小寫之間比較的結果是相等,如:'a''A'是相等的。

   boolean equals(Object anObject) - 比較兩個字符串內容是否相等

   boolean equalsIgnoreCase(StringanotherString) - 比較是否相等,不考慮大小寫

 

   boolean contains(CharSequence s) - 判斷當前字符串是否包含參數指定的內容

   boolean endsWith(String suffix) - 判斷當前字符串是否以參數字符串爲結尾

   boolean startsWith(String prefix) - 判斷當前字符串是否以參數字符串開頭

   String toLowerCase() - 用於將當前字符串中的所有字符轉換爲小寫。

   String toUpperCase() - 用於將當前字符串中的所有字符轉換爲大寫。

   String trim() - 用於去除字符串兩端的空白字符。

   byte[] getBytes() - 用於將字符串類型轉換爲byte數組。

   char[] toCharArray() - 用於將字符串轉換爲char數組。

 

   int indexOf(int ch) - 返回參數指定字符在當前字符串中第一次出現的索引位置。

   int indexOf(int ch, int fromIndex)

       - 從fromIndex位置開始查找字符第一次出現的位置

   int indexOf(String str) - 從當前字符串中查找str第一次出現的位置並返回。

   int indexOf(String str, int fromIndex) - 從fromIndex位置開始查找。

  

   int lastIndexOf(int ch) - 返回當前字符串中字符ch最後一次出現的索引位置。

   int lastIndexOf(int ch, int fromIndex) - 從fromIndex位置開始查找

   int lastIndexOf(String str) - 返回當前字符串中字符串str最後一次出現索引位置

   int lastIndexOf(String str, int fromIndex) -從fromIndex位置開始查找

   

   String substring(int beginIndex) - 獲取從beginIndex位置開始到結尾的子字符串

   String substring(int beginIndex, intendIndex)

       - 獲取當前字符串中從beginIndex位置開始一直到endIndex位置(不包含)。

 

1.3 split拆分和replace方法

 

 

2. 正則表達式(百度現成的)

包:java.util.regex

(1)基本概念

   正則表達式本質上就是一個字符串,通常使用^開頭使用$結尾,可以省略.

   該字符串用於進行用戶輸入數據的格式驗證/檢查,若不匹配則報錯。

關鍵方法:matches     str.matches (reg)

 

(2)常用的規則  [表示一位]、{表示多位}

   [abc] - 表示可以出現a、b 或 c。

   [^abc] - 表示可以出現任何字符,除了 a、b 或 c。

   [a-zA-Z] - 表示可以出現a到z或A到Z,兩頭的字母包括在內,可以出現任何字母。

  

   . - 表示可以出現任何字符。

   \d - 表示可以出現任何數字,相當於[0-9]。

   \D - 表示可以出現任何非數字,相當於[^0-9]。

   \s - 表示可以出現任何空白字符,相當於[\t\n\x0B\f\r]。

   \S - 表示可以出現任何非空白字符,相當於[^\s]。

   \w - 表示可以出現任何單詞字符,相當於[a-zA-Z_0-9],

        也就是由字母、數字以及下劃線組成。

   \W - 表示可以出現任何非單詞字符,相當於[^\w]。

  

   X? - 表示X可以出現一次或一次也沒有,也就是0 ~ 1次。

   X* - 表示X可以出現零次或多次,也就是0 ~ n次。

   X+ - 表示X可以出現一次或多次,也就是1 ~ n次。

   X{n} - 表示X可以出現恰好 n 次。

   X{n,}- 表示X可以出現至少 n 次,也就是 >= n次。

   X{n,m} - 表示X可以出現至少 n 次,但是不超過 m 次,也就是 >= n 並且<= m次。

Variablemust provide either dimension   expressions or an array initializer

 

3.StringBuilder類和StringBuffer類(查手冊會用即可)

1.1 基本概念

   由於String類描述的字符序列是無法更改的,當需要描述多個相近的字符串時,不能對同一個字符串進行修改只能單獨保存,因此對內存空間的消耗比較大,此時可以使用StringBuilder類和StringBuffer類來替代之,這兩種類型描述的字符序列可以更改。

   StringBuffer類是jdk1.0就有的類,支持線程安全,因此效率比較低。

   StringBuilder類是jdk1.5提供的類,不支持線程安全,因此效率比較高(推薦)。

  

1.2 常用的方法

   StringBuilder(String str) - 根據參數指定的內容構造對象,容量爲16 + str長度

   int capacity() - 用於返回調用對象的容量。

   int length()   - 用於返回調用對象中的字符個數。

  

   StringBuilder insert(int offset, String str)

        - 用於將str插入當前字符串中下標爲offset的位置。

   StringBuilder append(String str)

        - 用於將字符串str的內容插入到當前字符串的末尾位置。

  

   StringBuilder delete(int start, int end)

        - 用於刪除當前字符串中從start(包含)開始到end(不包含)結束。

  

   StringBuilder replace(int start, int end,String str)

        - 用於將當前字符串中start和end之間的字符串使用str進行替換。

   StringBuilder reverse() - 用於反轉字符序列。

 

4.日期相關的類(查手冊會用即可)

示例代碼:

D:\兄弟連視頻\day12\code\ TestCalendar.java TestDate.java TestSimpleDateFormat.java

4.1 Date類

(1)基本概念

   java.util.Date類用於描述特定的瞬間,可以精確到毫秒。

 

(2)常用的方法     

   Date() - 使用無參的形式構造對象,默認採用當前系統時間來初始化。

   Date(long date) - 根據參數指定的毫秒數來構造對象。

       - 其中毫秒數爲指定日期和時間距離1970年1月1日 0時0分0秒。

       - 1秒 =1000毫秒  1毫秒 =1000微秒  1微秒 =1000納秒

       - 該方法與File類中的一個方法是絕配。

   long getTime() - 用於獲取當前對象距離1970年1月1日0時0分0秒的毫秒數。

   void setTime(long time) - 用於設置距離上述時間的毫秒數來更改當前對象。

 

4.2 SimpleDateFormat類

(1)基本概念

記得:import java.text.SimpleDateFormat;

   java.text.SimpleDateFormat類用於格式化和解析日期類型的數據。

   通俗來說,該類就是用於實現Date類型和String類型之間的轉換。

 

(2)常用的方法

   SimpleDateFormat(String pattern) - 根據參數指定的格式來構造對象。

       - 其中參數字符串中的內容:y-年、M-月、d-日、H-時、m-分、s-秒

   String format(Date date) - 用於將參數指定的日期對象轉換爲String類型並返回。

   Date parse(String source) - 用於將String類型轉換爲日期類型並返回。

  

4.3 Calendar類

(1)基本概念

   java.util.Calendar類用於描述特定的瞬間,該類中的方法用於取代Date類過時方法

   該類是一個抽象類,不能實例化對象的。

 

(2)常用的方法  

   static Calendar getInstance() - 用於獲取該類的一個實例(多態)。

   void set(int year, int month, int date, inthourOfDay, int minute, int second) - 用於指定年月日時分秒信息的。

   Date getTime() - 用於將Calendar類型的對象轉換爲Date類型並返回。

 

 

 

4.4 TimeStamp時間戳

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第十三、十四天  集合類(容器)Collections  Map

示例代碼:

D:\兄弟連視頻\day14\code 和day15\code\

1 .綜述

1.1 基本概念

定義:Java.util中的接口 Collection<E>又被稱爲Java Collections frameworkJava容器的用途是保存對象,根據數據結構不同將其劃分爲CollectionMap

   當需要記錄多個類型不同/相同的數據時,則聲明一個集合記錄即可,集合就是容器。

   數組 - 本質上就是內存中的一塊連續存儲空間,用於記錄多個類型相同的數據。

        - 一旦聲明數組之後則長度固定,無法改變。

        - 插入和刪除元素不方便,可能會導致大量元素的移動。

        - 支持下標訪問,可以實現隨機訪問。

        - 既可以存放基本類型的數據,也可以存放引用類型的數據。

   集合 - 內存空間可以連續也可以不連續,記錄的數據類型可以相同也可以不同。

        - 集合的長度是可以隨時動態調整。

        - 插入和刪除元素可以不移動大量的元素。

        - 可以支持下標訪問,隨機訪問。

        - 只可以存放引用類型的數據,基本類型的數據不可以。   

 

1.2 基本分類

   在Java語言中將集合框架分爲兩大類:Collection接口 和 Map接口。

   其中Collection接口中操作元素的基本單位是:單個元素。

   其中Map接口中操作元素的基本單位是:單對元素。

  

   通常情況下,Collection接口很少使用,更多地使用該接口的子接口:List接口、Queue接口、以及Set接口。

 

1.3 Collection接口的常用方法(熟練、記住)

   boolean add(E e) - 用於將參數指定的元素e放入當前集合.

       - 成功返回true,否則false。

   boolean addAll(Collection<? extends E>c)

       - 用於將參數指定集合中的所有元素一個一個放入當前集合中。

  

   boolean remove(Object o) - 用於從當前集合中移除參數指定的單個元素。

   boolean removeAll(Collection<?> c) - 用於從當前集合移除參數指定所有元素。

   void clear() - 用於清空當前集合。

 

  boolean contains(Object o) - 用於判斷是否包含單個元素。

   boolean containsAll(Collection<?>c)  - 判斷是否包含參數指定所有元素

 

   boolean isEmpty() - 判斷是否爲空

   int size() - 獲取元素的個數

  

   boolean retainAll(Collection<?> c)-計算當前集合和參數集合的交集放入當前集合

   Iterator<E> iterator() - 獲取當前集合的迭代器。

2.List接口(重中之重)

示例代碼:D:\兄弟連視頻\day14\code\TestCollection.java和TestList.java

2.1 基本概念

   java.util.List接口是Collection接口的子接口,元素有先後次序並且可以重複。

   該接口的主要實現類有:ArrayList類、LinkedList類、Stack類、Vector類。

   其中ArrayList類的底層是採用動態數組來進行管理的,訪問方便,增刪不方便。

   其中LinkedList類的底層是採用鏈表來進行管理的,訪問不方便,增刪方便。

   其中Stack類的底層是採用動態數組來進行管理的,但該類具有後進先出的特性,簡稱爲LIFO(lastin first out),漢語名稱爲:棧。

   其中Vector類的底層是採用動態數組實現的,與ArrayList類相比是早期的類,支持線程安全,效率比較低,因此推薦使用ArrayList類。

 

2.2 常用的方法  E - 在此 collection 中保持的元素的類型

booleanadd( E e) - 用於將指定元素添加到此列表的結尾。

voidadd(int index, E element) - 用於將元素element插入到index的位置。

booleanaddAll(int index, Collection<? extends E> c)

        - 用於將集合c中的所有元素插入到當前集合中index位置。

  // boolean add(E,e) 將集合c2看做一個整體放入集合c1中。boolean= c1.add(c2)。

    E remove(int index) - 用於刪除當前集合中下標爲index位置的元素並返回。

    E set(int index, E element) - 用於使用element替換下標爲index位置元素並返回

    E get(int index) - 用於獲取index位置的元素並返回。

publicboolean retainAll(Collection<?> c)

c1.retainAll(c2) :取c1和c2的交集並放入c1中。

publicboolean containsAll(Collection<?> c)

c1.containsAll(c2) 如果c1包含容器c2中的所有元素,則返回 true。

boolean contains(Object o)

 c1.contains(“abc”)  如果此列表中包含指定的元素,則返回 true。

contains調用集合包含對象的equals方法與待判斷對象比較。一般要重寫equals

    List<E> subList(int fromIndex, inttoIndex)

       - 用於獲取fromIndex位置(包含)到toIndex位置(不包含)的視圖並返回。

       - 只是獲取數據並沒有申請新的存儲空間單獨保存。

 

3.泛型機制Stack棧

示例代碼:D:\兄弟連視頻\day14\code\ TestStack.java

目前集合中之所以可以存放不同類型的數據,是因爲將每個元素都看做Object類型放入的,當從集合中取出元素時默認也是Object類型,爲了表達該元素真實的類型就需要強制類型轉換,此方式可能引發類型轉換異常。

   爲了避免上述錯誤的發生,從jdk1.5開始要求使用集合時加上泛型機制,也就是在集合類型的後面使用<數據類型>的方式明確規定可以存放的數據內容,若放入其他類型數據則編譯報錯,如:

   List<String> l1 = newLinkedList<String>();

       

   泛型的本質就是參數化類型,也就是將數據類型作爲實參傳遞給該接口/類中的形參E,從此E全部被替換爲實參類型。

  jdk中的K,V,T,E等泛型名稱很多人以爲是固定寫法,其實這些名稱是可以改的,比如改成zhangsan,lisi都可以,jdk爲了容易看懂,所以用K表示鍵,V表示值,T表示type類型,E表示enum枚舉,其實這四個都只是符號,都是表示泛型名稱,下面的例子的T全部可以換成E,也可以換成K,V,zhangsan,都沒關係。 
   ? 表示不確定的類型 
   Object java中所有類的父類。

http://blog.csdn.net/xswh520/article/details/9160875

 

4.Queue隊列接口(重點)

示例代碼:D:\兄弟連視頻\day14\code\ TestQueue.java

4.1 基本概念

  java.util.Queue接口是Collection接口的子接口,與List接口是平級關係。

  該接口的主要實現類是:LinkedList類,增刪比較方便。

  隊列就是一種具有先進先出特性的數據結構,簡稱爲FIFO(firstin first out)。

 

4.2 常用的方法

  boolean offer(E e) - 用於將參數指定的元素放入當前隊列的末尾。

  E poll() - 用於獲取隊列的首元素並移除,若隊列爲空則返回null。

  E peek() - 用於獲取隊列的首元素,若隊列爲空則返回null。

這裏簡單對其重複的方法做點簡單的區分。

offer,add區別:

一些隊列有大小限制,因此如果想在一個滿的隊列中加入一個新項,多出的項就會被拒絕。

這時新的 offer 方法就可以起作用了。它不是對調用add() 方法拋出一個unchecked 異常,而只是得到由 offer()返回的 false。 

 

poll,remove區別:

remove()和 poll() 方法都是從隊列中刪除第一個元素。remove() 的行爲與Collection 接口的版本相似,

但是新的 poll() 方法在用空集合調用時不是拋出異常,只是返回 null。因此新的方法更適合容易出現異常條件的情況。

 

peek,element區別:

element()和 peek() 用於在隊列的頭部查詢元素。與 remove() 方法類似,在隊列爲空時,element() 拋出一個異常,而 peek() 返回 null

 

 

4.Set接口(重點)

示例代碼:D:\兄弟連視頻\day14\code\ TestSet.java和TestTreeSet.java

4.1 基本概念

   java.util.Set接口是Collection接口的子接口。元素沒有先後次序並且不允許重複。

   該接口的主要實現類:HashSet類 和 TreeSet類。

   其中HashSet類的底層是採用哈希表進行管理的。

   其中TreeSet類的底層是採用二叉樹進行管理的。

4.2 HashSet類

 

4.3 TreeSet類

常用方法:Set<Integer> s1 = new TreeSet<Integer>(); 一般TreeSet只存放同一種泛型的元素。方便實現Comparable接口。

 

(1)什麼是二叉樹?

   二叉樹就是指每個節點最多隻有兩個子節點的樹形結構。

   

(2)什麼是有序二叉樹?

   有序二叉樹就是指滿足以下三個條件的樹形結構,又叫做二叉查找樹。

       a.左子樹中的任何節點元素值都小於根節點元素值。

       b.右子樹中的任何節點元素值都大於根節點元素值。

       c.左右子樹的內部也要滿足上述規則。

 

(3)TreeSet類的要求

   當使用TreeSet類存放元素時必須要指定元素比較大小的規則,具體方式如下:

       a.使用元素的自然排序來指定規則,讓元素類型實現java.lang.Comparable接口.

       b.使用比較器來指定規則,創建TreeSet對象時指定java.util.Comparator接口。

 

 

 

4.4 Comparable接口和Comparator接口

Comparable接口:

 

Comparator接口

 

4.5常用的工具類

   java.util.Arrays類主要提供了大量用於操作數組的工具方法。

   java.util.Collections類主要提供了大量用於操作集合的工具方法。

5. Iterator迭代器常用的方法

   參考Collection接口即可。

   Iterator<E> iterator()

       - 用於獲取當前集合中的迭代器,可以迭代/遍歷/獲取集合中的每個元素。

         boolean hasNext() - 根據迭代器判斷當前集合是否擁有可以訪問的元素。

         E next()  - 用於獲取集合中的一個元素。

         void remove() - 用於從集合中移除迭代器返回的最後一個元素。

 

注意:

   當使用迭代器訪問集合中的所有元素時,切記不允許使用集合中的remove()方法刪除元素,否則會引發併發修改異常,建議使用迭代器自己的remove()方法刪除。

 

 

 

6. 增強版的for循環(foreach)

(1)語法格式

   for(元素類型 變量名 : 數組名/集合名){

       循環體;

   }

 

(2)執行流程

   每次從數組/集合取出一個元素賦值給變量名在循環體中使用,直到取完所有元素爲止 。

 

總結:

   對於Set集合(無序)中的元素訪問方式有3種:toString()、迭代器、for each結構。

   對於List集合(有序)的元素訪問方式有4種:除了上述3種方式,還有get()方法。

 

7.Map接口(重點)

示例代碼:D:\兄弟連視頻\day15\code\ TestTreeSet.java和TestMap.java

 

7.1 基本概念

   java.util.Map<K,V>集合用於存放鍵值對,其中鍵不允許重複,只能對應一個值。

       類型參數:

          K - 此映射所維護的鍵(Key)的類型

          V - 映射值(Value)的類型

   該接口的主要實現類:HashMap類 和 TreeMap類。

7.2 常用的方法

    V put(K key, V value) - 用於將參數指定的key和value組成一對放入當前集合中。

        - 當該方法實現增加的功能時返回null,但實現修改的功能時則返回之前的舊值

    V remove(Object key) - 用於根據參數指定的key從當前集合移除,返回對應value

    boolean containsKey(Object key) - 用於判斷參數指定的key是否存在。

    boolean containsValue(Object value) - 用於判斷參數指定的value是否存在。

    V get(Object key) - 根據參數指定的key返回對應的value,若不存在則返回null。

   

    Set<Map.Entry<K,V>> entrySet()- 用於獲取包含映射關係的Set視圖。如下圖:

         - 通俗來說,就是將Map集合轉換爲Set集合。

         - K getKey() - 用於獲取調用對象中的key.

         - V getValue() - 用於獲取調用對象中的value。

    Set<K> keySet() - 用於獲取包含鍵的Set視圖。

 

 

7.3 HashMap

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第十五天 異常Exception

示例代碼:

D:\兄弟連視頻\day15\code 和day16\code\

 

1. 基本概念

   異常就是不正常的意思,在Java語言中主要指在運行階段產生的錯誤。

   Java.lang.Throwable 類是 Java 語言中所有錯誤或異常的超類。

   該類的主要實現子類有:Error類 和Exception類。

   其中Error類主要用於描述比較嚴重的錯誤,無法通過編碼來解決。

   其中Exception類主要用於描述輕微的錯誤,可以通過編碼等方式解決。

 

2. 基本分類

   Java.lang.Exception類的所有已知子類分爲以下兩大類:

        RuntimeException - 運行時異常,也叫做非檢測性異常。

        IOException和其它所有異常 - 其它異常,也叫做檢測性異常。

              - 檢測性異常就是指在編譯階段可以被編譯器檢測出來的異常。

 

注意:

   當程序執行過程中發生異常並沒有手動編碼處理時,則採用默認處理方式,通常終止程序的執行並打印異常名稱、異常原因以及異常的位置等信息,導致後續代碼無法執行。

 

   Java.lang.RuntimeException類的主要子類:

       ArithmeticException - 算數異常

       ArrayIndexOutOfBoundsException - 數組下標越界異常(間接子類)

       NullPointerException - 空指針異常

       ClassCastException - 類型轉換異常

       NumberFormatException - 數字格式異常(間接子類)

       StringIndexOutOfBoundsException - 字符串下標越界異常(間接子類)

       ConCurrentModificationException - 併發修改異常

 

3. 非檢測異常的處理

   在以後的開發中可以使用if()條件判斷來避免絕大多數非檢測異常的發生。

 

4. 異常的捕獲try catch finally語句

(1)語法格式

   try{

      編寫所有可能發生異常的語句塊;

   }

   catch(異常類型 變量名){

      編寫處理當前異常類型的語句塊;

   }

   ... ...

   finally{

      編寫無論是否發生異常都應該執行的語句塊;

   }

   

(2)注意事項

   當需要編寫多個catch()分支,切記小範圍的異常類型應該放在大範圍異常類型的上面。

   懶人的寫法:

        catch(Exception e){ ...}

   finally{}中通常編寫用於進行善後處理的語句塊,比如:關閉文件、斷開數據庫等。

 

5. 異常的拋出throws

(1)基本概念

   當某些特殊場合中發生了異常卻無法處理或者不便於處理時,就可以將異常拋給該方法的調用者,這個過程就叫異常的拋出/轉移。可以通過throws關鍵字拋出異常。

 

(2)語法格式

   返回值類型 方法名(形參列表) throws異常類型1,異常類型2,...{ 方法體; }

如:

   public void show() throws Exception { }     

 

(3)方法重寫的原則

   a.要求方法名相同、參數列表相同以及返回值類型相同,從jdk1.5開始允許返回子類

   b.訪問權限不能變小,可以相同或者變大。

   c.不能拋出更大的異常。

 

注意:

   子類中重寫的方法可以拋出與父類中方法一樣的異常、更小的異常以及不拋出異常,

但不能拋出更大的異常,也不能拋出額外的異常。

 

6. 自定義異常

(1)自定義異常的由來

   當需要在程序中表達年齡不合理的異常時,在java官方庫中並沒有對應的異常類型,此時就需要自定義異常類來表達該錯誤,從而提高代碼的可讀性。

 

(2)自定義異常的步驟

   a.自定義xxxException類繼承自Exception類或者其子類。

   b.提供無參的構造方法和字符串作爲參數的構造方法。

自定義構造方法:(繼承父類Exception的構造方法)

要拋出異常的代碼:

 

(3)異常對象的拋出

   throw new 異常類型();

7. throws和throw區別

throws:用於拋出異常的聲明。

格式:返回值類型 方法名(形參列表) throws 異常類型1,異常類型2,...{ 方法體; }

位置:throws在方法體外,在方法名(形參列表)之後。

後面:throws後面可以跟多個異常類型。

 

throw:用於拋出一個異常對象。

格式:throw new 異常類型();

位置:throw在方法體裏面。

後面:throws後面只能跟一個對象。

 

8. 運行異常類的子類異常7個

算術異常:ArithmeticException

數組下標越界異常:ArrayIndexOutOfBoundsException

字符串下標越界異常:StringIndexOutOfBoundsException

空指針異常類:NullPointerException

數據類型轉換異常:ClassCastException

數據格式異常:NumberFormatException(間接子類)

併發修改異常: ConcurrentModificationException

 

 

 

 

第十六、十七天  File類   IO流

1.File類(重點)

示例代碼:

D:\兄弟連視頻day16\code\TestFile.java

1.1 基本概念

   java.io.File類用於作爲文件和目錄路徑信息的抽象表示,可以獲取文件和目錄的屬性信息,如:名稱、大小等信息。但是不能對文件的內容進行訪問

1.2 常用的方法

  構造方法: File(String pathname) - 根據參數指定的路徑名來構造對象。

   boolean exists() - 用於判斷文件或目錄是否存在。

   String getName() - 用於獲取文件或目錄的名稱。

   long length() - 用於獲取文件的長度/大小。

   long lastModified() - 用於獲取文件的最後一次修改時間。

        - 返回距離1970年1月1日0時0分0秒之間的毫秒數

        - 與Date類中的Date(long)構造方法搭配使用

   String getAbsolutePath() - 用於返回絕對路徑信息。

       絕對路徑 - 主要指從根目錄開始的路徑信息,如:c:/... d:/..

       相對路徑 - 主要指從當前目錄開始的路徑信息,如:./code ./code/code

                  . 代表當前目錄    .. 代表當前目錄的上一級目錄

       在以後的開發中推薦使用相對路徑。

   boolean delete() - 用於刪除文件或目錄。

   boolean createNewFile() - 用於創建新的空文件。 

   boolean mkdir() - 用於創建目錄。

   boolean mkdirs() - 用於創建多級/層目錄。

   File[] listFiles() - 用於獲取指定目錄中的所有內容並返回。

   boolean isFile() - 用於判斷調用對象關聯的是否爲一個文件。

   boolean isDirectory() - 用於判斷調用對象關聯的是否爲一個目錄。

 

1.3 目錄FileFilter接口

 

2.I/O流

示例代碼:

D:\兄弟連視頻day16\code\和day17\code\

2.1 基本概念

  I/O就是Input/Output的簡寫,也就是輸入/輸出,換句話說,也就是讀取/寫入操作。

  I/O流就是指像流水一樣不間斷地進行讀寫的操作。

2.2 基本分類

  根據讀寫操作的基本單位不同分爲:字節流 和 字符流。

   其中字節流就是指以字節爲基本單位進行讀寫的流,可以處理任何文件

   字符流就是指以字符(2個字節)爲基本單位進行讀寫的流,只能處理文本文件

   

   根據讀寫操作/數據流動的方向不同分爲:輸入流 和 輸出流(站在程序的角度)。

   其中輸入流就是指讀取文件中的內容輸入到程序中的流,也就是讀文件

   其中輸出流就是指將程序中的內容輸出到文件中的流,也就是寫文件

數據傳輸方式:

節點流(直接和文件打交道)和包裝流(程序和文件之間有管道,不直接接觸)。

2.3 I/O流的框架

   字節流的頂層父類爲:InputStream類 和OutputStream類。 - 抽象類

   其中InputStream類的主要子類有:

       FileInputStream類、DataInputStream類、ObjectInputStream類。

   其中OutputStream類的主要子類有:

       FileOutputStream類、DataOutputStream類、ObjectOutputStream類。

  

   字符流的頂層父類爲:Reader類 和 Writer類。           - 抽象類    

   其中Reader類的主要子類有:

      BufferedReader類、InputStreamReader類、StringReader類。

   其中Writer類的主要子類有:

      BufferedWriter類、OutputStreamWriter類、StringWriter類。

 

補充:

   PrintStream類是OutputStream類的間接子類。

2.4 FileOutputStream類(重中之重)

(1)基本概念

   java.io.FileOutputStream類用於將圖像數據之類的原始字節流寫入到輸出流中。

 

(2)常用的方法

   FileOutputStream(String name) - 根據參數指定的文件路徑構造對象並建立關聯。

   FileOutputStream(String name, booleanappend) - 以追加的方式建立關聯。

   void write(int b) - 用於寫入參數指定的單個字節。b自動找對應的ASCII碼值。

   void write(byte[] b, int off, int len)

       - 用於將數組b中從off位置開始的len個字節寫入。

   void write(byte[] b) - 用於將參數指定整個數組的內容寫入。

   void close() - 關閉輸出流並釋放有關的資源。

 

2.5 FileInputStream類(重中之重) -1和1

(1)基本概念

   java.io.FileInputStream類主要用於讀取圖像數據之類的原始字節流。  

 

(2)常用的方法

   FileInputStream(String name) - 根據參數指定的路徑名來構造對象。

   int read() - 用於從輸入流中讀取一個字節並返回。

       - 當讀取到文件末尾時則返回-1,否則返回讀取到的數據內容。

   int read(byte[] b, int off, int len)

       - 從輸入流中讀取len個字節的數據放入數組b中下標爲off的位置上。

       - 當讀取到文件末尾時則返回-1,否則返回讀取到的字節個數。

   int read(byte[] b)

       - 用於從輸入流中讀取b.length個字節到數組b中。

   int available()

       - 用於返回通過此輸入流可以讀取到的文件大小。

   void close()- 關閉輸出流並釋放有關的資源。

 

注意:

文件調用 FileOutputStream.write(-1);-1默認是INT型4個字節(32位,32個1)。但是voidwrite(int b)方法只能寫入一個字節(8位),所以讀取的是低8位,即:1111 1111

文件調用FileInputStream.read();但是int read( )方法只能讀取一個字節(8位),但是返回一個int型4個字節,32位。所以前面補32-8=24個0。即:00000000 0000 0000 0000 0000 1111 1111所以返回255。

 

 

文件拷貝:FISFOS

2.6 DataOutputStream類(熟悉)

(1)基本概念

   java.io.DataOutputStream類用於將基本類型的數據寫入輸出流中。

 

(2)常用的方法

   DataOutputStream(OutputStream out) - 根據參數指定的引用來構造對象。

       - 其中OutputStream類是抽象類,實參需要傳遞子類的對象。

   void writeInt(int v) - 用於將參數指定的整型變量值寫入輸出流中。

   void close()

 

2.7 DataInputStream類(熟悉)

(1)基本概念

   java.io.DataInputStream類用於從輸入流中讀取基本類型的數據。

 

(2)常用的方法  

   DataInputStream(InputStream in) - 根據參數指定的引用來構造對象。

       - 其中InputStream類是抽象類,實參需要傳遞子類的對象。

   int readInt() - 用於從輸入流中讀取一個整型數據並返回。

   void close()- 用於關閉IO流

2.8 BufferedReader類(重點)

(1)基本概念

   java.io.BufferedReader類用於讀取單個字符、字符數組以及一行字符內容。  

 

(2)常用的方法

   BufferedReader(Reader in) - 根據參數指定的引用來構造對象。

       - 其中Reader類是個抽象類,實參需要傳遞子類的對象。

       - 子類對象選擇InputStreamReader類型的對象,選擇FileInputStream類型對象

   String readLine() - 用於讀取一行字符串內容並返回。

   void close()          - 用於關閉IO流

 

2.9 BufferedWriter類(重點)

(1)基本概念

   java.io.BufferedWriter類用於寫入單個字符、字符數組以及一行字符內容。   

 

(2)常用的方法

   BufferedWriter(Writer out) - 根據參數指定的引用來構造對象。

       - 其中Writer類是個抽象類,實參需要傳遞子類的對象。

       - 子類對象選擇OutputStreamWriter類的對象,選擇FileOutputStream類型對象

   void write(String s, int off, int len)

       - 用於將字符串s中從下標爲off位置開始的len個字符寫入輸出流中。

   void newLine() - 用於寫入行分隔符。

   void close()       - 關閉該流的緩衝。

   void write(String str) - 從Writer類繼承下來的方法,用於寫入參數指定的字符串

voidflush()        - 刷新該流的緩衝。對於輸出的緩衝流,寫出的數據會先在內存中緩存,使用flush()將會使內存中的數據立刻寫出

 

 

2.10 PrintStream類(重點)

(1)基本概念

   java.io.PrintStream類用於方便地打印各種格式的數據。

 

(2)常用的方法

   PrintStream(OutputStream out) - 根據參數指定的引用構造對象。

      - 其中OutputStream類是抽象類,實參需要傳遞子類的對象。

   void print(String s) - 用於打印參數指定的字符串。

   void println(String x) - 用於打印字符串並終止該行。

void write(byte[] buf, int off, int len)

          - 將 len 字節從指定的初始偏移量爲 off 的 byte 數組寫入此流。

   void close()

(3)PrintStream與BufferedReader相對應。

 

2.11 ObjectOutputStream類(重點)

(1)基本概念

   java.io.ObjectOutputStream類用於將Java語言的對象整體寫入到輸出流中。

   只能將支持 java.io.Serializable 接口的對象寫入流中。(類必須實現該接口)

   類通過實現 java.io.Serializable 接口以啓用其序列化功能。

   所謂的序列化就是指將對象中需要保存的相關信息有效地組織成字節序列的過程。

 

(2)常用的方法 

   ObjectOutputStream(OutputStream out) - 根據參數指定的引用來構造對象。

       - 其中OutputStream類是抽象類,因此實參需要傳遞子類的對象。

   void writeObject(Object obj) - 用於將參數指定的對象寫入到輸出流中。

   void close()

User是一個類且已經實現java.io.Serializable 接口

2.12 ObjectInputStream類(重點)

(1)基本概念

   java.io.ObjectInputStream類用於從輸入流中讀取整個對象。

 

(2)常用的方法   

   ObjectInputStream(InputStream in) - 根據參數指定的引用構造對象。

        - 其中InputStream類是抽象類,因此實參需要傳遞子類的對象。

   Object readObject() - 用於讀取一個對象並返回。

        - 無法通過該方法的返回值來判斷是否讀取到文件末尾。

   void close()

 

經驗:

   當需要向文件中寫入多個對象時,建議先將多個對象放入集合中,再將整個集合看做一個對象整體寫入文件中,此時讀取文件中的內容只需要讀取一次就結束。

 

2.13 轉換類InputStreamReader和OutputStreamReader

(1)基本概念

   java.io. InputStreamReader:輸入時,實現字節流到字符流的轉換,提高操作的效率(前提是,數據是文本數據)。= = ==》解碼:字節數組---->字符串

   java.io. InputStreamReader:輸出時,實現字符流到字節流的轉換,提高操作的效率(前提是,數據是文本數據)。= = ==》解碼:字符串 ---->字節數組

 

2.14 標準的輸入輸出流

System.in:標準輸入流(鍵盤輸入)      System.out:標準輸出流(顯示器輸出)

 

第十八、十九天  線程

示例代碼:

D:\兄弟連視頻day18和day19\code\

 

1.線程的基本概念和基本操作

1.1 線程、進程 基本概念

   程序 - 數據結構 + 算法,主要指存放在硬盤/磁盤上的可執行文件。

   進程 - 主要指運行在內存中的程序。

   目前主流的操作系統都支持多進程,爲了讓操作系統在同一時間可以執行多個任務,但進程是重量級的,新建進程對系統的資源消耗比較大,因此不建議啓動過多的進程。

   線程就是指進程內部的程序流,也就是說操作系統支持多進程,在每一個進程的內部又可以支持多線程,並且線程是輕量級的,新建線程會共享所在進程的資源。

   因此在以後的開發中都使用多線程的機制。

   操作系統中通常都採用時間片輪轉法來保證多個任務的併發執行,所謂的併發就是指宏觀並行,微觀串行。

1.2 Thread類

 

2.線程的創建和主要方法

2.1 線程的創建(重中之重)

(1)線程的創建方式

   java.lang.Thread類用於描述線程,Java 虛擬機允許應用程序併發地運行多個執行線程。

   創建線程的主要方式:

      a.自定義類繼承Thread類並重寫run()方法,創建該類的對象調用start()方法。

      b.自定義類實現Runnable接口並重寫run()方法,創建該類的對象作爲創建Thread類對象的實參,最後使用Thread類的對象調用start()方法。

  

(2)線程創建的相關方法

   Thread() - 使用無參的方式構造對象。

   Thread(String name) - 使用參數指定的名稱來構造對象。

   Thread(Runnable target) - 根據接口類型的引用來構造對象。

   Thread(Runnable target, String name) - 根據接口引用和名稱來共同構造對象。

 

   void run() - 當調用對象是根據參數指定的接口引用構造時,則最終調用該接口引用所指向對象的run()方法,否則該方法啥也不做並返回。

   void start() - 用於啓動線程,JVM會調用該線程的run()方法。

 

(3)多線程的原理分析

   其中執行main()方法的線程叫做主線程,執行run()方法的線程叫做新線程/子線程。

   對於start()方法之前的代碼來說,只會被主線程執行一次,當start()方法調用成功之後,線程的個數瞬間由1個變成了2個,其中新創建的子線程去執行run()方法中的代碼塊,而主線程繼續向下執行,於是兩個線程同時執行產生了交錯的打印結果。

   當run()方法的代碼執行完畢後表示子線程結束;當main()方法的代碼執行完畢後表示主線程結束,各自獨立運行互不影響;主線程和子線程的先後執行次序沒有明確的規定,由系統的調度算法來決定。

 

注意:

   線程創建和啓動的兩種方式相比,採用繼承的方式相對來說代碼量簡單但是可維護性比較差,而實現接口的方式代碼相對複雜但可維護性更高,因此推薦使用實現接口的方式。

繼承方式:

 

實現接口方式:

2.2 線程的名稱和編號(熟悉)

   long getId() - 用於獲取線程的編號/標識符並返回。

   String getName() - 用於獲取線程的名稱並返回。

   void setName(String name) - 用於修改線程的名稱爲參數指定的內容。

   static Thread currentThread() - 用於返回當前正在執行的線程對象的引用。

 

2.3 線程的主要狀態(熟悉)

   新建狀態 - 當使用new創建線程對象之後進入的狀態。

            - 此時線程並沒有開始執行。

   就緒狀態 - 調用start()方法之後進入的狀態。

            - 此時線程依然沒有開始執行。

   運行狀態 - 當線程調度器調用已經就緒完成的線程後進入的狀態。

            - 此時線程開始執行。

            - 當時間片執行完畢後但任務沒有完成時回到就緒狀態。

   消亡狀態 - 當時間片執行完畢後並且任務已經完成時進入的狀態。

            - 此時線程已經終止。

   阻塞狀態 - 當線程在執行的過程中發生了阻塞事件進入的狀態,如:sleep()方法。

            - 當阻塞解除後進入就緒狀態。

 

2.4 Thread類的常用方法

   static void yield() - 讓出CPU的執行權,轉而去執行其他的線程(瞭解)。

   static void sleep(long millis) - 讓當前正在執行的線程休眠參數指定的毫秒數。

   static void sleep(long millis, int nanos) - 讓線程休眠參數指定的毫秒 + 納秒。

        - 1秒 =1000毫秒  1毫秒 =1000微秒  1微秒 =1000納秒

   void interrupt() - 用於中斷線程,通常用於睡眠的打斷(瞭解)。

   int getPriority() - 用於獲取當前線程的優先級。

   void setPriority(int newPriority) - 用於修改線程的優先級爲參數指定的數值。

       - 優先級高的線程表示獲取時間片的機會越多,但不保證一定先執行。

   boolean isDaemon() - 用於判斷當前線程是否爲守護線程。

   void setDaemon(boolean on) - 用於設置該線程爲守護線程。

void join() - 用於等待調用對象所描述的線程終止。

   void join(long millis) - 等待調用對象終止的最長時間爲參數指定的毫秒。

   void join(long millis, int nanos) - 用於等待參數指定的毫秒 + 納秒。

- 守護線程又叫做後臺線程,當所有非守護線程結束時,守護線程隨之結束。

 

 

3.線程的同步機制(重點)

3.1 基本概念

   當多個線程在同一時刻訪問同一種共享資源時,可能會造成數據的不一致問題,此時就需要對線程的操作進行協調,而線程之間的協調和通信就叫做線程的同步機制。

3.2 解決方案

  由程序可知:當線程一還沒有來得及將最新餘額寫入後臺數據庫時,線程二已經開始執行, 導致最終的結果不正確。

  解決方案:  將多個線程的並行操作改爲串行操作即可。

  引發問題:  當多個線程依次串行執行時,會導致執行的效率比較低,因此能不用則不用。

3.3 實現方式

   爲了解決上述問題,可以使用Java語言中synchronized關鍵字來保證線程操作的原子性,也就是說當線程執行鎖定的代碼時必須執行完畢纔會釋放CPU的執行權。

   具體方式如下:

      (1)使用同步語句塊的方式來保證原子性,語法格式如下:

         synchronized(類類型的引用){//可以用synchronized(this)

             編寫需要鎖定的代碼塊;

         }

         注意:

            多個線程所使用的鎖對象必須是同一個對象,否則無法實現同步的效果。

            因此通常推薦使用this關鍵字。

     (2)使用synchronized關鍵字來修飾整個方法。

3.4 原理分析

   當多個線程啓動後各自獨立運行都去搶佔對象鎖,若其中一個線程搶到了對象鎖則可以放心地執行鎖定的所有代碼,其他線程進入阻塞狀態,直到該線程執行完畢所有鎖定代碼後自動釋放對象鎖,此時等待的其他線程又可以搶佔對象鎖,搶到的線程去執行鎖定的代碼,搶佔不到的線程繼續保持阻塞狀態。

3.5 死鎖的概念

線程一執行的代碼:

   void run(){

       synchronized(a){      持有對象鎖a,等待對象鎖b

          ...

          synchronized(b){

              ... ...

          }

       }

   }

線程二執行的代碼:

   void run(){

       synchronized(b){     持有對象鎖b,等待對象鎖a

          ...

          synchronized(a){

              ... ...

          }

       }

   }

   在以後的開發中儘量不要使用同步語句塊的嵌套結構!!!

 

3.6 Object類中的常用方法

   void wait() - 用於讓當前正在執行的線程進入阻塞狀態,直到其他線程調用notify()或者notifyAll()方法(開發中推薦)

   void wait(long timeout) - 用於讓當前線程進入阻塞狀態,直到其他線程調用方法或者參數指定的毫秒數已經過去了。

   void notify() - 用於喚醒等待的單個線程(隨機)。

   void notifyAll() - 用於喚醒等待的所有線程。

3.7 線程池

第十九、二十天  網絡編程

示例代碼:

D:\兄弟連視頻day20\code\

1.網絡編程的常識(記住)

1.1 七層網絡協議模型

   ISO(國際標準委員會組織)將數據的傳遞從邏輯上劃分爲了以下七層:

       應用層、表示層、會話層、傳輸層、網絡層、數據鏈路層、物理層。

   當發送數據時需要按照上述七層的先後次序一層層進行加包處理,然後再發出。

   當接收到數據時需要按照上述七層的相反次序一層層進行拆包處理,然後再解析。

1.2 常見的網絡協議

   http - 超文本傳輸協議,瀏覽網頁時可以使用該協議。

   ftp  -文件傳輸協議,  上傳和下載文件時使用該協議。

   tcp  -傳輸控制協議,  進行網絡通信時使用該協議。

   udp  -用戶數據報協議,進行網絡通信時使用該協議。視頻緩存。

   ip   -Internet Protocol互聯網協議,是上述協議的底層協議

 

   協議 - 本質上就是一種約定/規則,用於實現雙方有效的通信。

1.3 IP地址(重點)

如:

   192.168.1.1 - 絕大多數路由器的登錄地址,進行Mac地址過濾。 

  

   IP地址 - 是互聯網中的唯一標識,可以通過IP地址定位到具體某一臺主機。

   IP地址本質上是由32位二進制組成的整數,叫做ipv4,當然也有128位二進制組成的整數,叫做ipv6,目前使用主流的還是ipv4.

   日常生活中採用點分十進制表示法來進行IP地址的描述,也就是將IP地址的每個字節轉換爲一個十進制整數,不同的十進制整數之間採用小數點分隔。

   如:

       0x01 02 03 04 => 1.2.3.4

   

查看IP地址:

   在windows系統的dos窗口中使用命令:ipconfig   ipconfig/all

   在linux系統的終端窗口中使用命令: ifconfig   /sbin/ifconfig

1.4 端口號(重點)

   IP地址 - 可以定位到具體某一臺設備/主機。

   端口號 - 可以定位某臺設備/主機中的具體某個進程。

   網絡通信/編程提供:IP地址 + 端口號。

  

   端口號本質上就是由16位二進制組成的整數,範圍是:0 ~ 65535,其中0 ~1024之間的端口號通常被系統佔用,因此編程時需要從1025開始使用。

2. 基於tcp協議的編程模型(重點)

2.1 基本概念

   C/S架構 -C(Client 客戶端)/S(Server服務器)   

   B/S結構 -B(Browser 瀏覽器)/S(Server服務器)

   Socket - 本意"插座",在網絡編程中表示用於通信的邏輯載體/端點,俗稱“套接字”。

2.2 編程模型

服務器:

   (1)創建ServerSocket類型的對象,並綁定參數指定的端口號。

   (2)等待客戶端的連接請求,調用accept()方法。

   (3)得到Socket類型的對象並使用輸入輸出流進行通信。

   (4)關閉Socket並釋放有關的資源。

 

客戶端:

   (1)創建Socket類型的對象,並提供服務器的IP地址和端口號。

   (2)使用輸入輸出流進行通信。

   (3)關閉Socket並釋放有關的資源。

2.3 相關類和方法的解析

(1)ServerSocket類

   java.net.ServerSocket類用於描述服務器套接字。

   ServerSocket(int port) - 根據參數指定的端口號來創建對象並綁定。

   Socket accept() - 監聽並接收客戶端的連接請求,若無客戶端連接則進入等待狀態。

   void close() - 用於關閉套接字。

 

(2)Socket類

   java.net.Socket類用於描述客戶端套接字。套接字是兩臺機器間通信的端點。

   Socket(String host, int port) - 根據參數指定的IP地址和端口號創建對象。

   InputStream getInputStream() - 用於獲取當前套接字的輸入流。

   OutputStream getOutputStream() - 用於獲取當前套接字的輸出流。

void close() - 用於關閉套接字。

  

 

3.tcp協議和udp協議的比較(筆試題)

(a)tcp協議

   tcp協議 - 傳輸控制協議,是一種面向連接的協議,類似於打電話。

           - 建立連接=> 進行通信  => 斷開連接

           - 在通信的整個過程中全程保持連接

           - 保證了數據傳遞的可靠性和有序性   

           - 是一種全雙工的字節流通信方式

           - 服務器壓力比較大,資源消耗比較多,而且數據傳遞的效率相對比較低。

 

(b)udp協議

   udp協議 - 用戶數據報協議,是一種非面向連接的協議,類似於寫信。

           - 在通信的整個過程中不需要保持連接。

           - 不保證數據傳遞的可靠性和有序性

           - 是一種全雙工的數據報通信方式

           - 服務器壓力比較小,資源消耗比較少,但數據傳遞的效率相對比較高。

4.基於udp協議的編程模型(重點)

4.1 編程模型

主機A(接收方):

   (1)創建DatagramSocket類型的對象,並與參數指定的端口綁定。

   (2)創建DatagramPacket類型的對象,等待接收數據。

   (3)調用receive()方法來接收數據。

   (4)關閉Socket並釋放有關的資源。

 

主機B(發送方): 

   (1)創建DatagramSocket類型的對象。

   (2)創建DatagramPacket類型的對象,並提供接收方的IP地址和端口號。

   (3)調用send()方法來發送數據。

   (4)關閉Socket並釋放有關的資源。

4.2 相關類和方法的解析

(1)DatagramSocket類

   java.net.DatagramSocket類用於描述發送或接收數據報的套接字,也就是包裹投遞/接收點

   DatagramSocket() - 使用無參的形式構造對象。

   DatagramSocket(int port) - 根據參數指定的端口號來構造對象。

   void receive(DatagramPacket p) - 用於接收數據並存放到參數指定的包裹中。

   void send(DatagramPacket p) - 用於將參數指定的包裹發送出去。

   void close() - 關閉套接字並釋放有關的資源。

 

(2)DatagramPacket類

   java.net.DatagramPacket類用於描述數據報信息的。

   DatagramPacket(byte[] buf, int length)

        - 用於構造一個能接收長度爲length的數據包,將數據存放在buf中。

   DatagramPacket(byte[] buf, int length,InetAddress address, int port)

        - 用於構造一個將長度爲length的數據報,發送給主機address上的port端口。

   InetAddress getAddress() - 用於獲取發送方/接收方的IP地址信息。

   int getPort() - 用於獲取發送方/接收方的端口號信息。

   int getLength() - 用於獲取發送/接收的數據長度。

 

(3)InetAddress類

   java.net.InetAddress類用於描述互聯網協議地址,也就是IP地址信息。

   static InetAddress getLocalHost() - 用於獲取本地主機的地址信息。

   static InetAddress getByName(String host) - 用於根據主機名來獲取地址信息。

   String getHostName() - 用於獲取主機名信息並返回。

   String getHostAddress() - 用於獲取ip地址信息並返回。

 

 

 

 

 

 

 

 

第二十一天  反射

示例代碼:

D:\兄弟連視頻day21\code\

1.基本概念

如:

   Person p = new Person();   - 在運行階段只能創建Person類型的對象

   p.show();                  - 在運行階段只能調用show()方法  

 

   反射本質上就是一種實現動態編程的機制,也就是說在運行階段才能確定創建何種類型的對象以及調用何種方法的機制,具體的類型和方法由實參決定。

   目前主流的框架技術底層都是採用反射機制實現的。

 

2 Class類  

2.1基本概念

   Class類的實例表示正在運行的Java應用程序中的類和接口,也就是代表一種數據類型。

   Class類沒有公共構造方法,Class類的實例是在類加載的過程中由Java虛擬機和類加載器自動構造的。

2.2獲取Class類實例/對象的主要方式

   a.使用數據類型.class的方式來獲取對應的Class對象。

   b.使用對象.getClass()方法的調用來獲取對應的Class對象。

   c.使用包裝類.TYPE的方式可以獲取對應基本類型的Class對象。

   d.使用Class.forName()的方式來獲取參數指定類型的Class對象。 

基本數據類型:a和c  引用數據類型:a和b和d

2.3常用的方法

T - 由此 Class 對象建模的類的類型(要實例化的對象類型)

   static Class<?> forName(StringclassName) - 用於獲取參數指定類型的Class對象。

   T newInstance() - 使用當前正在調用對象所代表的類來構造新對象。

 - 若當前正在調用對象代表String類,調用此方法就相當於newString()來構造對象。

  - 若當前正在調用對象代表Person類,調用此方法就相當於new Person()來構造對象。

   Constructor<T>getConstructor(Class<?>... parameterTypes)

      - 用於獲取當前正在調用對象所代表的類中參數指定的單個公共構造方法並返回。

   Constructor<?>[] getConstructors()

      - 用於獲取當前正在調用對象所代表的類中所有的公共構造方法並返回。

   Field getDeclaredField(String name)

      - 用於獲取當前正在調用對象所代表的類中參數指定的單個成員變量並返回。

   Field[] getDeclaredFields()

      - 用於獲取當前正在調用對象所代表的類中所有的成員變量並返回。

   Method getMethod(String name,Class<?>... parameterTypes)

      - 用於獲取當前正在調用對象所代表的類中參數指定的單個公共成員方法並返回。

   Method[] getMethods()

      - 用於獲取當前正在調用對象所代表的類中所有的公共成員方法並返回。

3. Constructor類

3.1基本概念

   java.lang.reflect.Constructor<T>類用於描述獲取到的單個構造方法。

3.2常用的方法

   T newInstance(Object... initargs)     

- 用於當前正在調用對象所代表的構造方法來構造新實例,參數進行新實例初始化工作

參數(Object...initargs):  其中…代表可變長參數, 

initargs- 將作爲變量傳遞給構造方法調用的對象數組;基本類型的值被包裝在適當類型的包裝器對象(如 Float 中的 float)中。

例如: (Object... initargs)就是  ("zhangfei",30)

Class c1 =Class.forName("xdl.day21.Person");//獲得class

Constructor ct =c1.getConstructor(String.class, int.class);//獲得Constructor類ct

System.out.println(ct.newInstance("zhangfei", 30)); //ct構造新實例

 

 

4 Field類

4.1基本概念

   java.lang.reflect.Field類用於描述獲取到的單個成員變量。

 

4.2常用的方法  

   Object get(Object obj)

      - 用於獲取對象obj中當前正在調用對象所代表成員變量的數值並返回。

      - 若參數傳入Person類型的p對象,當前正在調用的對象代表成員變量name時,

        調用該方法表示返回p.name的數值。

   void set(Object obj, Object value)

      - 用於將obj對象中當前正在調用對象所代表成員變量的數值修改爲value。

      - 若參數傳入Person類型的p對象,當前正在調用的對象代表成員變量name時,

        調用該方法則表示p.name= value的效果。

   void setAccessible(boolean flag)

      - 用於設置是否進行Java語言的訪問檢查,若給true則表示取消檢查。

5 Method類

5.1基本概念

   java.lang.reflect.Method類用於描述獲取到的單個成員方法。

5.2常用的方法

   Object invoke(Object obj, Object... args)

      - 用於使用obj對象調用當前正在調用對象所代表的成員方法,實參傳遞args並返回。

      - 若參數傳入Person類型的p對象,當前正在調用的對象代表成員方法getName()時,調用該方法則表示p.getName(args)的效果。

 

6. JavaBean的概念

  JavaBean本質上就是一種習慣性的編程規範,並不是明確的編程規則/語法要求,具體如下:

     (1)要求遵循JavaBean規範的類必須在一個包中;

     (2)要求遵循JavaBean規範的類必須有無參的構造方法;

     (3)要求遵循JavaBean規範的類必須私有化成員變量;

     (4)要求遵循JavaBean規範的類必須提供公有的get和set成員方法;

     (5)要求遵循JavaBean規範的類支持序列化操作;

 

 

 

 

 

 

 

第二十一、二十二天  設計原則、模式

示例代碼:

D:\兄弟連視頻day21\code\

1. 設計原則

1.1 項目/軟件開發的流程

    需求分析文檔=> 概要設計文檔 => 詳細設計文檔 => 編碼和測試=> 安裝和調試

=>維護和升級

1.2 常用的設計原則

http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html

(1)開閉原則(Open Close Principle  OCP)

- 對擴展開放,對修改關閉。

                   - 爲了保證程序的可維護性和複用性更高,儘量避免錯誤的發生。

                   - 任何軟件都是bug(臭蟲、漏洞)的。

如:

   public class Person{                 

      private String name;

      ... ... 

   }  

 

   public class SubPerson extends Person{

      private int age;

   }

 

   (2)里氏代換原則(LiskovSubstitution Principle  LSP)

 - 任何父類可以出現的地方,子類一定可以出現。

  - 子類 is a 父類,體現在繼承和多態方面。

如:

   public class TestShape{

       public void draw(Shape s){

           s.show();

       }

   }

  

   TestShape ts = new TestShape();

   ts.draw(new Circle(1, 2, 3));

  

  (3) 依賴倒轉原則(DependenceInversion Principle  DIP)

- 儘量依賴於抽象類和接口,而不是具體實現類。

- 抽象類和接口對子類具有強制性和規範性。

如:

   public abstract class A{

      void show();

   }

 

   public class B extends A{

      @Override

      void show(){

           ....

      }

   }

 

   (4)接口隔離原則(InterfaceSegregation Principle  ISP)

- 儘量依賴於小接口而不是大接口,避免接口的污染。

如:

   public interface RunAnimal{ 

       public void run();

   }

   public interface FlyAnimal{

       public void fly();

   }

 

 

   public class Dog implements RunAnimal{

       public void run(){  ...}

   }

 

   (5) 迪米特法則(Demeter Principle最少知道原則)(DP)

- 高內聚,低耦合。

       - 內聚就是指一個實體/模塊儘量將該模塊需要具備的所有功能都聚集在內部。

       - 耦合就是指一個實體/模塊儘量少於其他實體/模塊有關聯。

     

  (6)合成複用原則(Composite ReusePrinciple  CRP)

- 儘量使用合成的原則,而少使用繼承。

如:

   public class A{

      public void show(){ ... ...}

   }

 

   public class B{

      A a;

      public B(A a){

         this.a = a;

      }

      public void test(){

          //調用A類中的show()方法

          a.show();

      }

   }

 

2.常用的設計模式

2.1 基本概念

http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html

   設計模式(Designpattern)是一套被反覆使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。

   通俗來說,就是使用在固定場合中的固定套路。

2.2 基本分類

   創建型模式 - 工廠方法模式、抽象工廠模式、單例設計模式、...(要求會寫)

   結構型模式 - 裝飾器模式、代理模式、...(要求看懂)

   行爲型模式 - 模板方法模式、觀察者模式、...(以後講到)     

 

常見算法

示例代碼:

D:\兄弟連視頻day22\code\

1.常用的查找算法(重點)

1.1 線性查找算法(順序查找算法)

(1)算法流程

   a.使用目標元素與樣本數列中的第一個元素起依次進行比較;

   b.若找到與目標元素相等的元素,則表示查找成功;

   c.若目標元素與樣本數列中的所有元素都比較完畢也沒找到相等的元素,則表示查找失敗;

1.2 二分查找算法(折半查找算法)

示例代碼:D:\兄弟連視頻day22\code\TestFind.java

(1)算法流程

   a.假定樣本數列中的元素都是從小到大排列的;

   b.使用目標元素與樣本數列中的中間元素比較大小,若相等則表示查找成功;

   c.若目標元素小於中間元素,則去中間元素的左邊進行查找,重複步驟b;

   d.若目標元素大於中間元素,則去中間元素的右邊進行查找,重複步驟b;

   e.若目標元素與所有該比較元素比較完畢後也沒有相等的元素,則表示查找失敗;

 

2.常用的排序算法(重點)

示例代碼:D:\兄弟連視頻day22\code\TestFind.java

2.1 冒泡排序算法(重中之重)

示例代碼:D:\兄弟連視頻day22\code\TestSort.java

 

(1)算法流程 

   a.比較相鄰位置的兩個元素,若第一個元素比較大則交換兩個元素的位置;

   b.從開始的第一對一直到結尾最後一對,經過這一步最後的元素將是這組元素中的最大值;

   c.重複步驟b持續對越來越少的元素進行兩兩比較,直到處理完畢所有元素爲止;

     (直到任意兩個相鄰位置的元素都無需發生交換爲止)

 

2.2 插入排序算法(熟悉) 

(1)算法流程

  a.從第一個元素起,認定該元素已經有序;

  b.取出下一個元素與左邊的有序數列從右向左依次進行比較;

  c.若取出的元素小於左邊的元素,則將左邊的元素右移;

  d.重複步驟c,直到取出元素大於等於左邊的元素時,則將取出的元素插入到左邊元素的右邊   e.重複步驟b,直到處理完畢所有元素爲止;

 

2.3 選擇排序算法(熟悉)

(1)算法流程

   a.從第一個元素起依次取出,並且假定取出的元素爲這一組元素中的最小值,

     使用min記錄下標;

   b.使用min記錄的元素與後續元素依次比較大小;

   c.若找到了比min記錄的元素還小的元素,則使用min變量重新記錄該元素的下標;

   d.直到min記錄的元素與後續所有元素比較完畢後,交換min記錄的元素與最開始假定的

     元素,經過這一步最前面的元素將是這組元素中的最小值;

   e.重複步驟a,直到處理完畢所有元素爲止;

 

2.4 快速排序算法(重點)

(1)算法流程

   a.找到樣本數列中的中間元素作爲基準值單獨保存起來;

   b.分別使用左右兩邊的元素與基準值比較大小,將所有比基準值小的元素放在基準值

     的左邊,將所有比基準值大和相等的元素放到基準值的右邊,這個過程叫做分組; 

   c.經過這一步,左邊的元素小於基準值,右邊的元素大於等於基準值,但左右兩邊

     的分組內部不一定有序,此時需要對左右兩邊的分組進行再次分組;

   d.直到處理完畢所有元素爲止;

 

 

常見面試題:

1. wait()和sleep()區別:

http://www.cnblogs.com/renhui/p/6069353.html 

解釋:

sleep(有參數)方法是Thread類裏面的,主要的意義就是讓當前線程停止執行,讓出cpu給其他的線程,但是不會釋放對象鎖資源以及監控的狀態,當指定的時間到了之後又會自動恢復運行狀態。

wait()方法是Object類裏面的,主要的意義就是讓線程放棄當前的對象的鎖,進入等待此對象的等待鎖定池,只有針對此對象調動notify方法後本線程才能夠進入對象鎖定池準備獲取對象鎖進入運行狀態。

區別是:

(a)sleep()有參數:毫秒            wait()無參數
(b)sleep()睡眠時,保持對象鎖,仍然佔有該鎖;而wait()睡眠時,釋放對象鎖。
但是wait()和sleep()都可以通過interrupt()方法打斷線程的暫停狀態,從而使線程立刻拋出InterruptedException(但不建議使用該方法)。

2. final, finally,finalize

http://www.cnblogs.com/xiaomoxian/p/5184520.html

 final:關鍵字通常指的是“無法改變的”

final可以修飾變量(必須給賦值且值不能更改)、方法(無法被重寫)和類(無法被繼承)。

finally:關鍵字。對於一些代碼,可能會希望無論try塊中的異常是否拋出,它們都能夠執行。這通常適用於善後(內存回收之外)的工作。

finalize():方法。垃圾回收器準備釋放內存的時候,會先調用finalize()。

      (1).對象不一定會被回收。

      (2).垃圾回收不是析構函數。

      (3).垃圾回收只與內存有關。

     (4).Java GC(GarbageCollection,垃圾收集,垃圾回收)機制和finalize()都是靠不住的,只要JVM還沒有快到耗盡內存的地步,它是不會浪費時間進行垃圾回收的。

3. 修飾詞順序:

[訪問權限] [abstract] [static] [final] [transient] [volatile] [synchronized][native] [strictfp]

4. run方法和start方法

java Thread中,run方法和start方法的區別,下面說法錯誤的是?

這裏需要注意Thread的start()與run()方法:

用start()方法才能真正啓動線程,此時線程會處於就緒狀態,一旦得到時間片,就會調用線程的run()方法進入運行狀態;

而run()方法只是普通的方法,如果直接調用run()方法,則會按照順序執行主線程這一個線程

1.start方法        

用start方法來啓動線程,是真正實現了多線程, 通過調用Thread類的start()方法來啓動一個線程,這時此線程處於就緒(可運行)狀態,並沒有運行,一旦得到cpu時間片,就開始執行run()方法。但要注意的是,此時無需等待run()方法執行完畢,即可繼續執行下面的代碼。所以run()方法並沒有實現多線程。    

2.run方法        

run()方法只是類的一個普通方法而已,如果直接調用Run方法,程序中依然只有主線程這一個線程,其程序執行路徑還是隻有一條,還是要順序執行,還是要等待run方法體執行完畢後纔可繼續執行下面的代碼。

 

5.Collection與Collections的區別? 

java.util.Collection:

1、是一個集合接口。它提供了對集合對象進行基本操作的通用接口方法。

2、Collection接口在Java類庫中有很多具體的實現。比如SET LIST

3、Collection接口的意義是爲各種具體的集合提供了最大化的統一操作方式。

實例: publicinterface Collection<E> extends Iterable<E> {}

       List l1 = newLinkedList();  l1.add(newName("Kael","M"));

java.util.Collections:

1、是一個包裝類。它包含有各種有關集合操作的靜態多態方法。此類不能實例化,就像一個工具類,服務於Java的Collection框架。但是可以被調用。

實例:Collections.sort(l1);

http://blog.csdn.net/hz_lizx/article/details/54909082

6.構造器Constructor是否可被override(覆蓋)?

https://www.cnblogs.com/guweiwei/p/6596542.html

構造器Constructor不能被繼承,因此不能重寫Override,但可以被重載Overload。

Constructor不能被繼承,所以Constructor也就不能被override。每一個類必須有自己的構造函數,負責構造自己這部分的構造。子類不會覆蓋父類的構造函數,相反必須負責在一開始調用父類的構造函數

7.數組有沒有length()這個方法?String有沒有length()這個方法?

 

數組有

## JAVA基礎

標籤(空格分隔): JAVA後端
參考資料:《JAVA核心技術 卷I》
---


### 第一章  JDK安裝、快捷鍵、JAVA語言特點
#####1.1 Java語言的背景
   Java語言誕生於1995年,在編程語言排行榜佔據重要的地位。                  
   Java語言之父是高斯林,以前隸屬於sun公司,現在隸屬於oracle-sun公司(甲骨文)。
#####1.2 Java語言的主要版本
(1)Java SE版本
   - Java Platform, Standard Edition)稱之爲“Java平臺標準版”。
   - 主要用於編寫桌面應用程序。
(2)Java EE版本
   - Java Platform,Enterprise Edition)稱之爲“Java平臺企業版”。   
   - 主要用於編寫具有B/S結構的電子商務網站、門戶網站以及電信計費系統等。
(3)Java ME版本
   - Java Platform,Micro Edition)稱之爲Java 平臺微型版。  
   - 隨着Android系統的普及,該技術已經走向淘汰。

####3.開發環境的搭建和使用
#####3.1 jdk的下載和安裝
(1)jdk的下載
   下載方式一:直接去官網下載 - ww.sun.com/www.oracle.com 
   下載方式二:直接用谷歌/百度/搜狗搜索 jdk1.7 64位 下載和安裝   
(2)jdk的安裝
   若下載的是綠色版,則直接解壓即可。
   若下載的是安裝版,根據提示一步步點擊下一步即可,切記不要有中文路徑。

#####3.2 相關的概念
   javac.exe - Java語言的編譯器,用於將高級源代碼文件翻譯成字節碼文件。
   java.exe  - Java語言的解釋器,用於啓動java虛擬機進行字節碼文件的解釋並執行
   jre - Java運行時環境信息,只要運行java程序就必須安裝jre。
   jdk - Java開發工具包,只要編寫/開發Java語言程序就必須安裝jdk,jdk自帶jre。
   JVM - Java虛擬機,並不是真實存在的主機,作爲java程序和計算機之間的橋樑。
#####3.3 環境變量的概念和配置
(1)基本概念
   環境變量就是指用於存放環境信息並且數值可以改變的量。
   通常情況下若啓動一個可執行文件需要增加路徑纔可以,當把路徑放入環境變量中後,只需要通過可執行文件的名稱就可以啓動該程序。
(2)配置方式
   計算機 => 右鍵,選擇屬性 => 高級系統設置 => 高級 => 環境變量 => 系統變量 => 找到Path變量點擊編輯,將javac.exe所在的路徑信息加入到該變量值的最前面,添加英文版的分號 => 一路點擊確定即可。
   切記Path變量值原來的內容不要改動,以避免帶來災難性的後果!!!
#####3.4 Java程序的開發流程
   (1)新建文本文檔,將默認的xxx.txt重命名爲xxx.java。
   (2)使用記事本的方式打開該文件,並編寫Java代碼保存。
   (3)啓動dos窗口,使用cd命令將路徑切換到xxx.java所在的目錄中。
   (4)使用javac編譯器根據xxx.java生成xxx.class文件。     
   (5)使用java xxx解釋並執行該文件。 
#####3.5 常用的快捷鍵
   ctrl+s  - 保存
   ctrl+a  - 全選
   ctrl+c  - 複製
   ctrl+x  - 剪切
   ctrl+v  - 粘貼
   ctrl+f  - 查找
   ctrl+z  - 撤銷    
   alt+tab - 切換任務窗口
   windows+tab - 切換任務窗口
   windows+d   - 顯示桌面
   windows+e   - 打開計算機的磁盤界面
   windows+l   - 實現鎖屏
   windows+r   - 啓動運行窗口,輸入cmd再回車啓動dos窗口
   ctrl+alt+delete - 啓動任務管理器 
   使用shift鍵可以進行中英文的切換。
#####3.6 常用的dos命令
   d:  - 表示切換到D盤
   cd 目錄名 - 表示切換到指定的目錄中
   cls - 表示清屏
   dir  - 表示查看當前目錄中的所有內容
   cd .. - 表示切換到上一級目錄
#####3.7 Java語言的特點
  (1)Java語言是一門純面向對象的編程語言。
  (2)Java語言具有跨平臺的特性,也就是同一份字節碼文件可以在不同的平臺上執行,
     是因爲有Java虛擬機負責翻譯工作。
  (3)Java語言具有自動垃圾回收機制。

### 第二章   變量和註釋、數據類型及轉換、運算符、編碼

####X.JAVA中堆棧和內存分配(重點)
 - **RAM:RamdomAccessMemory隨機存取存儲器,斷電丟失**

  - 1. 寄存器:最快的存儲區,由編譯器根據需求進行分配,我們在程序中無法控制。
  - 2. 棧:存放基本類型的變量數據和對象的引用以及方法參數,但對象本身不存放在棧中,而是存放在堆(new出來的對象)或者常量池中(字符串常量對象存放在常量池中。)
  - 3. 堆:存放所有new出來的對象。
  - 4. 靜態域:存放靜態成員(static定義的)
  - 5. 常量池:存放字符串常量和基本類型常量(public static final)。
 - **ROM:Read Only Memory只讀存儲器斷電不丟失,用得少** 
  - 6. 非RAM存儲:硬盤(**HDD**是外存儲器不是ROM)等永久存儲空間

[參考鏈接:](https://www.cnblogs.com/happyPawpaw/p/4443323.html)
https://www.cnblogs.com/happyPawpaw/p/4443323.html
#### **X.JAVA中引用、對象和指針 以及C語言中變量、變量名、變量地址、指針、引用**

 - 可以認爲Java中的引用就是指針,是一種限制的指針,不能參與整數運行和指向任意位置的內存,並且不用顯示回收對象。

```Java
Java Code

Person p = new Person(); //創建了一個Person實例,也被稱爲Person對象,這個Person對象被賦給p變量
//將p變量的值賦給p2
Person p2 = p;
```
 - 程序中定義的Person類型的變量實際上是一個引用,它被存放在棧內存裏,指向實際的Person對象;而真正的Person對象則存在在堆(heap)內存中。

**c 中變量、變量名、變量地址、指針、引用:**

 - 變量,就是一個房間,它有編號(地址),他有名字(變量名),他有內容(裏面的人)、

```C語言
變量:存放3的那個內存空間
變量名: a
變量地址:0x12345678
指針: *pi 指針(地址爲值的變量就是指針變量) pi指針名 內容0x12345678
引用: int& 就是引用類型,int& b = a;
       意思就是b是對a引用,也就是b是a的別名、a就是b,b就是a

    int a = 3; // a 是名字,3 是內容,地址可以假設是0x 12345678 (通常就是32位地址)、0x12345678 這個房間裏面住的是一個int。

    int *pi = &a; // pi 是名字,內容就是a的地址,0x12345678; 所以,你懂的,
    *pi = 4; // 就是通過pi,也就是a 的地址,把a的內容改成4了、

    int & b = a; // 同樣的0x12345678 這個房間,剛纔他有個名字a,現在又有個名字b了、
    
    b = 10; // 也就是 a = 10;
    
    a = 100; // 也就是 b = 100;
    
    int& 就是引用類型,int& b = a;
    
    意思就是b是對a 引用,也就是b 是a 的別名、a就是b,b就是a
    
    - pi 的類型int*, pi就是個指針(變量)、好吧,變量的別名,就相當於外號,
```

####1.變量和註釋(重點)
#####1.1 變量(域)的基本概念以及分類
[參考鏈接:](http://blog.chinaunix.net/uid-26434689-id-3328442.html)
http://blog.chinaunix.net/uid-26434689-id-3328442.html

 - 變量(域/field): 
     - 當需要在程序中記錄一個數據內容時,則需要聲明一個變量來保存,變量本質上就是內存條中的一塊區域。
     - 由於記錄的數據內容不同導致所需要的內存空間大小不同,在Java語言使用數據類型加以描述,而使用變量名來描述該內存空間的地址信息。
   
**變量分類**:按照被聲明位置劃分:局部變量、成員變量(也叫“實例變量”、“域”)、 靜態變量(也叫類變量)。

**靜態變量**(也叫類變量)是類中獨立於方法之外的變量,用static 修飾。(static表示“全局的”、“靜態的”,用來修飾成員變量和成員方法,或靜態代碼塊(靜態代碼塊獨立於類成員,jvm加載類時會執行靜態代碼塊,每個代碼塊只執行一次,按順序執行))。
**成員變量**(也叫“實例變量”、“域”)也是類中獨立於方法之外的變量,不過沒有static修飾。
**局部變量**是類的方法中的變量。

```
看下面的僞代碼說明:
public class Variable{ 類名
     static int allClicks=0;//靜態變量也叫類變量
     String str="hello world";//實例變量也叫成員變量
     public void method(){ 方法名
        int i =0;//局部變量
     }
}
```

成員變量也稱爲:“域”,“實例變量”,在實體類或數據類中被稱爲“屬性”或“字段”。當成員變量可以改變時,被稱爲對象的狀態。
常量:用final修飾,值一旦給定就不能修改。const(C++定義常量)在JAVA中不使用但是作爲保留字。
**Java變量和對象的作用域**:
[參考鏈接:](https://www.cnblogs.com/AlanLee/p/6627949.html)
https://www.cnblogs.com/AlanLee/p/6627949.html  

#####1.2 變量的聲明和初始化
   數據類型 變量名 = 初始值;   - 其中=初始值是可以省略的,但分號不可以省略
如:
   int id = 1001; - 推薦使用該方式
   int id;    
注意:C++區分定義(extern)和聲明,JAVA不區分。
#####1.3 使用變量的注意事項
  (1)使用變量之前必須聲明。
  (2)使用變量之前必須指定初始值。
  (3)不允許聲明同名的變量。
  (4)每個變量都擁有自己獨立的作用域(有效的範圍)。
補充:
   在方法體中聲明的變量叫做局部變量,局部變量的作用域爲:聲明開始到方法體結束
#####1.4 標識符(變量名)的命名規則
  (1)必須由字母、數字、下劃線_以及美元$組成,其中數字不能開頭。
     如:id、name、name2等。
  (2)不能使用Java語言中的關鍵字/保留字,也就是Java語言中用來代表特殊含義的單詞
     如:class、public、void、int等
  (3)區分大小寫,長度沒有限制但不宜過長。
     如:day 和 Day代表不同的標識符,不推薦使用。
  (4)儘量使用英文單詞的組合做到見名知意,雖然支持中文,但不推薦使用。
     如:sendMsgToAll、minute、time、length  年齡
#####1.5 常見的編程規範
  (1)儘量使用空格、縮進以及空行來提高代碼的可讀性和層次感。
  (2)當類名由多個單詞組成時,要求每個單詞的首字母都要大寫。
  (3)當變量名由多個單詞組成時,要求從第二個單詞起每個單詞的首字母要大寫。
#####1.6 註釋
   單行註釋 - 從//開始一直到本行的末尾之間的內容都是註釋內容。
   多行註釋 - 從/*開始一直到*/結尾之間的內容都是註釋內容。
   其中多行註釋要求不允許嵌套使用,如:/* /* */ */ 是錯誤的。
   
#####1.7 作用域
[參考鏈接: ](https://www.cnblogs.com/AlanLee/p/6627949.html)  https://www.cnblogs.com/AlanLee/p/6627949.html
   
####2.數據類型(重點)
#####2.1 數據類型的分類
  在Java語言中將數據類型分爲兩大類:基本數據類型 和 引用數據類型。
  其中基本數據類型主要有(8種):
      byte/short/int/long - 用於描述整數數據的類型,如:666。
      float/double        - 用於描述小數數據的類型,如:3.14。
      char                - 用於描述字符數據的類型,如:'a'。
      boolean             - 用於描述真假信息的類型,如:true 和 false。
  其中引用數據類型主要有:
      數組、類、接口、枚舉以及標註(瞭解)。
  
#####2.2 常用的進制(數學、理解基本數據類型)
  日常生活中採用十進制加以描述,逢十進一,權重爲:10^0 10^1 10^2 ...
  計算機中採用二進制加以描述,逢二進一,權重爲:2^0 2^1 2^2 ...   
  八進制和十六進制爲了簡化二進制的表示形式。
  在計算機中採用二進制的最高位(最左邊)來代表符號位,若該位是0則表示非負數,若該位是1則表示負數。
#####2.3 進制之間的轉換(數學、理解基本數據類型)
(1)十進制和二進制之間的轉換(要求每個人掌握)
   a.正十進制轉換爲二進制的方式
     1)除2取餘法,讓十進制整數不斷地除以2取出餘數,直到商爲0將所有餘數逆序排列
     2)拆分法,將十進制整數拆分爲若干個二進制權重的和,若該權重出現則下面寫1,
               若該權重沒有出現則下面寫0(推薦)。
   如:12
       128 64 32 16    8 4 2 1       12 = 8 + 4
          0   0   0    0     1 1 0 0       12轉換爲二進制的結果是:0000 1100   
   b.正二進制轉換爲十進制的方式
     1)加權法,讓二進制的每個數字乘以當前位的權重最後相加。
   如:0000 1100
    0000 1100 => 0*2^7 + 0*2^6 + 0*2^5 + 0*2^4 + 1*2^3 + 1*2^2 + 0*2^1 + 0*2^0
              => 0 + 0 + 0 + 0 + 8 + 4 + 0 + 0
              => 12  
   
   c.負十進制轉換爲二進制的方式
     1)先將該整數的絕對值轉換爲二進制,然後進行按位取反再加1.
   如:-12
       12轉換爲二進制:0000 1100      12的二進制:0000 1100   
       按位取反:      1111 0011     -12的二進制:1111 0100 +
       再加1:          1111 0100     --------------------------    
                                                1 0000 0000(最高位溢出)
   d.負二進制轉換爲十進制的方式
    1)先進行按位取反加1,然後轉換爲十進制整數,最後添加負號
   如:1111 0100
       1111 0100進行按位取反:0000 1011
       加1:                  0000 1100
       轉換爲十進制整數:     12
       最後添加負號:         -12
######2.3.1原碼反碼補碼擴展:
原碼、反碼以及補碼的概念。
http://blog.csdn.net/u011080472/article/details/51280919 
http://blog.csdn.net/liushuijinger/article/details/7429197 
機器數:一個數在計算機中的二進制表示形式, 叫做這個數的機器數。機器數是帶符號的,在計算機用一個數的最高位存放符號, 正數爲0,負數爲1。
真值:將帶符號位的機器數對應的真正數值稱爲機器數的真值。
例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1
原碼:如果機器字長爲n,那麼一個數的原碼就是用一個n位的二進制數,其中最高位爲符號位:正數爲0,負數爲1。剩下的n-1位表示概數的絕對值。
例如: X=+101011 , [X]原= 00101011    X=-101011 , [X]原= 10101011 
位數不夠的用0補全。
PS:正數的原、反、補碼都一樣:0的原碼跟反碼都有兩個,因爲這裏0被分爲+0和-0。
反碼:反碼就是在原碼的基礎上,符號位不變其他位按位取反(就是0變1,1變0)。
補碼:
補碼就是在反碼的基礎上按照正常的加法運算加1。
例如:X=-101011 , [X]原= 10101011 ,[X]反=11010100,[X]補=11010101
PS:0的補碼是唯一的,如果機器字長爲8那麼[0]補=00000000。
 
移碼:
移碼最簡單了,不管正負數,只要將其補碼的符號位取反即可。
例如:X=-101011 , [X]原= 10101011 ,[X]反=11010100,[X]補=11010101,[X]移=01010101


(2)八進制和二進制之間的轉換(熟悉)
   a.二進制轉換爲八進制的方式
     1)將每三位二進制合併爲一位八進制,並使用0作爲前綴代表八進制。
    如:
       010 110  => 026
   b.八進制轉換爲二進制的方式
     1)將每一位八進制拆分爲三位二進制,並使用0b作爲前綴代表二進制(jdk1.7)。
    如:
       075 => 0b111 101 

(3)十六進制和二進制之間的轉換(熟悉)
   a.二進制轉換爲十六進制的方式
    1)將每四位二進制合併爲一位十六進制,並使用0x作爲前綴代表十六進制。
    如:
       1010 0011 => 0xa3(十六進制中使用a~f來代表10 ~ 15).
   b.十六進制轉換爲二進制的方式
    1)將每一位十六進制拆分爲四位二進制,並使用0b作爲前綴代表二進制。
    如:
       0xab => 0b1010 1011
#####2.4 單個字節表示的整數範圍(重中之重)
    在計算機中單個字節表示八位二進制位,最高位(最左邊)的二進制位代表符號位,若該位是0則表示非負數,若該位是1則表示負數,具體如下:
    非負數的表示範圍是:0000 0000 ~ 0111 1111  => 0 ~ 127 => 0 ~ 2^7-1  
其中0000 0000轉換爲十進制整數就是0;
其中0111 1111轉換爲十進制整數:64 + 32 + 16 + 8 + 4 + 2 + 1 = 127;
    負數的表示範圍是:  1000 0000 ~ 1111 1111 => -128 ~ -1 => -2^7 ~ -2^0
其中1000 0000轉換爲十進制整數:
    按位取反:0111 1111  => 加1:1000 0000 => 128  => -128;
其中1111 1111轉換爲十進制整數:
    按位取反:0000 0000  => 加1:0000 0001 => 1    => -1;

綜上所述:
    對於單個字節的二進制來說,所能表示的十進制整數範圍是:-128 ~ 127.
                                                          -2^7 ~ 2^7-1.
#####2.5 整數類型
   在Java語言中用於描述整數的類型有:byte/short/int/long,推薦使用int類型。
   其中byte類型在內存空間佔1個字節的大小,表示範圍是:-128 ~ 127(-2^7 ~ 2^7-1)
   其中short類型在內存空間佔2個字節的大小,表示範圍是:-2^15 ~ 2^15-1。
                                                       (-32768 ~ 32767)。
   其中int類型在內存空間佔4個字節的大小,表示範圍是:-2^31 ~ 2^31-1.
                                                       (正負二十一億之間)
   其中long類型在內存空間佔8個字節的大小,表示範圍是:-2^63 ~ 2^63-1.
                                                       (比int類型範圍還大)
   在程序中直接寫出的整數數值叫做 直接量/常量/字面值,默認爲int類型,如:666,若希望表示long類型的直接量,則需要在直接量的後面加上L或者l,推薦使用L。

擴展:
   若希望表示比long類型範圍還大的整數,則藉助java.math.BigInteger類。
#####2.6 浮點類型
   在Java語言中用於描述小數數據的類型有:float/double,推薦使用double類型。
   其中float類型在內存空間中佔4個字節的大小,叫做單精度浮點數。
   其中double類型在內存空間中佔8個字節的大小,叫做雙精度浮點數。
   在程序中直接寫入的小數數據叫做直接量/常量/字面值,默認爲double類型,若希望表示float類型的直接量,則需要在直接量的後面增加F或者f。

Float double擴展:
   float類型和double類型是不能實現精確計算的,爲了得到精確的結果需要藉助java.math.BigDecimal類加以描述。
   有餘力的同學課下可以查詢float和double存儲結構。
http://blog.csdn.net/zq602316498/article/details/41148063
float:4字節 32位
        1bit(符號位) 8bits(指數位) 23bits(尾數位)     a = r^3其中r爲底數 3是指數 
double:8字節 64位
        1bit(符號位) 11bits(指數位) 52bits(尾數位)

#####2.7 布爾類型
  在Java語言中用於描述真假信息的類型有:boolean,該類型的數值:true 和 false.
  由於布爾類型只有兩個數值因此使用一個二進位制就足夠描述,但通常認爲是1個字節
#####2.8 字符類型(熟悉)
  在Java語言中用於描述字符信息的類型有:char,在內存空間中佔2個字節的大小,通常用於描述單個字符,如:'a' '1' '中'等。
  在現實生活中使用更多的是多個字符組成的字符串,使用String類型加以描述,並且使用雙引號括起來,如:"xiaomage"。
  要求大家記住的ASCII數值有:
       'A' - 65   'a' - 97   '0' - 48   空格 - 32   換行 - 10
  要求大家記住的轉義字符有:
       \" - "   \' - '   \\  - \   \t - tab鍵  \n - 換行符 

####3.基本數據類型之間的轉換(熟悉)
複習:
   Java語言基本數據類型有:byte、short、int、long、float、double、char boolean    byte b = 10;  - 10叫直接量,默認是int類型

   基本數據類型之間的轉換分爲:自動類型轉換 和 強制類型轉換。
   其中自動類型轉換主要指:小範圍向大範圍之間的轉換。
   其中強制類型轉換主要指:大範圍向小範圍之間的轉換。
       語法格式:目標類型 變量名 = (目標類型)源類型變量名;
              如:byte b1 = (byte)s1;

經驗:
   當程序中出現大範圍向小範圍轉換的代碼時編譯報錯,若希望編譯能夠通過則需要按照上述方式進行強轉,但強轉帶來的結果會改變原始數據,因此能不用則不用。
double sum = 0.0;     int i = 1;//sum如果聲明爲double則報錯損失精度
        for(  i  =  1;  i  <=  num;  i++  ){
        System.out.println("數字:"+i);
        sum = sum + 1.0/i;(推薦) //sum =  sum + ((double)1)/i;;//也可以
        }
####4.運算符(重點)
#####4.1 算數運算符
  + 表示加法運算符   - 表示減法運算符    * 表示乘法運算符    /  表示除法運算符
  % 表示取模/取餘運算符
  
注意事項:
  (1)兩個整數相除時結果取整數部分,丟棄小數部分。
  (2)若希望結果是浮點數據,則需要進行處理,方式如下:
      a.將其中一個操作數強轉爲double類型,則結果不會丟棄小數部分。
      b.將其中一個操作數乘以1.0提升爲double類型,則結果不會丟失小數部分(推薦)
  (3)0不能做除數,0.0可以做除數,但結果是無窮大,因此以後編程不要使用0和0.0
     作爲除數。

經驗:
  運算符+ 既可以當做算數運算符處理,也可以當做字符串連接符處理,區分方式如下:
     a.當運算符+兩側的操作數都不是字符串時,則看做算數運算符處理。
     b.當運算符+兩側的操作數中只要有一個是字符串時,則看做字符串連接符處理。
    System.out.println(100+200+"300");//輸出300300
    System.out.println("300"+100+200); //輸出300200100
#####4.2 比較/關係運算符
   > 表示是否大於  >= 表示是否大於等於  < 表示是否小於  <= 表示是否小於等於
   == 表示是否等於  != 表示是否不等於

   關係運算符參與的表達式結果爲boolean類型,只有兩種:true 和 false 
#####4.3 自增減運算符
   + 表示加法運算符   ++ 表示自增運算符,也就是讓變量自己的數值加1.
   - 表示減法運算符   -- 表示自減運算符,也就是讓變量自己的數值減1.

經驗:
   在以後的編程中儘量單獨使用自增減運算符,不要和其他運算符搭配使用,以避免錯誤的發生。如:ia++;
#####4.4 邏輯運算符
   && - 表示邏輯與運算符,相當於"並且",同真爲真,一假爲假。
   || - 表示邏輯或運算符,相當於"或者",一真爲真,同假爲假。
   !  - 表示邏輯非運算符,相當於"取反",真爲假,假爲真。
   
短路特性:
    對於邏輯與運算符來說,若第一個條件爲假則整個表達式的條件一定爲假,此時第二個條件可以跳過不執行。
    對於邏輯或運算符來說,若第一個條件爲真則整個表達式的條件一定爲真,此時第二個條件可以跳過不執行。  
#####4.5 條件/三目運算符
   ?: - 條件/三目運算符
   條件表達式? 表達式1: 表達式2; 
       - 判斷條件條件表達式是否成立
            => 若成立,則執行表達式1;
            => 若不成立,則執行表達式2;
#####4.6 賦值運算符
 (1)簡單賦值
    =  表示將=右邊的數據賦值給=左邊的變量,去覆蓋該變量原來的數值。
如:
    ia = 10;
    ia = ib = ic = 20;   =>  ia、ib、ic最終的結果都是20.

筆試題:
   分析以下四種形式的區別?
       ia = 10;  - 將數據10賦值給ia,覆蓋ia原來的數值。
       10 = ia;  - 編譯報錯
       ia == 10; - 判斷ia是否等於10
       10 == ia; - 判斷10是否等於ia

(2)複合賦值    
   +=  -=  *=  /=  ... ...
如:
   ia = ia + 10;(推薦,可讀性更強)   
   =>  ia += 10;    

筆試題:
   分析以下兩種形式的區別?
   byte b1 = 5;  b1 += 2;     //ok
   byte b1 = 5;  b1 = b1 + 2; //error
解析:
   b1 += 2 真正等價的是:b1 = (byte)(b1 + 2);   

#####4.7 移位運算符(瞭解)
   <<   表示左移運算符,也就是按照二進制位向左移動,右邊添加0.
   >>   表示右移運算符,也就是按照二進制位向右移動,左邊添加符號位.
   >>>  表示無符號右移運算符,也就是按照二進制位向右移動,左邊添加0.

#####4.8 位運算符(瞭解)
   &   表示按位與運算符,同1爲1,一0爲0.(1看做真,0看做假)
   |   表示按位或運算符,同0爲0,一1爲1.
   ~   表示按位取反運算符,1爲0,0爲1.
   ^   表示按位異或運算符,相同爲0,不同爲1.

#####4.9 運算符的優先級
   (1)()的優先級極高。
   (2) =的優先級極低。
   (3) * / % 的優先級高於 + -,同級的運算符(從左到右)哪個在前先算哪個。
####5.[編碼](https://blog.csdn.net/longintchar/article/details/51079340 )

##### - ASCII碼
     - 所有的英文字母都對應到一個數字編碼,這就是ASCII碼(American Standard Code for Information Interchange)。ASCII碼是很久很久以前(1968年)制定的。它只使用了一個8位字節中的低7位,總共是127個編碼位。

##### - Unicode:編碼標準
     - 十六位Unicode字符集,可以表示 2^16=65536個數目。而UTF-8,UTF-16,UTF-32是UNICODE在計算機中的不同存儲方式。

##### - 碼點(code point):
     - 一個編碼表中的某個字符對應的代碼值。

##### - 字符集(charset):計算機可以表示的字符組成了一個集合。
     - 常見的字符集有Unicode,ASCII等。

##### - 字符集編碼(Character encoding):
     - 而encoding則是一種映射工具,它將自然語言的字符和字符集進行配對。常見的字符集編碼有UTF-8,GBK,Big5等。

### 第三章  程序結構
三種程序結構:順序、分支、循環結構
 
####1.分支結構
#####1.1基本概念
   當需要進行條件的判斷和選擇時,需要使用分支結構來進行處理。
#####1.2 if分支結構
(1)語法格式
   if(條件表達式){
      語句塊1;
   }   
   語句塊2;

(2)執行流程
   判斷條件表達式是否成立 
       => 若成立,則執行語句塊1;  => 執行語句塊2;
       => 若不成立,則執行語句塊2;
1.2.1 if-else分支結構
(1)語法格式
   if(條件表達式){
      語句塊1;
   }
   else{
      語句塊2; 
   }
   語句塊3;

(2)執行流程
   判斷條件表達式是否成立
       => 若成立,則執行語句塊1;  => 執行語句塊3;
       => 若不成立,則執行語句塊2; => 執行語句塊3;
1.2.2 if-else if-else分支結構
(1)語法格式
   if(條件表達式1){
      語句塊1;
   }
   else if(條件表達式2){
      語句塊2;
   }
   ... ...
   else{
      語句塊3;
   }
   語句塊4;
 
(2)執行流程
   判斷條件表達式1是否成立 
       => 若成立,則執行語句塊1 => 執行語句塊4;
       => 若不成立,則判斷條件表達式2是否成立
               => 若成立,則執行語句塊2 => 執行語句塊4;
               => 若不成立,則執行語句塊3 => 執行語句塊4;
#####1.3 switch-case結構(熟悉)
(1)語法結構
```
   switch(變量/表達式){// switch(byte、short、char、int、枚舉、JAVA SE 7開始支持 String )

       case 字面值1: 語句塊1; break;
       case 字面值2: 語句塊2; break;
       ... ...
       default:語句塊3;  
   }
   語句塊4;
```
**警告:** 若不加break,會從滿足case條件的語句一直執行,直到default語句執行完,退出循環。
(2)執行流程
   計算變量/表達式的結果 
      => 判斷結果是否等於字面值1  
         => 若成立,則執行語句塊1 => 執行break => 執行語句塊4;
         => 若不成立,則判斷是否等於字面值2
               => 若成立,則執行語句塊2 => 執行break => 執行語句塊4;
               => 若不成立,則執行語句塊3 => 執行語句塊4;

(3)注意事項
   switch()中支持的類型:byte、short、char、int,從jdk1.5開始支持枚舉類型,從jdk1.7開始支持String類型。
 
####2.循環結構(重中之重)
#####2.1 基本概念
   當需要重複做一件事時,可以使用循環結構來解決。
#####2.2 for循環 空語句
(1)語法結構
   for(表達式1; 條件表達式2; 表達式3){
      語句塊1;(循環體)
   }   
   語句塊2;

(2)執行流程
   執行表達式1 => 判斷條件表達式2是否成立
       => 若成立,則執行語句塊1  => 執行表達式3 => 判斷條件表達式2是否成立
       => 若不成立,則執行語句塊2
(3)for(;;)格式:1.必須要有兩個分號”;”2.裏面的條件表達式能計算出正確結果就行
(4)空語句:for(;;); 等同於for(;;){;}括號裏面只有“;”的語句,啥也不執行。
#####2.3 break和continue關鍵字
實例:TestForBreakContinue.java  
**break** 關鍵字用在循環和 if else 中表示跳出當前循環,用在switch-case結構表示跳出當前結構。
**break 嵌套**:break 用於退出所在循環體。如果退出外層循環體,需要用標號的方式。
```
    flag:
    while(){
        for(;;){
            if() break;//跳出for當前循環
            if() break flag;//跳出flag標記 while循環
        }
    }
```
**continue**
```
    Scanner sc = new Scanner(System.in);
    while (sum < goal) {
        System.out.println("小夥子輸入一個膜法值:");
        int num = sc.nextInt();
        if (n < 0)    continue;//如果n<0,跳過 sum += n;立刻跳回while循環首部
        sum += n;
    }
        
    Scanner sc = new Scanner(System.in);
    for (int i = 0; i < 10; i++) {
        System.out.println("小夥子輸入一個膜法值:");
        int num = sc.nextInt();
        if (n < 0) continue;//如果 n<0 跳回i++
        sum += n;
    }
```
#####2.4 特殊的循環
  for(;;) - 該循環中沒有明確的循環條件,這樣的循環叫做無限循環,俗稱"死循環"。
  該循環通常情況下與break關鍵字搭配使用
```
    for(;;){
        if(i>3) break;
        i++;                    
    }//i>4的時候跳出循環
```
#####2.5 for循環嵌套
1)語法格式
```
   for(表達式1; 條件表達式2; 表達式3){
    //表達式1中變量作用域爲For循環整個循環體
      for(表達式4; 條件表達式5; 表達式6){
          語句塊7(循環體);
      }
   }
```
(2)執行流程   
   執行表達式1 => 判斷條件表達式2是否成立
      => 若成立,則執行表達式4 => 判斷條件表達式5是否成立 
            => 若成立,則執行語句塊7 => 執行表達式6 => 判斷條件表達式5是否成立
            => 若不成立,則執行表達式3 => 判斷條件表達式2是否成立
     => 若不成立,則結束整個循環
######2.5.1警告:
```
for(表達式1; 條件表達式2; 表達式3); //表達式1中變量作用域爲For循環整個循環體

    for (int i = 0; i != 1; i += 0.1) {
        System.out.printf("I的值:%4.2f", i);//編譯不通過
// java.util.IllegalFormatConversionException: f != java.lang.Integer
    }
    
    for (double i = 0; i != 1; i += 0.1) {//死循環  double精度有誤差
        System.out.printf("I的值:%4.2f ", i);
    }
```
######2.5.2 for each:
```
語句格式:for( variable : collection ) statement
variable:用於暫存集合collection中的每一個元素。
collection:必須是數組或者實現Iterable接口的類對象(ArrayList等)
```
#####2.6 while循環
(1)語法格式
   while(條件表達式){
      循環體;
   } 
   語句塊;

(2)執行流程
   判斷條件表達式是否成立
      => 若成立,則執行循環體 => 判斷條件表達式是否成立
      => 若不成立,則執行語句塊;

(3)注意事項
   a.while循環和for循環是完全可以互換的。
   b.while循環通常使用在明確循環條件但不明確循環次數的場合中。
     for循環通常使用在明確循環次數/範圍的場合中。
   c.while(true)等價於for(;;),都表示無限循環,俗稱"死循環"。

(4)while(boolean)格式:1.()內可以使TRUE或者FALSE  2.可以是條件表達式,但是表達式結果只能是布爾類型。
#####2.7 do-while循環(熟悉)
(1)語法格式
   do{
      循環體;
   }while(條件表達式);//注意分號
   語句塊;

(2)執行流程
   執行循環體 => 判斷條件表達式是否成立
       => 若成立,則執行循環體 => 判斷條件表達式是否成立
       => 若不成立,則執行語句塊

(3)注意事項
   a.do-while循環通常使用在至少執行一次循環體的場合中。
   b.do-while循環的條件表達式後面有分號,其他循環沒有。

### 第四章  數組
####1.一維數組
#####1.1 基本概念
![1.jpg-142kB][1]
   變量本質上就是一塊內存空間,用於記錄單個數據,而且內容可以改變。
   一維數組本質上就是一段連續的內存空間,用於記錄多個數據類型相同的數據,內容可以發生改變,換句話說,一維數組就是一個容器。
   數組名 - 主要指數組的名稱,用於記錄該連續內存空間的首地址信息。
   數組元素 - 主要指存放在數組中的數據內容。
   數組長度 - 主要指數組中存放的元素個數,通常使用 數組名.length來獲取。
   數組下標 - 主要指數組中元素的編號,從0開始一直到 數組名.length-1。

#####1.2 數組的聲明
(1)數組聲明的語法格式
```
   數據類型[] 數組名稱 = new 數據類型[數組的長度]; - 動態方式
如:
   int[] arr = new int[5]; - 聲明一個長度爲5,元素類型爲int的一維數組
   int num = 5;            - 聲明一個初始值爲5的變量
   
   int arr[] = new int[5]; - 不推薦使用該方式
```
(2)注意事項
   a.只有數組在聲明的時候,[]中的數字代表數組的長度,否則一律代表下標。
   b.當創建數組沒有指定初始值時,採用默認初始化(參考ppt)。
 
(3)數組元素的初始化
```
   數據類型[] 數組名稱 = {初始值1,初始值2, ...}; - 靜態方式
如:
   int[] arr = {10, 20, 30, 40, 50}; - 聲明一個長度爲5元素類型爲int的數組
   arr[0] = 10;
   arr[1] = 20;
   arr[2] = 30;
   arr[3] = 40;
   arr[4] = 50;
```
注意:基本類型的數組(數據元素爲基本類型)創建後。元素類型爲:BYTE、SHORT、CHAR、INT、LONG爲0;FLOAT和DOUBLE爲0.0;BOOLEAN爲False。
#####1.3 數組的聲明 size()  length length()方法:
1.length屬性是針對Java中的數組來說的,要求數組的長度可以用其length屬性;
2.length()方法是針對字符串來說的,要求一個字符串的長度就要用到它的length()方法;
3.java中的size()方法是針對泛型集合說的,如果想看這個泛型有多少個元素,就調用此方法來查看!

####2.二維數組(熟悉)
#####2.1 基本概念
   一維數組本質上就是一段連續的內存空間,用於記錄多個類型相同的數據內容。
   二維數組本質上就是由一維數組組成的數組,也就是說二維數組中的每個元素都是一個一維數組。

#####2.2 二維數組的聲明
(1)語法格式
**多維數組(數組的數組),本質上也是一維數組。**
   數據類型[][] 數組名稱 = new 數據類型[行數][列數];
如:
   int[][] arr = new int[2][2]; - 聲明一個具有2行5列存放int類型元素的二維數組
   其中行下標的範圍是:0 ~ 1;
   其中列下標的範圍是:0 ~ 4;

   arr代表什麼?  arr[0]代表什麼? arr[0][0]代表什麼?
解析:
   arr代表二維數組的名稱,用於記錄該二維數組的首地址。
   arr[0]代表二維數組的第一行,也就是一個一維數組。
   arr[0][0]代表二維數組中的第一行第一列,也就是第一個元素值。
   int[][]a= new int a[i][j];i代表行,j代表列
   arr.length=i;代表二維數組的長度,也就是二維數組的行數。
   arr[0].length=j;代表第一行的列數,也就是一維數組的長度。

(2)二維數組的初始化
   數據類型[][] 數組名稱 = {{元素值1,元素值2,...},{元素值3,元素值4,...},...};
如:
   int[][] arr = {{1,2,3},{4,5,6}}; - 聲明一個2行3列的二維數組
   其中行下標就是:0 ~ 1;
   其中列下標就是:0 ~ 2;
#####2.3 數組的拷貝和二維數組
```
public class CopyArray {

    public static void main(String[] args) {
        int[] arr1 = { 2, 3, 5, 7, 11, 12 };
        System.out.println(Arrays.toString(arr1));
        // [2, 3, 5, 7, 11, 12]

        int[] cpArr = arr1;
        cpArr[5] = 99;
        // 兩個變量arr1和cpArr引用同一個數組
        System.out.println(Arrays.toString(arr1));
        // [2, 3, 5, 7, 11, 99]
        System.out.println(Arrays.toString(cpArr));
        // [2, 3, 5, 7, 11, 99]

        int[] cpArr2 = Arrays.copyOf(arr1, 2 * arr1.length);
        System.out.println(Arrays.toString(cpArr2));
        // 長度過大補0 過小從前截取
        // [2, 3, 5, 7, 11, 99, 0, 0, 0, 0, 0, 0]
    }
    
}

```
```
package com.study.array;

/**
 * 打印
  10 %        11 %        12 %        13 %        14 %        15 %
10000.00    10000.00    10000.00    10000.00    10000.00    10000.00
11000.00    11100.00    11200.00    11300.00    11400.00    11500.00
12100.00    12321.00    12544.00    12769.00    12996.00    13225.00
13310.00    13676.31    14049.28    14428.97    14815.44    15208.75
14641.00    15180.70    15735.19    16304.74    16889.60    17490.06
16105.10    16850.58    17623.42    18424.35    19254.15    20113.57
17715.61    18704.15    19738.23    20819.52    21949.73    23130.61
19487.17    20761.60    22106.81    23526.05    25022.69    26600.20
21435.89    23045.38    24759.63    26584.44    28525.86    30590.23
23579.48    25580.37    27730.79    30040.42    32519.49    35178.76
 * @ClassName: MultidimensionalArray
 * @Description: TODO(多維數組)
 * @author Administrator
 * @date 2018年5月24日 下午7:08:09
 *
 */
public class MultidimensionalArray {

    public static void main(String[] args) {
        final double STARTRATE = 10;
        final int NRATES = 6;// 匯率
        final int NYEARS = 10;// 年份

        // 數組用於存放10%...15%不同的匯率
        double[] interestRate = new double[NRATES];
        for (int i = 0; i < interestRate.length; i++) {
            interestRate[i] = (STARTRATE + i) / 100;
        }

        // 定義二維數組balances 用於存儲餘額
        double[][] balances = new double[NYEARS][NRATES];

        // 設置第一行餘額balances[0][i]全部爲10000
        for (int i = 0; i < balances[0].length; i++) {
//balances.length:10 二維數組長度 10 行數
//balances[0].length:6 一維數組長度 6 列數
            balances[0][i] = 10000;
        }

        // 兩層for循環嵌套 計算未來幾年利息interest
        for (int i = 1; i < balances.length; i++) {// 10 列數 從第2行開始
            for (int j = 0; j < balances[0].length; j++) {// 6 行數 從第1列開始
                // 計算上一年餘額
                double oldBalance = balances[i - 1][j];
                // 計算稅率
                double interest = interestRate[j];

                balances[i][j] = oldBalance * (1 + interest);
                // System.out.printf("%10.2f",balances[i][j]);
            }
        }
        // 打印一行利息比率
        for (int i = 0; i < interestRate.length; i++) {
            System.out.printf("%10.0f %%", 100 * interestRate[i]);
        }
        
        System.out.println();
        
        // 嵌套兩層 for each打印餘額表格
        for (double[] ds : balances) {
            for (double d : ds) {
                System.out.printf("  %10.2f", d);
            }
            System.out.println();
        }
    }

}

```

### 第五章  類和對象
####1.對象概念
1.1 什麼是對象?
   萬物皆對象。

1.2 什麼是面向對象?
   面向對象就是指以特徵和行爲的觀點去分析現實世界中事物的方式。

1.3 什麼是面向對象編程OOP?
面向對象編程(Object Oriented Programming--OOP)就是指先用面向對象的觀點進行分析,再採用一門面向對象的編程語言進行翻譯/表達的過程。
   其中C語言是一門面向過程的編程語言。
   其中C++語言是一門既面向過程又面向對象的編程語言。
   其中Java語言是一門純面向對象的編程語言。

1.4 爲什麼需要面向對象編程?
   面向對象編程是軟件產業化發展的需求。

1.5 如何學好面向對象編程?
   深刻理解面向對象的三大特徵:封裝、繼承、多態。

####2.類
#####2.1 類的基本概念
   類就是"分類"的概念,也就是對同一類事物的統稱,描述該類事物共同的特徵和行爲
   類是抽象的概念,是創建對象的模板,而對象是客觀存在的實體,佔用一塊內存空間
   類是一種引用數據類型,包含用於描述特徵的成員變量,以及用於描述行爲的成員方法(JAVA中可以忘記函數概念)。  
######2.1.1 類之間的關係
[參考鏈接:](https://blog.csdn.net/u014470581/article/details/62036457) https://blog.csdn.net/u014470581/article/details/6203645
類之間的常見三種關係:
**繼承(inheritance):is-a**
繼承指的是一個類(稱爲子類、子接口)繼承另外的一個類(稱爲父類、父接口)的功能,並可以增加它自己的新功能的能力。關鍵字extends。在UML類圖設計中,繼承用一條帶空心三角箭頭的實線表示,從子類指向父類,或者子接口指向父接口。 
![繼承.jpg-13.6kB][3]
**依賴(dependence):uses-a**
一個類的方法操縱另一個類的對象。
代碼層面,爲類B作爲參數被類A在某個method方法中使用。在UML類圖設計中,依賴關係用由類A指向類B的帶箭頭虛線表示。 
![依賴.jpg-23.2kB][4]
**聚合(aggregation):has-a**
一個**company**公司對象包含一些**employee**員工對象。在UML類圖設計中,聚合關係以空心菱形加實線箭頭表示。
![聚合.jpg-7.9kB][5]
#####2.2 類的定義
```
(1)類定義的語法格式
   class 類名{
      類體;
   }

類定義的一般形式如下
[類定義修飾符] class  <類名>   
{   //類體
      [成員變量聲明]
 [構造函數]
      [成員方法]
}
```
注意:
   通常情況下,當類名由多個單詞組成時,每個單詞的首字母都要大寫。駝峯命名法。

#####2.3 成員變量 以及初始化
```
 (1)成員變量聲明的語法格式
   class 類名{
       數據類型 成員變量名 = 初始值; - 其中=初始值是可以省略的
   }
如:
  class Person{
      String name;    //用於描述姓名的成員變量
      int ageNum;        //用於描述年齡的成員變量
      double weight;  //用於描述體重的成員變量
  }   
```

**注意:**
  通常情況下,當成員變量名由多個單詞組成時,要求從第二個單詞起首字母大寫。
![成員變量初始化.jpg-124.7kB][6]
#####2.X 補充:局部變量 成員變量區別
   局部變量 - 主要指聲明在方法體中的變量,作用域從聲明開始一直到方法體結束。
   成員變量 - 主要指聲明在類體中的變量,作用域從聲明開始一直到類體結束。    
成員變量有兩種:
    A:一種就是類變量或靜態變量  這類變量前面加static關鍵字修飾
        這類變量一旦賦值它的值就在你new出來的任何一個實例中具有相同的值 
   B:另一種叫做實例變量  前面不加static關鍵字修飾,每一個new出來的新實例都
可以對他賦予自己需要的值

成員變量和局部變量在內存中的分配
  對於成員變量和局部變量:成員變量就是方法外部,類的內部定義的變量;局部變量就是方法或語句塊內部定義的變量。局部變量必須初始化。 形式參數是局部變量,局部變量的數據存在於棧內存中。棧內存中的局部變量隨着方法的消失而消失。 成員變量存儲在堆中的對象裏面,由垃圾回收器負責回收。   如以下代碼:

(2)成員變量默認初始化
 

#####2.4 對象的創建
(1)語法格式
   new 類名();
如:
   new Person();  - 表示新建一個Person類型的對象,叫做匿(無)名對象; 

(2)使用方式
   使用new運算創建對象的過程叫做類的實例化,也叫作構造對象,當創建對象後需要在堆區申請一塊內存空間,用於記錄該對象獨有的成員變量信息。

#####2.5 引用(引用數據類型聲明的變量名)
(1)基本概念
   引用:使用引用數據類型聲明的變量名叫做引用變量,簡稱爲"引用"。用於記錄新建對象在堆區中的內存地址信息,便於再次訪問該對象。 
   ![引用類型.jpg-145.2kB][7]

(2)語法格式
   類名 引用變量名;
如:
   Person p;
   Person p = new Person();   

注意:
   當需要訪問成員變量時,使用 引用.成員變量名 的方式進行。
   p.name = "zhangfei";
   p.age = 30;   

#####2.6 成員方法 (格式返回值調用)
2.6.1 語法格式
  class 類名{
      返回值類型 成員方法名(形參列表){
          方法體;
      }
  }
如:
  class Person{
     void show(){
         System.out.println("沒事出來秀一下!");
     } 
  }


2.6.2 成員方法的詳解
(1)返回值類型
   返回值就是指從方法體內向方法體外傳遞的數據內容。
   返回值類型就是指返回值的數據類型。 
       當返回的數據內容爲66時,則返回值類型寫爲:int;
       當返回的數據內容爲3.14時,則返回值類型寫爲:double;
       當返回的數據內容爲"hello"時,則返回值類型寫爲:String;
   在方法體中使用return關鍵字返回數據並結束方法,如:return 66; return num。
   return關鍵字後面可以跟:字面值、變量、表達式以及方法的調用等。
   當方法體中沒有可以返回的數據內容時,則返回值類型寫:void即可。

(2)形參列表
   形式參數就是指從方法體外向方法體內傳入的數據內容,語法格式:數據類型 形參名
   形參列表就是形參的集合,格式爲:數據類型 變量名1,數據類型 變量名2,...
       當傳入的數據內容爲66時,則形參列表寫爲:int i;
       當傳入的數據內容爲3.14時,則形參列表寫爲:double d;
       當傳入的數據內容爲"hello"時,則形參列表寫爲:String s;
       當傳入的數據內容爲66和"hello"時,則形參列表寫爲:int i, String s;
   當不需要傳遞任何數據到方法體內時,則形參列表位置啥也不寫即可。

(3)方法體
   方法體就是用於描述方法功能的語句塊,通常用於多條語句的打包,從而提高代碼的複用性和可維護性。

2.6.3 方法的調用
(1)語法格式
   引用/對象.成員方法名(實參列表);
如:
   p.show();

(2)使用方式
   實參列表主要用於進行形參列表的初始化工作,因此參數的個數、類型以及順序等都必須與形參列表保持一致。
   實參可以傳遞字面值、變量、表達式、方法的調用等。
#####2.7 構造方法
 
1.1 構造方法(重中之重)
(1)語法格式
   class 類名{
      類名(形參列表){
         構造方法體;
      }
   }
如:
   class Person{
      Person(){
         ...
      }
   }

(2)注意事項
   a.構造方法的方法名稱與類名完全相同。
   b.構造方法是沒有返回值類型的,連void都沒有。
   c.當new一個新對象時,會自動調用構造方法來進行該對象成員變量的初始化工作。
d.構造方法只能被public private等訪問修飾符修飾
   e.構造方法只能在new的時候被調用。其他情況不能用。參考下圖
 

(3)默認構造方法
   當一個類中沒有自定義任何形式的構造方法時,編譯器會自動添加一個無參的空構造方法,該構造方法叫做默認/缺省構造方法,如:Person(){}
   當類中出現了自定義構造方法後,則編譯器不再提供任何版本的構造方法。
(4)構造方法重載
 
(5)建議:
1、建議自定義無參數構造方法,不要依賴編譯器,防止出現錯誤。
2、當類中無成員變兩個或者變量都爲常量(final)時,建議不提供任何版本的構造。
3、當類中有非常量成員變量時。建議提供兩個構造方法:一個無參數、一個全參數。

##### 2.8 方法的重載( Overload)
(1)基本概念
   在同一個類中,方法名相同參數列表不同之間的方法構成重載關係。
原理:編譯器根據參數列表不同,底層生成綁定到不同名稱的方法。

(2)重載的主要形式
   方法重載的形式有:參數的個數不同、參數的類型不同以及參數的順序不同。
   與參數的變量名和返回值類型無關,但建議返回值類型最好相同。

   判斷方法能否構成重載的依據:調用該方法時能否區分即可。
   java.io.PrintStream類中提供了大量的重載方法,print()和println()方法。
 

(3)重載的主要作用
   重載的作用在於:調用者只需要記住一個方法名就可以調用不同版本的方法,從而達到不同的效果,具體調用的版本由實際參數來決定。
####3. This關鍵字(指針)
 
#####3.1調用對象參數對象
```
如:
   class A{}
   class B{
      void show(A a){ ... }
   }
   
   A a = new A();
   B b = new B();
   b.show(a);
   調用對象:其中對象b是用於調用show()方法的,因此叫做調用對象。
   參數對象:其中對象a是用於作爲實參傳遞給show()方法的,因此叫做參數對象。
```

#####3.2 基本概念(當前對象)
   對於構造方法來說,this關鍵字代表當前正在構造的對象。
   對於成員方法來說,this關鍵字代表當前正在調用的對象。
   
原理解析:
   當使用不同的對象調用同一個方法時,那麼方法體中的this代表的對象也就不同,當訪問成員變量時相當於使用this.的(我的)方式訪問,因此最終的結果也就不同。

#####3.3 使用方式(就近原則)
  (1)當形參變量名和成員變量名相同時,在方法體中(就近原則)會優先選擇形參變量名,若希望使用成員變量名,則需要在變量名的前面加上this.明確要求使用成員變量(掌握)。
  (2)使用this.的方式調用成員方法(瞭解)。
  (3)在構造方法的第一行使用this(實參)的方式調用本類中的其他構造方法(瞭解)。
  
#####3.4 This構造方法
下圖:this("name",  67, true);和this(); 只能同時出現一個。否則構造器陷入死循環編譯報錯。
```
package com.study.test;

public class Test {
        
    private String name;
    private int age;
    private boolean boyFriend;
    
    public Test() {//空參構造
//        this()和this("name",  67, true);同時只能出現一個 否則構造器陷入死循環
        this("name",  67, true);//this 指針調用非空構造參數
        System.out.println("I am a boy:");
    }

    public Test(String name, int age, boolean boyFriend) {
//        this(); //語法報錯Recursive constructor invocation Test() 地遞歸構造函數
        System.out.println("I am a boy:");
        this.name = name;
        this.age = age;
        this.boyFriend = boyFriend;
    }
    
}

```
 
#####3.5 空指針類型異常
 - 原因:當引用類型變量爲NULL時無法對對象實行訪問,此時如果通過引用訪問其變量或者調用方法,就會出現空指針異常(NullPointerException);
```
1. Calling the instance method of a null object. 
2. Accessing or modifying the field of a null object. 
3. Taking the length of null as if it were an array. 
4. Accessing or modifying the slots of null as if it were an array. 
5. Throwing null as if it were a Throwable value. 
```

 - 1:NullPointerException由RuntimeException派生出來,是一個運行級別的異常。意思是說可能會在運行的時候纔會被拋出,而且需要看這樣的運行級別異常是否會導致你的業務邏輯中斷。
 - 2:空指針異常發生在對象爲空,但是引用這個對象的方法。例如: String s = null; //對象s爲空(null) int length = s.length();//發生空指針異常  
 - 3:一個變量是null,及只有其名,沒有實值內容,也沒分配內存,當你要去取他的長度,對他進行操作就會出現NullPointException,所以聲明一個變量時最好給它分配好內存空間,給予賦值。  
 - 4:比如變量爲空,而你沒有去判斷,就直接使用,就會出現NullPointException。寫程序時嚴謹些,儘量避免了,例如在拿該變量與一個值比較時,要麼先做好該異常的處理如: if (str == null) {   System.out.println("字符爲空!"); } 當然也可以將這個值寫在前面進行比較的,例如,判斷一個String的實例s是否等於“a”,不要寫成s.equals("a"),這樣寫容易拋出NullPointerException,而寫成"a".equals(s)就可以避免這個問題。不過對變量先進行判空後再進行操作比較好  
 - 5:儘量避免返回null,方法的返回值不要定義成爲一般的類型,而是用數組。這樣如果想要返回null的時候,就返回一個沒有元素的數組。就能避免許多不必要的NullPointerException,使用NullObject返回代替返回null確是一種不錯的選擇。 
 
 
####4. 方法的傳參和參數數目不確定
1.1 方法的傳參過程(原理、儘量理解)

public int max(int a,int b){......}
int a = 5; int b = 6;
int res = m.max(a,b);

  (1)main()方法是程序的入口,爲main()方法分配變量的內存空間並初始化。
  (2)調用max()方法,爲max()方法的形參變量分配內存空間。
  (3)使用實際參數爲形式參數進行初始化,也就是將實參的數值賦值給形參的內存空間
  (4)執行max()方法的方法體,執行完畢後釋放形參變量的內存空間
  (5)main()方法得到max()方法的返回值並繼續向下執行。

參數數目變化:
返回值  方法名(數據類型…  變量名)    eg:  int num(int… a)  
其中變量名a是數組通過下標訪問元素

public static int num(int... a) {
    int sum = 0;
    for (int i = 0; i < a.length; i++) {
        sum += a[i];
    }
    return sum;
}

要求大家重點掌握的內容:
  a.當使用基本數據類型作爲形參時,在方法體中改變形參變量的數值不會影響到實參; 
  b.當使用引用數據類型作爲形參時,在方法體中改變形參變量指向的數值時,則會
影響到實參指向的數值,因爲形參和實參指向同一塊區域。
 
  c.當使用引用數據類型作爲形參時,在方法體中改變形參變量的指向後在更改指向的
內容,則不會對實參指向的內容產生影響,因爲形參和實參指向不同的區域。
 
####5. 遞歸和遞推

 - (1)基本概念
    - 遞歸就是指在方法體中調用該方法自身的形式。
 - (2)使用原則
    - a.尋找遞歸的規律,並指定退出條件。
    - b.遞歸使得問題簡單化,而不是複雜化。
    - c.遞歸可能會影響程序的執行性能,此時需要使用遞推替代之。
    
斐波那契數列遞歸:

 - 方法調用自身方法
```
package com.study.test;

public class Test {

    public static Long fibonacciRecursive(int i) {// 遞歸

        if (i <= 2) {
            return 1L;
        } else {
            return fibonacciRecursive(i - 1) + fibonacciRecursive(i - 2);
        }

    }
    
    
    public static long fibonacciRecurrence(Long i) {// 遞推
        
        if (i <= 2) {
            return 1L;
        } else {
            Long  s1 = 1L, s2 = 1L, sn = 0L;
            for (int j = 2; j < i; j++) {
                sn = (long)(s1 + s2);
                s1 = s2;
                s2 = sn;
            }
            
            return sn;
        }

    }

    public static void main(String[] args) {

        Long result = fibonacciRecursive(0);
        System.out.println(result);
        Long result2 = fibonacciRecurrence(6L);
        System.out.println(result2);
    }
}

```
 
 - 斐波那契數列遞推: 
     - 循環 返回值不調用函數自身


### 第六章  封裝、繼承、重寫、 static、 super、this、單例、構造塊、靜態語句塊

####1. 封裝

#####1.1 基本概念
   當一個類中沒有做任何處理時,則測試類中可以任意訪問該類中的成員,此時就有可能帶來一些合法但不合理的數值,
   爲了避免該問題的發生就需要對類中的成員進行保護處理,而這種處理方式就叫做類的封裝。
   換句話說,封裝就是一種爲了保證成員變量值合理的機制。

#####1.2 封裝的流程
  (1)使用private關鍵字修飾成員變量,表示私有化。
  (2)提供公有的get成員變量/set成員變量方法供外界使用,在方法體中進行合理性判斷
  (3)在構造方法體中調用set成員變量的方法進行合理性判斷。
如下圖:
 ![image.png-41.7kB][8]

####2.static關鍵字(重點)
#####1.1 基本概念
 - 通常情況下,類中的成員變量都隸屬於對象層級,也就是每創建一個對象都會擁有獨立的一份,當所有對象共享同一份數據時並單獨記錄時會導致內存空間的浪費,此時可以使用static關鍵字修飾該成員變量表達靜態的概念,當使用static關鍵字修飾之後該成員變量就從對象層級提升到類層級,被所有對象共享與對象是否創建無關。
訪問方式:推薦類名.的,不建議使用對象/引用.的方式訪問。static修飾的加載到方法區
 
 
#####1.2 使用方式
   (1)在非靜態的成員方法中既可以訪問非靜態的成員,也可以訪問靜態的成員;
      (成員:成員變量 + 成員方法   類層級的內容被所有對象共享) 下圖show()方法。
   (2)在靜態的成員方法只能訪問靜態的成員,不能訪問非靜態的成員;下圖test()方法。
      (成員:成員變量 + 成員方法   調用靜態方法時可能還沒有創建任何的對象)
      (靜態的成員方法中是沒有this關鍵字的)
   (3)只有隸屬於類層級被所有對象共享的內容才能使用static關鍵字修飾;
       (不能濫用static) 
示例代碼:
D:\兄弟連視頻\day09\code\ TestStatic.java

####3. 構造塊和靜態語句塊(熟悉)
  a. 構造塊就是指在類中直接使用{}括起來的語句塊;
  b. 靜態語句塊就是指在類中直接使用static{}括起來的語句塊;
c.抽象類裏面可以用構造塊{}和static{}(JDK1.7語法不報錯 但是沒意義)
d.接口裏面不可以用構造塊和{}static{}(JDK1.7語法上報錯)
d. static{;} 靜態語句塊 前面不能加任何修飾符。

執行流程:   靜態語句塊  => 構造塊  => 構造方法體;
 
####4. 單例設計模式
(1)基本概念
   在某些特殊場合中,當一個類對外提供一個對象且只能提供一個對象時,這樣的類叫做單例類,而編寫單例類的設計形式和編程套路就叫做單例設計模式。實例:任務管理器只能開一個。

(2)實現流程
   a.私有化構造方法,使用private關鍵字修飾;
   b.提供本類的引用指向本類的對象,並使用private static共同修飾;
   c.提供公有的get成員方法負責將對象返回出去,並使用static修飾;

(3)實現方式
   單例設計模式的實現方式有兩種:餓漢式 和 懶漢式,以後的開發中推薦餓漢式;
示例代碼:
D:\兄弟連視頻\day09\code\ Singleton.java和TestSingleton.java
 

 


####5. 繼承
#####5.1繼承的由來和概念
   示例代碼:
D:\兄弟連視頻\day09\code\ Person.java和Student.java
當多個類中有相同的特徵和行爲時,就可以將相同的內容提取出來組成一個新的類,在編寫這多個類時只需要繼承這個新的類就可以複用相同的特徵和行爲,從而提高代碼的複用性和可維護性。
   換句話說,繼承就是一種實現代碼複用和提高可維護性的機制。
   在Java語言中使用extends(子類父類繼承)( 和implements(實現接口) )關鍵字來表達繼承關係。
如:
   class Student extends Person{ ... ...}  
   其中Person類叫做超類/父類/基類。
   其中Student類叫做派生類/子類。
 
#####5.2 注意事項
  (1)子類可以繼承父類中的成員方法以及成員變量
     (私有的成員變量也可以繼承但不能直接訪問)
     子類不能繼承父類的內容有:構造方法和私有成員方法。
父類中的構造方法是不能繼承的,但是在實例化子類的時候會調用父類的構造方法。
http://blog.csdn.net/wangyl_gain/article/details/49366505   
http://www.cnblogs.com/H-BolinBlog/p/5331195.html 
  (2)無論使用何種形式構造子類的對象,都會默認調用父類的無參構造方法來構造
     子類對象中包含的父類對象,也就是對父類中成員變量進行初始化,相當於
     super()調用的效果。
  (3)Java語言只支持單繼承不支持多繼承,也就是說一個子類只能有一個父類,
     但一個父類可以有多個子類。
  (4)不能濫用繼承,必須滿足邏輯關係:子類 is a 父類。比如:狗是動物。
#####5.3 extends關鍵字
 
#####5.4繼承中的構造方法
 
####6. super、this關鍵字(熟悉)
#####6.1基本概念
   this關鍵字 可以代表本類的對象;
   super關鍵字 可以代表父類的對象;

#####6.2使用方式
   使用this.的方式可以訪問本類的成員變量和成員方法;
   使用super.的方式可以訪問父類的成員變量和成員方法;

   使用this(實參)的方式可以調用本類中的其他構造方法;
   使用super(實參)的方式可以調用父類中的構造方法;

要求大家掌握的內容:
   a.使用this.的方式可以用於區分同名的成員變量和局部變量;
   b.使用super.的方式可以調用父類中被覆蓋的方法;
   c.使用super(實參)的方式可以調用父類的構造方法;

####7.方法的重寫(Override 重點)

 (1)基本概念
   當子類繼承父類中的方法不足以滿足子類的需求時,就可以在子類中重新寫一個和父類中方法一模一樣的方法,這種形式叫做方法的重寫/覆蓋。
(2)方法重寫的原則(拷貝方法名稱列表就行了)
   a.要求方法名相同、參數列表相同、返回值類型相同,從jdk1.5開始允許返回子類.
   b.訪問權限不能變小,可以相同或變大。   
   c.不能拋出更大的異常(異常機制)。
(3)Java中靜態屬性和方法可以被繼承,不可以被重寫(Override)而是被隱藏。靜態方法推薦用 (類名.方法名)的方式來調用。(不推薦 對象.方法名的方式)
實例:
 

### 第七章 包、訪問控制符、 final、 對象創建的過程
####1. 訪問控制
#####1.1 包的定義
   package 包名;   - 表示指定單層目錄  
   package 包名1.包名2.包名3....;  - 表示指定多層目錄
        - 用於管理文件方便,更重要的是可以避免同名文件導致的錯誤發生。
命名格式:org.apache.(公司名稱)commons(項目名).lang(模塊).StringUtil(類名)
#####1.2 常用的訪問控制符(權限修飾符)
   public - 表示公有的/公開的
   protected - 表示保護的
   默認訪問符 - 表示默認的
   private - 表示私有的   

#####1.3 訪問控制符的權限信息
```
   訪問控制符  訪問控制權限  本類   本包中的類   子類   其他類
   public        公開的     ok        ok        ok     ok
   protected     保護的     ok        ok        ok     no
   默認控制符     默認的     ok        ok        no     no
   private          私有的     ok        no        no     no
```
要求大家掌握的內容:
    a.public關鍵字修飾的內容表示可以在任意位置訪問。
    b.private關鍵字修飾的內容表示只能在本類的內部訪問。
    c.通常情況下,成員變量都是用private修飾,成員方法都使用public修飾。
d. 訪問控制符不能修飾static{;}靜態語句塊
#####1.4類的修飾  修飾詞順序 
修飾詞順序:[訪問權限] [abstract] [static] [final] [transient] [volatile] [synchronized] [native] [strictfp]

####2.final關鍵字(重點)
#####2.1 基本概念
   final本意爲“最終的,不可更改的”,修飾類、成員方法以及成員變量。

#####2.2 使用方式:不能重寫、不能繼承、必須初始化
   final關鍵字修飾類,表示該類是最終的,體現在該類不能被繼承。
        - 防止濫用繼承,如:java.lang.System類/String類等   
   final關鍵字修飾成員方法,表示該方法是最終的,體現在該方法不能被重寫。
        - 防止不經意間造成的方法重寫,
          如:java.text.SimpleDateFormat類中的format()方法
   final關鍵字修飾成員變量,表示該成員變量必須初始化而且不能更改(基本數據類型),如果是引用name該引用不會在指向其他對象。
        - 防止不經意間造成的修改,如:java.lang.Thread類中的MAX_PRIORITY。 

**補充:**
```
   在Java語言中很少單獨使用static和final關鍵字修飾成員變量,通常都是使用public static final共同修飾成員變量表示常量的概念。
   通常的命名規範是:所有字母都大寫,不同單詞之間使用下劃線連接。
   如:
    基本數據類型: 值不可改變    
    public static final double PI = 3.14;
      
      
     引用:引用無法指向其他對象,對象可以更改。
     final StringBuilder stringBuilder = new StringBuilder("abc");
    System.out.println(stringBuilder.hashCode());//118352462
    System.out.println(stringBuilder);//abc
    stringBuilder.append("123");
    System.out.println(stringBuilder.hashCode());//118352462
    System.out.println(stringBuilder);//abc123
```
      

####3.對象創建的過程
#####3.1 單個對象創建的執行過程
示例代碼:
D:\兄弟連視頻\day10\code\ TestObjectCreate.java
   (1)在執行代碼之前需要將類的字節碼信息讀入內存空間中的方法區,叫類的加載。
   (2)main()方法時程序的入口,當執行new TestObjectCreate()時表示在堆區申請空間
   (3)若成員變量沒有指定初始值時,則採用默認初始化方式進行,否則採用指定的
      初始值進行初始化。          
   (4)執行構造塊中的語句,可以對成員變量進行再次修改。
   (5)執行構造方法體中的語句,可以對成員變量進行再次修改。
   (6)此時對象構造完成,繼續執行main()方法中的後續代碼。

#####3.2 子類對象創建的執行過程
示例代碼:
D:\兄弟連視頻\day10\code\ TestSubObject.java  TestSuperObject.java
                  Father.java和sun.java
   (1)先加載父類的字節碼信息,因此先執行父類的靜態語句塊。
   (2)再加載子類的字節碼信息,因此執行子類的靜態語句塊。
   (3)執行父類的構造塊,再執行父類的構造方法體,此時父類的對象構造完成。
   (4)執行子類的構造塊,再執行子類的構造方法體,此時子類的對象構造完成。
   (5)繼續執行main()方法中後續的代碼。
 

### 第八章 多態、接口、 內部類  Object類、包裝類
####1.多態(重中之重、難點)
#####1.1 基本概念
   多態就是指同一種事物表現出來的多種形態。
   寵物:狗、貓、鳥、小強、...
   整數:byte b1 = 10;  short s1 = 10; int l1 = 10; 
多態:Pet p = new Dog(); Pet p = new Cat();//Cat Dog都是Pet子類 。
父類變量/引用指向子類對象
 
#####1.2 語法格式
示例代碼:
D:\兄弟連視頻\day10\code\ Person.java  Student.java
  
 父類類型 引用變量名 = new 子類類型();  - 父類的引用指向了子類的對象
如:
   Person p = new Student();
   p.show();

解析:
   a.在編譯階段p是Person類型的,只能調用Person類中的show()方法,否則編譯報錯;
   b.在運行階段p真正指向的對象是Student類型的,最終調用Student類的show()方法;
   
 


#####1.3 多態的效果
   (1)父類的引用能直接調用父類中的成員方法。
   (2)父類的引用不能直接調用子類中的成員方法。
   (3)父類的引用可以直接調用父子類都有的成員方法。
        對於非靜態的成員方法來說,父類的引用最終調用子類重寫以後的版本;
        對於靜態的成員方法來說,父類的引用最終調用父類自己的方法,與對象無關;
調用靜態方法:建議用    類名.靜態方法
 
#####1.4 引用數據類型之間的轉換 
   (1)當子類類型向父類類型轉換時,只需要發生自動類型轉換即可。
Person ps  =  new Student(“A”,11,1001);//(小到大)自動轉換
   (2)當父類類型向子類類型轉換時,需要進行強制類型轉換,語法格式如下:
        子類類型 引用變量名 = (子類類型)父類類型的引用名;
Person ps = new Person();     Student s = (Student) ps;
  

 (3)引用類型之間的轉換必鬚髮生在父子類之間,否則編譯報錯;
Person ps = new Person();    String s1 = (String) ps;//報錯
   (4)當父類類型的引用被強制轉換爲子類類型時,編譯階段不會報錯,但若轉換的
      子類類型並不是該引用真正指向的類型,則運行階段產生類型轉換異常。   
類型轉換異常:java.lang.ClassCastException 
   (5)爲了避免上述錯誤的發生,建議只要進行強制類型轉換則應該先使用instanceof
      進行判斷只有條件成立時再進行強制類型轉換。
#####1.5 instanceof運算符 區分== equals
語法格式如下:
         if(父類引用 instanceof 子類類型) - 判斷父類引用是否真正指向該子類類型
        instanceof爲一個操作符 可以理解爲是       - 若是則返回true,否則返回false。
實例:class Animal{}; class Dog extends Animal{}; class Cat extends Animal{};
Animal animal = new Dog();
animal  instanceof Animal = = True; 
animal  instanceof  Dog = = True; 
animal  instanceof  Cat = = False;

#####補充: 區分==和equals:
 https://www.cnblogs.com/dolphin0520/p/3592500.html
http://blog.csdn.net/t12x3456/article/details/7341515 
==就是用來比較值是否相等。equals方法是用來比較兩個對象的引用是否相等。
1)對於 = =運算符,如果作用於基本數據類型的變量,則直接比較其存儲的 “值”是否相等;   如果作用於引用類型的變量,則比較的是所指向的對象的地址。
2)對於equals方法,注意:equals方法不能作用於基本數據類型的變量。
 如果沒有對equals方法進行重寫,則比較的是引用類型的變量所指向的對象的地址;    
諸如String、Date等類對equals方法進行了重寫的話,比較的是所指向的對象的內容。
3)對於instanceof: (class A實例) instanceof (class B)  A顯式聲明的類型與右邊類B必須是同種類或者是B的子類才返回TRUE;
#####1.6實際應用
示例代碼:
D:\兄弟連視頻\day10\code\ Rect.java和Shape.java和Circle.java和 TestShape.java
    使用父類的引用作爲方法的形參時,可以屏蔽不同子類的差異性實現通用的編程,換句話說,就是編寫一份通用的代碼可以處理不同的子類對象,而且打印不同的結果。

####2.抽象類(重點)
#####2.1 什麼是抽象方法?
示例代碼:
D:\兄弟連視頻\day10\code\ TestAbstract.java 和 SubTestAbstract.java
   抽象方法就是指不能具體實現的方法,也就是沒有方法體,並使用abstract修飾。
   語法格式:
       訪問控制符 abstract 返回值類型 方法名稱(形參列表);  
   如:
       public abstract void cry();

#####2.2 什麼是抽象類?
   抽象類就是使用abstract關鍵字修飾的類,抽象類是不能構造對象的。看下圖
 
#####2.3 注意事項
   (1)抽象類中可以有成員變量、構造方法以及成員方法。
   (2)抽象類中可以沒有抽象方法,也可以有抽象方法。
   (3)擁有抽象方法的類必須是抽象類。
(4)抽象類中有非抽象的構造方法(構造方法 只能被public private等訪問修飾),但是無法實例化(無法new抽象類),是爲了防止生成抽象類後調用抽象方法(所以封死了構造方法)。

#####2.4 實際意義
   抽象類的實際意義不在於實例化對象而在於被繼承,當一個類繼承抽象類就必須要重寫抽象類中的抽象方法,否則該類也得聲明爲抽象類。
   因此抽象類對子類具有強制性和規範性,叫做模板設計模式。
 
經驗分享:
   在以後的開發中推薦使用多態的語法格式在方法體中使用,因爲當使用多態的語法時則調用的所有方法一定是父類中擁有的方法,若希望更換子類對象時,只需要將new後面的類型加以改變而其他代碼立刻生效,因此提高了代碼的可維護性和可擴展性。
   該方式的缺點在於父類的引用不能直接訪問子類的獨有成員變量和成員方法。
推薦:TestAbstract ta = new SubTestAbstract(); ta.show(); 

####3. 接口

#####3.1 基本概念

 - 接口就是一種比抽象類還抽象的類,該接口是不能實例化對象,更重要的是,接口中的所有方法都是抽象方法。
 - 聲明類的關鍵字是class,而聲明接口的關鍵字是interface。
 - 繼承類的關鍵字是extends,而實現接口的關鍵字是implements。

#####3.2 注意事項
 - (1)接口中的所有變量都必須由public static final共同修飾(可省略不報錯但是極不推薦),也就是常量。
 - (2)接口中的所有方法由public abstract共同修飾(可以省略其中任何一個關鍵字也可以都省略),也就是抽象方法。
 - (3)JAVA SE8以後允許在接口中增加靜態方法。
 - (4)JAVA SE8以後可以爲接口方法提供一個默認實現。用default修飾。
```
public interface Path{//靜態方法
    public static Path get(String first,String... more){
        return FileSystems.getDefault().getPath(first,more);
    }
}

public interface Comparable<T>{
    default int compareTo(T other){//defult默認方法
        return 0;
    }
}
```

#####3.3 類和接口之間的關係
 - 類和類之間的關係     使用extends關鍵字表達繼承的關係     支持單繼承
 - 類和接口之間的關係   使用implements關鍵字表達實現的關係  支持多實現
 - 接口和接口之間的關係 使用extends關鍵字表達繼承的關係     通常認爲單繼承

#####3.4 接口和抽象類之間的區別
 - (1)聲明抽象類的關鍵字是class,聲明接口的關鍵字是interface。
 - (2)繼承抽象類的關鍵字是extends,實現接口的關鍵字是implements。
 - (3)繼承抽象類只支持單繼承,而實現接口可以支持多實現。
 - (4)抽象類中可以有構造方法,而接口中沒有構造方法。
 - (5)抽象類中可以有成員變量,而接口只允許有常量。
 - (6)抽象類中可以有成員方法,而接口只允許有抽象方法。
 - (7)抽象類中增加方法可以不影響子類,但接口中增加方法一定會影響子類。

#####3.5 接口方法衝突
 - 前提:JAVA語法,單繼承多實現。在這過程中出現多個同樣的方法。
 - 情況:一個接口中將一個方法定義爲默認方法,在父類或者另一個接口中定義了同樣的方法(同名,有相同的參數類型,不存在返回值類型不同的情況)。
 - 解決方案:
    - 1、父類優先。如果父類提供了一個具體方法,(接口中)同名而且具有相同參數類型的默認方法會被忽略。
    - 2、接口衝突。如果一個父接口提供了一個默認方法,另一個接口提供了一個相同方法(同名參數類型相同,不論是否是默認參數),必須覆蓋這個方法來解決衝突。
```
//接口衝突 對應情況2
public interface Named {
    default String getName(){//A 默認實現
        return getClass().getName()+":Named_"+hashCode();
    };
//    String getName();//B 不是默認實現。不能直接用。否則報錯Cannot directly invoke the abstract method getName() for the type Named
//  A和B只能同時出現一個,否則報錯Duplicate method方法重複
}    

public interface Person {
    default String    getName(){//另一種默認實現
        return getClass().getName()+":Person_"+hashCode();
    }
}

public class Student implements Named, Person {

    @Override
    public String getName() {//接口Person和Named 都含有同名方法getName,編譯器報錯,在實現類Student中選擇兩個衝突方法中的一個,或者自己重寫方法。
        return Person.super.getName();//Person接口的默認方法
//        return Named.super.getName();//Named接口的默認方法
    }


//    public String getName() {
//        return "Student";
//    }
    
    public static void main(String[] args) {
        Student student = new Student();
        System.out.println(student.getName());
    }
}

```
####4.內部類
#####4.1 基本概念
 - 當把一個類的定義寫在另外一個類的類體中時,那麼把寫在內部的類叫做內部類,該內部類所在的類叫外部類。
 - 類中的內容主要有:成員變量、構造方法、成員方法、構造塊、靜態語句塊、內部類。

#####4.2 語法格式
```
   class 外部類名{
      class 內部類名{

      }
   }
```

#####4.3 主要作用
   當一個類存在的價值僅僅是爲某一個類單獨服務時,就可以將該類定義爲所服務類的內部類,內部類可以直接訪問所在類的私有成員,而不再需要公有的get/set方法等。
內部類一般情況下對外不可見,除了包含它的外部類其他類無法訪問到它。

#####4.4 內部類的主要分類
   普通內部類 - 將一個類的定義直接寫在另外一個類的內部(瞭解)。
   靜態內部類 - 使用static關鍵字修飾的內部類(瞭解)。
              - 普通的外部類是不允許使用static關鍵字修飾。
   局部內部類 - 將一個類的定義直接寫在一個方法體的內部(瞭解)。
              - 該類的作用域僅限於方法體的內部。
   匿名內部類 - 指沒有名字的內部類,用於構造父類/接口類型的對象(重點)。

#####4.5 匿名內部類(重點、難點) 回調模式:略
示例代碼:
D:\兄弟連視頻\day11\code\ SubA.java 和A.java和TestA.java

 
(1)語法格式
   父類/接口類型 引用名 = new 父類/接口類型(){
       進行方法的重寫
   };
 (2)經驗分享
   當使用接口類型的引用作爲方法的形參時,實參的傳遞方式有兩種:
a.自定義類實現接口,並創建該類的對象作爲實參傳遞給形參。
b.自定義匿名內部類來構造接口的引用,使用接口引用作爲實參傳遞給形參。
 
A是一個interface
####5. Object類(重點)
#####5.1基本概念
java.lang.Object類是類層次結構的根類,任何類向上查找父類總是可以找到Object
#####5.2 常用的包
   java.lang包 - 該包是Java核心包,包中的所有類和接口等由JVM自動導入。
               - 如:java.lang.System/String類等
   java.util包 - 該包是Java工具包,包中提供了大量的工具類。
               - 如:java.util.Scanner/Random類等
   java.io包   - 該包是Java中的輸入輸出包,包中提供了大量操作文件的類等。
               - 如:java.io.FileInputStream類等。
   java.net包  - 該包是Java中網絡包,包中提供了大量進行網絡通信的類等。
               - 如:java.net.ServerSocket類等。
  
#####5.3常用的方法
示例代碼:
D:\兄弟連視頻\day11\code\ Student.java  TestStudent.java

   Object() - 使用無參形式構造對象。
   boolean equals(Object obj) - 用於判斷調用對象是否與參數對象obj相等。
       - 該方法默認比較兩個對象的地址信息是否相等,等價於 = = 的效果。
       -重寫equals最好要重寫hashCode()方法
   int hashCode() - 用於返回調用對象的哈希碼值(對象內存地址的編號)。
       - 當兩個對象調用equals()方法相等時,則各自調用該方法的返回值必須相同。
       - 當兩個對象調用equals()方法不相等時,各自調用該方法的返回值可以相同,
         但最好不相同。
       - 要求只要重新equals()方法就一定要重寫hashCode()方法來保證上述約定。
   String toString() - 用於返回調用對象的字符串形式。
       - 通常該方法返回的字符串內容有:包名.類名@哈希碼的十六進制。
       -  System.out.println(裏面內容編譯器自動轉換爲String類型);
####6.包裝類和數學處理類
#####6.1 包裝類的由來
   Java語言是一門純面向對象的編程語言,萬物皆對象。
   Person p = new Person();
   int num = 10;

   在某些特殊場合(集合)中要求所有的數據都是對象,那麼對於基本數據類型的變量來說若要使用則需要進行對象化的處理,此時就需要藉助包裝類將變量包裝成對象。

#####6.2 常用的包裝類
   int      =>  java.lang.Integer類(重點)
   double   =>  java.lang.Double類
   byte     =>  java.lang.Byte類
   short    =>  java.lang.Short類
   long     =>  java.lang.Long類
   float    =>  java.lang.Float類
   boolean  =>  java.lang.Boolean類
   char     =>  java.lang.Character類

#####6.3 Integer類(重點)
示例代碼:
D:\兄弟連視頻\day11\code\ TestInteger.java

(1)基本概念
   java.lang.Integer類是對int類型的包裝類,該類的內部提供了int類型的成員變量。
   該類被final關鍵字。

(2)常用的方法   
   該類是Object類的間接子類,並且在該類的內部重寫了equals()、hashCode()、toString()方法
   Integer(int value) - 根據參數指定的整數值構造對象。
   Integer(String s) - 根據參數指定的字符串構造對象。
   int intValue() - 表示以int類型返回該對象的數值。
   static int parseInt(String s) - 用於將參數指定的字符串轉換爲int類型並返回。 

(3)裝箱和拆箱
   從int類型向Integer類型的轉換過程 叫做裝箱。
   從Integer類型向int類型的轉換過程 叫做拆箱。
   從jdk1.5開始提供了自動裝箱和自動解箱的機制,也就是說不需要方法直接轉換。

#####6.4 BigDecimal類(瞭解)
示例代碼:
D:\兄弟連視頻\day11\code\ TestBigDecimal.java

(1)基本概念
   java.math.BigDecimal類用於實現浮點數據的精確計算。

(2)常用的方法
   BigDecimal(String val) - 根據參數指定的字符串內容來構造對象。
   BigDecimal add(BigDecimal augend) 
        - 用於計算調用對象和參數對象的和並返回。
   BigDecimal subtract(BigDecimal subtrahend)
        - 用於計算調用對象和參數對象的差並返回。
   BigDecimal multiply(BigDecimal multiplicand) 
        - 用於計算調用對象和參數對象的積並返回。
   BigDecimal divide(BigDecimal divisor) 
        - 用於計算調用對象和參數對象的商並返回。
 
#####6.5 BigInteger類(瞭解)
示例代碼:
D:\兄弟連視頻\day11\code\ TestBigInteger.java
(1)基本概念
   java.math.BigInteger類主要用於描述long類型不足以表示的數據。

(2)常用的方法 
   BigInteger(String val) - 根據參數指定的字符串來構造對象。
   成員方法與上述類中的方法同名。
 
      


### 第九章 String類 正則表達式 StringBuilder 日期類
####1.String類
示例代碼:

#####1.1 基本概念 常量池
   java.lang.String類用於描述字符串,在Java程序中的所有字符串字面值都可以作爲該類的實例描述,如:“hello”。
   該類描述的字符串是個常量,字符串的內容不可改變。
如:
   String      name    =   "zhangfei";
     |           |              |
引用數據類型 引用變量名    字符串字面值

   name = "guanyu"; - 表示修改引用變量名name的指向,而不是指向的內容。 

筆試題:
   String str = ""; 和 String str = null;之間有區別嗎?
解析:
   有區別,前面的表示有字符串對象,但裏面沒有內容;後面的表示連字符串對象都沒有
 
  
常量池:http://blog.csdn.net/dajunxing/article/details/48056419 
http://www.cnblogs.com/javaminer/p/3923484.html 
http://www.cnblogs.com/SaraMoring/p/5687466.html 
#####1.2 常用的方法
(1)常用的構造方法
   String() - 使用無參的方式構造對象。
   String(byte[] bytes) - 根據參數指定的byte數組來構造對象。
   String(byte[] bytes, int offset, int length) 
      - 根據參數指定byte數組中從offset位置開始的length個字節來構造對象。
   String(String original) - 根據參數指定的字符串來構造對象。
   String(StringBuffer buffer) - 根據參數指定的引用來構造對象。
   String(StringBuilder builder) - 同上

(2)常用的成員方法
   char charAt(int index) - 根據參數指定的下標返回對應的字符。
   int length() - 用於返回字符串的長度。
    
   int compareTo(String anotherString) - 用於比較調用對象和參數對象的大小。
        - 若調用對象和參數對象相等,則返回0;若大於則返回正數;若小於返回負數
        - 分別使用兩個字符串中對應位置的字符從頭開始進行比較,若第一個字符能夠
          區分大小則比較結束,否則使用下一個位置的對應字符進行比較。
        - 當字符串的前面內容相同時,則長度更大的字符串比較大。
如:
   "hello"  'h' 'e' 'l'   'l' > 'h'  返回正數,證明"hello"字符串比較大
   "hehe"   'h' 'e' 'h'
   
   "hello"       'h' 'e' ...  存在的字符串內容相同時,則大小取決於長度
   "helloworld"  'h' 'e' ...     
 
   int compareToIgnoreCase(String str) - 比較字符串的大小,不考慮大小寫。
        - 也就是相同字母的大小寫之間比較的結果是相等,如:'a' 'A'是相等的。
   boolean equals(Object anObject) - 比較兩個字符串內容是否相等
   boolean equalsIgnoreCase(String anotherString) - 比較是否相等,不考慮大小寫

   boolean contains(CharSequence s) - 判斷當前字符串是否包含參數指定的內容
   boolean endsWith(String suffix) - 判斷當前字符串是否以參數字符串爲結尾
   boolean startsWith(String prefix) - 判斷當前字符串是否以參數字符串開頭
   String toLowerCase() - 用於將當前字符串中的所有字符轉換爲小寫。
   String toUpperCase() - 用於將當前字符串中的所有字符轉換爲大寫。
   String trim() - 用於去除字符串兩端的空白字符。 
   byte[] getBytes() - 用於將字符串類型轉換爲byte數組。
   char[] toCharArray() - 用於將字符串轉換爲char數組。

   int indexOf(int ch) - 返回參數指定字符在當前字符串中第一次出現的索引位置。
   int indexOf(int ch, int fromIndex) 
       - 從fromIndex位置開始查找字符第一次出現的位置 
   int indexOf(String str) - 從當前字符串中查找str第一次出現的位置並返回。
   int indexOf(String str, int fromIndex) - 從fromIndex位置開始查找。
   
   int lastIndexOf(int ch) - 返回當前字符串中字符ch最後一次出現的索引位置。
   int lastIndexOf(int ch, int fromIndex) - 從fromIndex位置開始查找
   int lastIndexOf(String str) - 返回當前字符串中字符串str最後一次出現索引位置
   int lastIndexOf(String str, int fromIndex) - 從fromIndex位置開始查找
    
   String substring(int beginIndex) - 獲取從beginIndex位置開始到結尾的子字符串
   String substring(int beginIndex, int endIndex) 
       - 獲取當前字符串中從beginIndex位置開始一直到endIndex位置(不包含)。

#####1.3 split拆分和replace方法
 
 
####2. 正則表達式(百度現成的)
包:java.util.regex 
(1)基本概念
   正則表達式本質上就是一個字符串,通常使用^開頭使用$結尾,可以省略.
   該字符串用於進行用戶輸入數據的格式驗證/檢查,若不匹配則報錯。
關鍵方法:matches     str.matches (reg) 

(2)常用的規則  [表示一位]、{表示多位}
   [abc] - 表示可以出現a、b 或 c。
   [^abc] - 表示可以出現任何字符,除了 a、b 或 c。
   [a-zA-Z] - 表示可以出現a到z或A到Z,兩頭的字母包括在內,可以出現任何字母。
   
   . - 表示可以出現任何字符。
   \d - 表示可以出現任何數字,相當於[0-9]。
   \D - 表示可以出現任何非數字,相當於[^0-9]。
   \s - 表示可以出現任何空白字符,相當於[ \t\n\x0B\f\r]。
   \S - 表示可以出現任何非空白字符,相當於[^\s]。
   \w - 表示可以出現任何單詞字符,相當於[a-zA-Z_0-9],
        也就是由字母、數字以及下劃線組成。
   \W - 表示可以出現任何非單詞字符,相當於[^\w]。
   
   X? - 表示X可以出現一次或一次也沒有,也就是0 ~ 1次。
   X* - 表示X可以出現零次或多次,也就是0 ~ n次。
   X+ - 表示X可以出現一次或多次,也就是1 ~ n次。
   X{n} - 表示X可以出現恰好 n 次。
   X{n,}- 表示X可以出現至少 n 次,也就是 >= n次。
   X{n,m} - 表示X可以出現至少 n 次,但是不超過 m 次,也就是 >= n 並且 <= m次。
Variable must provide either dimension   expressions or an array initializer

####3.StringBuilder類和StringBuffer類(查手冊會用即可)
#####3.1 基本概念
   由於String類描述的字符序列是無法更改的,當需要描述多個相近的字符串時,不能對同一個字符串進行修改只能單獨保存,因此對內存空間的消耗比較大,此時可以使用StringBuilder類和StringBuffer類來替代之,這兩種類型描述的字符序列可以更改。
   StringBuffer類是jdk1.0就有的類,支持線程安全,因此效率比較低。
   StringBuilder類是jdk1.5提供的類,不支持線程安全,因此效率比較高(推薦)。
   
#####3.2 常用的方法
   StringBuilder(String str) - 根據參數指定的內容構造對象,容量爲16 + str長度
   int capacity() - 用於返回調用對象的容量。
   int length()   - 用於返回調用對象中的字符個數。
   
   StringBuilder insert(int offset, String str) 
        - 用於將str插入當前字符串中下標爲offset的位置。 
   StringBuilder append(String str) 
        - 用於將字符串str的內容插入到當前字符串的末尾位置。
   
   StringBuilder delete(int start, int end)
        - 用於刪除當前字符串中從start(包含)開始到end(不包含)結束。
   
   StringBuilder replace(int start, int end, String str) 
        - 用於將當前字符串中start和end之間的字符串使用str進行替換。
   StringBuilder reverse() - 用於反轉字符序列。

####4.日期相關的類(查手冊會用即可)
示例代碼:
D:\兄弟連視頻\day12\code\ TestCalendar.java TestDate.java TestSimpleDateFormat.java
#####4.1 Date類
(1)基本概念
   java.util.Date類用於描述特定的瞬間,可以精確到毫秒。

(2)常用的方法      
   Date() - 使用無參的形式構造對象,默認採用當前系統時間來初始化。
   Date(long date) - 根據參數指定的毫秒數來構造對象。
       - 其中毫秒數爲指定日期和時間距離1970年1月1日 0時0分0秒。
       - 1秒 = 1000毫秒  1毫秒 = 1000微秒  1微秒 = 1000納秒
       - 該方法與File類中的一個方法是絕配。
   long getTime() - 用於獲取當前對象距離1970年1月1日0時0分0秒的毫秒數。
   void setTime(long time) - 用於設置距離上述時間的毫秒數來更改當前對象。

#####4.2 SimpleDateFormat類
(1)基本概念
記得:import java.text.SimpleDateFormat;
   java.text.SimpleDateFormat類用於格式化和解析日期類型的數據。
   通俗來說,該類就是用於實現Date類型和String類型之間的轉換。
 
(2)常用的方法
   SimpleDateFormat(String pattern) - 根據參數指定的格式來構造對象。
       - 其中參數字符串中的內容:y-年、M-月、d-日、H-時、m-分、s-秒
   String format(Date date) - 用於將參數指定的日期對象轉換爲String類型並返回。
   Date parse(String source) - 用於將String類型轉換爲日期類型並返回。
   
#####4.3 Calendar類
(1)基本概念
   java.util.Calendar類用於描述特定的瞬間,該類中的方法用於取代Date類過時方法
   該類是一個抽象類,不能實例化對象的。

(2)常用的方法   
   static Calendar getInstance() - 用於獲取該類的一個實例(多態)。
   void set(int year, int month, int date, int hourOfDay, int minute, int second) - 用於指定年月日時分秒信息的。
   Date getTime() - 用於將Calendar類型的對象轉換爲Date類型並返回。

 

#####4.4 TimeStamp時間戳


### 第十章  集合類(容器)Collections  Map
示例代碼:

####1 .綜述
#####1.1 基本概念
定義:Java.util中的接口 Collection<E>又被稱爲Java Collections framework。Java容器的用途是保存對象,根據數據結構不同將其劃分爲Collection和Map。
   當需要記錄多個類型不同/相同的數據時,則聲明一個集合記錄即可,集合就是容器。
   數組 - 本質上就是內存中的一塊連續存儲空間,用於記錄多個類型相同的數據。
        - 一旦聲明數組之後則長度固定,無法改變。
        - 插入和刪除元素不方便,可能會導致大量元素的移動。
        - 支持下標訪問,可以實現隨機訪問。
        - 既可以存放基本類型的數據,也可以存放引用類型的數據。
   集合 - 內存空間可以連續也可以不連續,記錄的數據類型可以相同也可以不同。
        - 集合的長度是可以隨時動態調整。
        - 插入和刪除元素可以不移動大量的元素。
        - 可以支持下標訪問,隨機訪問。
        - 只可以存放引用類型的數據,基本類型的數據不可以。    

#####1.2 基本分類
   在Java語言中將集合框架分爲兩大類:Collection接口 和 Map接口。
   其中Collection接口中操作元素的基本單位是:單個元素。
   其中Map接口中操作元素的基本單位是:單對元素。
   
   通常情況下,Collection接口很少使用,更多地使用該接口的子接口:List接口、Queue接口、以及Set接口。
 
#####1.3 Collection接口的常用方法(熟練、記住)
   boolean add(E e) - 用於將參數指定的元素e放入當前集合.
       - 成功返回true,否則false。
   boolean addAll(Collection<? extends E> c) 
       - 用於將參數指定集合中的所有元素一個一個放入當前集合中。
   
   boolean remove(Object o) - 用於從當前集合中移除參數指定的單個元素。
   boolean removeAll(Collection<?> c) - 用於從當前集合移除參數指定所有元素。
   void clear() - 用於清空當前集合。
  
   boolean contains(Object o) - 用於判斷是否包含單個元素。
   boolean containsAll(Collection<?> c)  - 判斷是否包含參數指定所有元素

   boolean isEmpty() - 判斷是否爲空
   int size() - 獲取元素的個數
   
   boolean retainAll(Collection<?> c)-計算當前集合和參數集合的交集放入當前集合
   Iterator<E> iterator() - 獲取當前集合的迭代器。
####2.List接口(重中之重)
示例代碼:
#####2.1 基本概念
   java.util.List接口是Collection接口的子接口,元素有先後次序並且可以重複。
   該接口的主要實現類有:ArrayList類、LinkedList類、Stack類、Vector類。
   其中ArrayList類的底層是採用動態數組來進行管理的,訪問方便,增刪不方便。
   其中LinkedList類的底層是採用鏈表來進行管理的,訪問不方便,增刪方便。
   其中Stack類的底層是採用動態數組來進行管理的,但該類具有後進先出的特性,簡稱爲LIFO(last in first out),漢語名稱爲:棧。
   其中Vector類的底層是採用動態數組實現的,與ArrayList類相比是早期的類,支持線程安全,效率比較低,因此推薦使用ArrayList類。

#####2.2 常用的方法  E - 在此 collection 中保持的元素的類型
boolean add( E e) - 用於將指定元素添加到此列表的結尾。
void add(int index, E element) - 用於將元素element插入到index的位置。
boolean addAll(int index, Collection<? extends E> c) 
        - 用於將集合c中的所有元素插入到當前集合中index位置。
  //  boolean add(E,e) 將集合c2看做一個整體放入集合c1中。boolean = c1.add(c2)。
    E remove(int index) - 用於刪除當前集合中下標爲index位置的元素並返回。
    E set(int index, E element) - 用於使用element替換下標爲index位置元素並返回
    E get(int index) - 用於獲取index位置的元素並返回。
public boolean retainAll(Collection<?> c) 
c1.retainAll(c2) :取c1和c2的交集並放入c1中。
public boolean containsAll(Collection<?> c)
c1.containsAll(c2) 如果c1包含容器c2中的所有元素,則返回 true。
boolean contains(Object o) 
 c1.contains(“abc”)  如果此列表中包含指定的元素,則返回 true。
contains調用集合包含對象的equals方法與待判斷對象比較。一般要重寫equals
    List<E> subList(int fromIndex, int toIndex) 
       - 用於獲取fromIndex位置(包含)到toIndex位置(不包含)的視圖並返回。
       - 只是獲取數據並沒有申請新的存儲空間單獨保存。
 
####3.泛型機制 Stack棧
示例代碼:D:\兄弟連視頻\day14\code\ TestStack.java
目前集合中之所以可以存放不同類型的數據,是因爲將每個元素都看做Object類型放入的,當從集合中取出元素時默認也是Object類型,爲了表達該元素真實的類型就需要強制類型轉換,此方式可能引發類型轉換異常。
   爲了避免上述錯誤的發生,從jdk1.5開始要求使用集合時加上泛型機制,也就是在集合類型的後面使用<數據類型>的方式明確規定可以存放的數據內容,若放入其他類型數據則編譯報錯,如:
   List<String> l1 = new LinkedList<String>();
        
   泛型的本質就是參數化類型,也就是將數據類型作爲實參傳遞給該接口/類中的形參E,從此E全部被替換爲實參類型。
   jdk中的K,V,T,E等泛型名稱很多人以爲是固定寫法,其實這些名稱是可以改的,比如改成zhangsan,lisi都可以,jdk爲了容易看懂,所以用K表示鍵,V表示值,T表示type類型,E表示enum枚舉,其實這四個都只是符號,都是表示泛型名稱,下面的例子的T全部可以換成E,也可以換成K,V,zhangsan,都沒關係。 
   ? 表示不確定的類型 
   Object java中所有類的父類。
http://blog.csdn.net/xswh520/article/details/9160875

####4.Queue隊列接口(重點)
示例代碼:D:\兄弟連視頻\day14\code\ TestQueue.java
#####4.1 基本概念
  java.util.Queue接口是Collection接口的子接口,與List接口是平級關係。
  該接口的主要實現類是:LinkedList類,增刪比較方便。
  隊列就是一種具有先進先出特性的數據結構,簡稱爲FIFO(first in first out)。

#####4.2 常用的方法
  boolean offer(E e) - 用於將參數指定的元素放入當前隊列的末尾。 
  E poll() - 用於獲取隊列的首元素並移除,若隊列爲空則返回null。
  E peek() - 用於獲取隊列的首元素,若隊列爲空則返回null。
這裏簡單對其重複的方法做點簡單的區分。
offer,add區別:
一些隊列有大小限制,因此如果想在一個滿的隊列中加入一個新項,多出的項就會被拒絕。
這時新的 offer 方法就可以起作用了。它不是對調用 add() 方法拋出一個 unchecked 異常,而只是得到由 offer() 返回的 false。 
 
poll,remove區別:
remove() 和 poll() 方法都是從隊列中刪除第一個元素。remove() 的行爲與 Collection 接口的版本相似,
但是新的 poll() 方法在用空集合調用時不是拋出異常,只是返回 null。因此新的方法更適合容易出現異常條件的情況。
 
peek,element區別:
element() 和 peek() 用於在隊列的頭部查詢元素。與 remove() 方法類似,在隊列爲空時, element() 拋出一個異常,而 peek() 返回 null

  
####4.Set接口(重點)
示例代碼:D:\兄弟連視頻\day14\code\ TestSet.java和TestTreeSet.java
#####4.1 基本概念 
   java.util.Set接口是Collection接口的子接口。元素沒有先後次序並且不允許重複。
   該接口的主要實現類:HashSet類 和 TreeSet類。
   其中HashSet類的底層是採用哈希表進行管理的。
   其中TreeSet類的底層是採用二叉樹進行管理的。
#####4.2 HashSet類
  
#####4.3 TreeSet類 
常用方法:Set<Integer> s1 = new TreeSet<Integer>(); 一般TreeSet只存放同一種泛型的元素。方便實現Comparable接口。

(1)什麼是二叉樹?
   二叉樹就是指每個節點最多隻有兩個子節點的樹形結構。
    
(2)什麼是有序二叉樹?
   有序二叉樹就是指滿足以下三個條件的樹形結構,又叫做二叉查找樹。
       a.左子樹中的任何節點元素值都小於根節點元素值。
       b.右子樹中的任何節點元素值都大於根節點元素值。
       c.左右子樹的內部也要滿足上述規則。

(3)TreeSet類的要求
   當使用TreeSet類存放元素時必須要指定元素比較大小的規則,具體方式如下:
       a.使用元素的自然排序來指定規則,讓元素類型實現java.lang.Comparable接口.
       b.使用比較器來指定規則,創建TreeSet對象時指定java.util.Comparator接口。
 
 

#####4.4 Comparable接口和Comparator接口
Comparable接口:
   
Comparator接口
  
#####4.5常用的工具類
   java.util.Arrays類主要提供了大量用於操作數組的工具方法。
   java.util.Collections類主要提供了大量用於操作集合的工具方法。
####5. Iterator迭代器常用的方法 
   參考Collection接口即可。
   Iterator<E> iterator() 
       - 用於獲取當前集合中的迭代器,可以迭代/遍歷/獲取集合中的每個元素。 
         boolean hasNext() - 根據迭代器判斷當前集合是否擁有可以訪問的元素。
         E next()  - 用於獲取集合中的一個元素。
         void remove() - 用於從集合中移除迭代器返回的最後一個元素。

注意:
   當使用迭代器訪問集合中的所有元素時,切記不允許使用集合中的remove()方法刪除元素,否則會引發併發修改異常,建議使用迭代器自己的remove()方法刪除。
 


####6. 增強版的for循環(for each)
(1)語法格式
   for(元素類型 變量名 : 數組名/集合名){
       循環體;
   } 

(2)執行流程
   每次從數組/集合取出一個元素賦值給變量名在循環體中使用,直到取完所有元素爲止 。 

總結:
   對於Set集合(無序)中的元素訪問方式有3種:toString()、迭代器、for each結構。
   對於List集合(有序)的元素訪問方式有4種:除了上述3種方式,還有get()方法。

####7.Map接口(重點)
示例代碼:D:\兄弟連視頻\day15\code\ TestTreeSet.java和TestMap.java 

#####7.1 基本概念
   java.util.Map<K,V>集合用於存放鍵值對,其中鍵不允許重複,只能對應一個值。
       類型參數:
          K - 此映射所維護的鍵(Key)的類型
          V - 映射值(Value)的類型
   該接口的主要實現類:HashMap類 和 TreeMap類。 
#####7.2 常用的方法
    V put(K key, V value) - 用於將參數指定的key和value組成一對放入當前集合中。
        - 當該方法實現增加的功能時返回null,但實現修改的功能時則返回之前的舊值
    V remove(Object key) - 用於根據參數指定的key從當前集合移除,返回對應value
    boolean containsKey(Object key) - 用於判斷參數指定的key是否存在。
    boolean containsValue(Object value) - 用於判斷參數指定的value是否存在。
    V get(Object key) - 根據參數指定的key返回對應的value,若不存在則返回null。
    
    Set<Map.Entry<K,V>> entrySet() - 用於獲取包含映射關係的Set視圖。如下圖:
         - 通俗來說,就是將Map集合轉換爲Set集合。
         - K getKey() - 用於獲取調用對象中的key.
         - V getValue() - 用於獲取調用對象中的value。
    Set<K> keySet() - 用於獲取包含鍵的Set視圖。
 
 
#####7.3 HashMap   
 

### 第十一章 異常Exception
示例代碼:
D:\兄弟連視頻\day15\code 和day16\code\ 

####1. 基本概念
   異常就是不正常的意思,在Java語言中主要指在運行階段產生的錯誤。
   Java.lang.Throwable 類是 Java 語言中所有錯誤或異常的超類。
   該類的主要實現子類有:Error類 和 Exception類。
   其中Error類主要用於描述比較嚴重的錯誤,無法通過編碼來解決。
   其中Exception類主要用於描述輕微的錯誤,可以通過編碼等方式解決。

####2. 基本分類 
   Java.lang.Exception類的所有已知子類分爲以下兩大類:
        RuntimeException - 運行時異常,也叫做非檢測性異常。
        IOException和其它所有異常 - 其它異常,也叫做檢測性異常。
              - 檢測性異常就是指在編譯階段可以被編譯器檢測出來的異常。

注意:
   當程序執行過程中發生異常並沒有手動編碼處理時,則採用默認處理方式,通常終止程序的執行並打印異常名稱、異常原因以及異常的位置等信息,導致後續代碼無法執行。

   Java.lang.RuntimeException類的主要子類:
       ArithmeticException - 算數異常
       ArrayIndexOutOfBoundsException - 數組下標越界異常(間接子類)
       NullPointerException - 空指針異常
       ClassCastException - 類型轉換異常
       NumberFormatException - 數字格式異常(間接子類)
       StringIndexOutOfBoundsException - 字符串下標越界異常(間接子類)
       ConCurrentModificationException - 併發修改異常

####3. 非檢測異常的處理 
   在以後的開發中可以使用if()條件判斷來避免絕大多數非檢測異常的發生。

####4. 異常的捕獲try catch finally語句 
(1)語法格式
   try{
      編寫所有可能發生異常的語句塊;
   }
   catch(異常類型 變量名){
      編寫處理當前異常類型的語句塊;
   }
   ... ...
   finally{
      編寫無論是否發生異常都應該執行的語句塊;
   }
    
(2)注意事項
   當需要編寫多個catch()分支,切記小範圍的異常類型應該放在大範圍異常類型的上面。
   懶人的寫法:
        catch(Exception e){ ...} 
   finally{}中通常編寫用於進行善後處理的語句塊,比如:關閉文件、斷開數據庫等。
 
####5. 異常的拋出 throws
(1)基本概念
   當某些特殊場合中發生了異常卻無法處理或者不便於處理時,就可以將異常拋給該方法的調用者,這個過程就叫異常的拋出/轉移。可以通過throws關鍵字拋出異常。

(2)語法格式
   返回值類型 方法名(形參列表) throws 異常類型1,異常類型2,...{ 方法體; }
如:
   public void show() throws Exception { }      

(3)方法重寫的原則
   a.要求方法名相同、參數列表相同以及返回值類型相同,從jdk1.5開始允許返回子類
   b.訪問權限不能變小,可以相同或者變大。
   c.不能拋出更大的異常。

注意:
   子類中重寫的方法可以拋出與父類中方法一樣的異常、更小的異常以及不拋出異常,
但不能拋出更大的異常,也不能拋出額外的異常。

####6. 自定義異常
(1)自定義異常的由來
   當需要在程序中表達年齡不合理的異常時,在java官方庫中並沒有對應的異常類型,此時就需要自定義異常類來表達該錯誤,從而提高代碼的可讀性。

(2)自定義異常的步驟
   a.自定義xxxException類繼承自Exception類或者其子類。
   b.提供無參的構造方法和字符串作爲參數的構造方法。
自定義構造方法:(繼承父類Exception的構造方法) 
要拋出異常的代碼:
 
(3)異常對象的拋出
   throw new 異常類型();
####7. throws和throw區別
throws:用於拋出異常的聲明。
格式:返回值類型 方法名(形參列表) throws 異常類型1,異常類型2,...{ 方法體; }
位置:throws在方法體外,在方法名(形參列表)之後。
後面:throws後面可以跟多個異常類型。

throw:用於拋出一個異常對象。
格式:throw new 異常類型();
位置:throw在方法體裏面。
後面:throws後面只能跟一個對象。

####8. 運行異常類的子類異常7個
算術異常:ArithmeticException
數組下標越界異常:ArrayIndexOutOfBoundsException
字符串下標越界異常:StringIndexOutOfBoundsException
空指針異常類:NullPointerException
數據類型轉換異常:ClassCastException
數據格式異常:NumberFormatException(間接子類)
併發修改異常: ConcurrentModificationException


### 第十二章  File類   IO流
####1.File類(重點)
示例代碼:
D:\兄弟連視頻day16\code\TestFile.java
1.1 基本概念
   java.io.File類用於作爲文件和目錄路徑信息的抽象表示,可以獲取文件和目錄的屬性信息,如:名稱、大小等信息。但是不能對文件的內容進行訪問。
1.2 常用的方法
  構造方法: File(String pathname) - 根據參數指定的路徑名來構造對象。
   boolean exists() - 用於判斷文件或目錄是否存在。
   String getName() - 用於獲取文件或目錄的名稱。
   long length() - 用於獲取文件的長度/大小。
   long lastModified() - 用於獲取文件的最後一次修改時間。
        - 返回距離1970年1月1日0時0分0秒之間的毫秒數
        - 與Date類中的Date(long)構造方法搭配使用
   String getAbsolutePath() - 用於返回絕對路徑信息。
       絕對路徑 - 主要指從根目錄開始的路徑信息,如:c:/...  d:/..
       相對路徑 - 主要指從當前目錄開始的路徑信息,如:./code  ./code/code
                  . 代表當前目錄    .. 代表當前目錄的上一級目錄
       在以後的開發中推薦使用相對路徑。
   boolean delete() - 用於刪除文件或目錄。
   boolean createNewFile() - 用於創建新的空文件。  
   boolean mkdir() - 用於創建目錄。
   boolean mkdirs() - 用於創建多級/層目錄。 
   File[] listFiles() - 用於獲取指定目錄中的所有內容並返回。
   boolean isFile() - 用於判斷調用對象關聯的是否爲一個文件。
   boolean isDirectory() - 用於判斷調用對象關聯的是否爲一個目錄。
 
1.3 目錄FileFilter接口  

####2.I/O流
示例代碼:
D:\兄弟連視頻day16\code\和day17\code\
 2.1 基本概念
  I/O就是Input/Output的簡寫,也就是輸入/輸出,換句話說,也就是讀取/寫入操作。
  I/O流就是指像流水一樣不間斷地進行讀寫的操作。
2.2 基本分類
  根據讀寫操作的基本單位不同分爲:字節流 和 字符流。
   其中字節流就是指以字節爲基本單位進行讀寫的流,可以處理任何文件。
   字符流就是指以字符(2個字節)爲基本單位進行讀寫的流,只能處理文本文件。
    
   根據讀寫操作/數據流動的方向不同分爲:輸入流 和 輸出流(站在程序的角度)。
   其中輸入流就是指讀取文件中的內容輸入到程序中的流,也就是讀文件。
   其中輸出流就是指將程序中的內容輸出到文件中的流,也就是寫文件。
數據傳輸方式:
節點流(直接和文件打交道)和包裝流(程序和文件之間有管道,不直接接觸)。
2.3 I/O流的框架
   字節流的頂層父類爲:InputStream類 和 OutputStream類。 - 抽象類
   其中InputStream類的主要子類有:
       FileInputStream類、DataInputStream類、ObjectInputStream類。
   其中OutputStream類的主要子類有:
       FileOutputStream類、DataOutputStream類、ObjectOutputStream類。
   
   字符流的頂層父類爲:Reader類 和 Writer類。           - 抽象類     
   其中Reader類的主要子類有:
      BufferedReader類、InputStreamReader類、StringReader類。
   其中Writer類的主要子類有:
      BufferedWriter類、OutputStreamWriter類、StringWriter類。

補充:
   PrintStream類是OutputStream類的間接子類。
2.4 FileOutputStream類(重中之重)
(1)基本概念
   java.io.FileOutputStream類用於將圖像數據之類的原始字節流寫入到輸出流中。

(2)常用的方法
   FileOutputStream(String name) - 根據參數指定的文件路徑構造對象並建立關聯。
   FileOutputStream(String name, boolean append) - 以追加的方式建立關聯。
   void write(int b) - 用於寫入參數指定的單個字節。b自動找對應的ASCII碼值。
   void write(byte[] b, int off, int len) 
       - 用於將數組b中從off位置開始的len個字節寫入。
   void write(byte[] b) - 用於將參數指定整個數組的內容寫入。
   void close() - 關閉輸出流並釋放有關的資源。
 
2.5 FileInputStream類(重中之重) -1和1
(1)基本概念
   java.io.FileInputStream類主要用於讀取圖像數據之類的原始字節流。   

(2)常用的方法
   FileInputStream(String name) - 根據參數指定的路徑名來構造對象。
   int read() - 用於從輸入流中讀取一個字節並返回。
       - 當讀取到文件末尾時則返回-1,否則返回讀取到的數據內容。
   int read(byte[] b, int off, int len) 
       - 從輸入流中讀取len個字節的數據放入數組b中下標爲off的位置上。
       - 當讀取到文件末尾時則返回-1,否則返回讀取到的字節個數。
   int read(byte[] b) 
       - 用於從輸入流中讀取b.length個字節到數組b中。
   int available() 
       - 用於返回通過此輸入流可以讀取到的文件大小。
   void close()- 關閉輸出流並釋放有關的資源。

注意:
文件調用 FileOutputStream.write(-1);-1默認是INT型4個字節(32位,32個1)。但是void write(int b)方法只能寫入一個字節(8位),所以讀取的是低8位,即:1111 1111。
文件調用FileInputStream.read();但是int read( )方法只能讀取一個字節(8位),但是返回一個int型4個字節,32位。所以前面補32-8=24個0。即:0000 0000 0000 0000 0000 0000 1111 1111。所以返回255。

 
文件拷貝:FIS FOS 
2.6 DataOutputStream類(熟悉)
(1)基本概念
   java.io.DataOutputStream類用於將基本類型的數據寫入輸出流中。

(2)常用的方法
   DataOutputStream(OutputStream out) - 根據參數指定的引用來構造對象。
       - 其中OutputStream類是抽象類,實參需要傳遞子類的對象。
   void writeInt(int v) - 用於將參數指定的整型變量值寫入輸出流中。
   void close()

2.7 DataInputStream類(熟悉)
(1)基本概念 
   java.io.DataInputStream類用於從輸入流中讀取基本類型的數據。

(2)常用的方法   
   DataInputStream(InputStream in) - 根據參數指定的引用來構造對象。
       - 其中InputStream類是抽象類,實參需要傳遞子類的對象。
   int readInt() - 用於從輸入流中讀取一個整型數據並返回。
   void close()- 用於關閉IO流
2.8 BufferedReader類(重點)
(1)基本概念
   java.io.BufferedReader類用於讀取單個字符、字符數組以及一行字符內容。   

(2)常用的方法 
   BufferedReader(Reader in) - 根據參數指定的引用來構造對象。
       - 其中Reader類是個抽象類,實參需要傳遞子類的對象。
       - 子類對象選擇InputStreamReader類型的對象,選擇FileInputStream類型對象
   String readLine() - 用於讀取一行字符串內容並返回。
   void close()          - 用於關閉IO流
 
2.9 BufferedWriter類(重點)
(1)基本概念
   java.io.BufferedWriter類用於寫入單個字符、字符數組以及一行字符內容。    

(2)常用的方法
   BufferedWriter(Writer out) - 根據參數指定的引用來構造對象。
       - 其中Writer類是個抽象類,實參需要傳遞子類的對象。
       - 子類對象選擇OutputStreamWriter類的對象,選擇FileOutputStream類型對象
   void write(String s, int off, int len) 
       - 用於將字符串s中從下標爲off位置開始的len個字符寫入輸出流中。
   void newLine() - 用於寫入行分隔符。
   void close()       - 關閉該流的緩衝。
   void write(String str) - 從Writer類繼承下來的方法,用於寫入參數指定的字符串
void flush()        - 刷新該流的緩衝。對於輸出的緩衝流,寫出的數據會先在內存中緩存,使用flush()將會使內存中的數據立刻寫出 

 
2.10 PrintStream類(重點)
(1)基本概念
   java.io.PrintStream類用於方便地打印各種格式的數據。

(2)常用的方法 
   PrintStream(OutputStream out) - 根據參數指定的引用構造對象。
      - 其中OutputStream類是抽象類,實參需要傳遞子類的對象。
   void print(String s) - 用於打印參數指定的字符串。
   void println(String x) - 用於打印字符串並終止該行。
void write(byte[] buf, int off, int len) 
          - 將 len 字節從指定的初始偏移量爲 off 的 byte 數組寫入此流。
   void close() 
(3)PrintStream與BufferedReader相對應。 
 
2.11 ObjectOutputStream類(重點) 
(1)基本概念
   java.io.ObjectOutputStream類用於將Java語言的對象整體寫入到輸出流中。
   只能將支持 java.io.Serializable 接口的對象寫入流中。(類必須實現該接口)
   類通過實現 java.io.Serializable 接口以啓用其序列化功能。
   所謂的序列化就是指將對象中需要保存的相關信息有效地組織成字節序列的過程。

(2)常用的方法  
   ObjectOutputStream(OutputStream out) - 根據參數指定的引用來構造對象。
       - 其中OutputStream類是抽象類,因此實參需要傳遞子類的對象。
   void writeObject(Object obj) - 用於將參數指定的對象寫入到輸出流中。
   void close()
User是一個類且已經實現java.io.Serializable 接口 
2.12 ObjectInputStream類(重點)
(1)基本概念
   java.io.ObjectInputStream類用於從輸入流中讀取整個對象。

(2)常用的方法    
   ObjectInputStream(InputStream in) - 根據參數指定的引用構造對象。
        - 其中InputStream類是抽象類,因此實參需要傳遞子類的對象。
   Object readObject() - 用於讀取一個對象並返回。
        - 無法通過該方法的返回值來判斷是否讀取到文件末尾。
   void close()

經驗:
   當需要向文件中寫入多個對象時,建議先將多個對象放入集合中,再將整個集合看做一個對象整體寫入文件中,此時讀取文件中的內容只需要讀取一次就結束。
 
2.13 轉換類InputStreamReader和OutputStreamReader
(1)基本概念
   java.io. InputStreamReader:輸入時,實現字節流到字符流的轉換,提高操作的效率(前提是,數據是文本數據)。= = = =》解碼:字節數組---->字符串
   java.io. InputStreamReader:輸出時,實現字符流到字節流的轉換,提高操作的效率(前提是,數據是文本數據)。= = = =》解碼:字符串 ---->字節數組
 
2.14 標準的輸入輸出流
System.in:標準輸入流(鍵盤輸入)      System.out:標準輸出流(顯示器輸出)

### 第十三章  線程
示例代碼:

####1.線程的基本概念和基本操作
#####1.1 線程、進程 基本概念
   程序 - 數據結構 + 算法,主要指存放在硬盤/磁盤上的可執行文件。
   進程 - 主要指運行在內存中的程序。
   目前主流的操作系統都支持多進程,爲了讓操作系統在同一時間可以執行多個任務,但進程是重量級的,新建進程對系統的資源消耗比較大,因此不建議啓動過多的進程。
   線程就是指進程內部的程序流,也就是說操作系統支持多進程,在每一個進程的內部又可以支持多線程,並且線程是輕量級的,新建線程會共享所在進程的資源。
   因此在以後的開發中都使用多線程的機制。
   操作系統中通常都採用時間片輪轉法來保證多個任務的併發執行,所謂的併發就是指宏觀並行,微觀串行。
####1.2 Thread類  

####2.線程的創建和主要方法
#####2.1 線程的創建(重中之重)
(1)線程的創建方式
   java.lang.Thread類用於描述線程,Java 虛擬機允許應用程序併發地運行多個執行線程。
   創建線程的主要方式:
      a.自定義類繼承Thread類並重寫run()方法,創建該類的對象調用start()方法。
      b.自定義類實現Runnable接口並重寫run()方法,創建該類的對象作爲創建Thread類對象的實參,最後使用Thread類的對象調用start()方法。
   
(2)線程創建的相關方法
   Thread() - 使用無參的方式構造對象。
   Thread(String name) - 使用參數指定的名稱來構造對象。
   Thread(Runnable target) - 根據接口類型的引用來構造對象。
   Thread(Runnable target, String name) - 根據接口引用和名稱來共同構造對象。

   void run() - 當調用對象是根據參數指定的接口引用構造時,則最終調用該接口引用所指向對象的run()方法,否則該方法啥也不做並返回。
   void start() - 用於啓動線程,JVM會調用該線程的run()方法。 

(3)多線程的原理分析
   其中執行main()方法的線程叫做主線程,執行run()方法的線程叫做新線程/子線程。
   對於start()方法之前的代碼來說,只會被主線程執行一次,當start()方法調用成功之後,線程的個數瞬間由1個變成了2個,其中新創建的子線程去執行run()方法中的代碼塊,而主線程繼續向下執行,於是兩個線程同時執行產生了交錯的打印結果。
   當run()方法的代碼執行完畢後表示子線程結束;當main()方法的代碼執行完畢後表示主線程結束,各自獨立運行互不影響;主線程和子線程的先後執行次序沒有明確的規定,由系統的調度算法來決定。

注意:
   線程創建和啓動的兩種方式相比,採用繼承的方式相對來說代碼量簡單但是可維護性比較差,而實現接口的方式代碼相對複雜但可維護性更高,因此推薦使用實現接口的方式。
繼承方式:
 
實現接口方式: 
#####2.2 線程的名稱和編號
   long getId() - 用於獲取線程的編號/標識符並返回。
   String getName() - 用於獲取線程的名稱並返回。
   void setName(String name) - 用於修改線程的名稱爲參數指定的內容。
   static Thread currentThread() - 用於返回當前正在執行的線程對象的引用。
 
#####2.3 線程的主要狀態(熟悉)
   新建狀態 - 當使用new創建線程對象之後進入的狀態。
            - 此時線程並沒有開始執行。
   就緒狀態 - 調用start()方法之後進入的狀態。
            - 此時線程依然沒有開始執行。
   運行狀態 - 當線程調度器調用已經就緒完成的線程後進入的狀態。
            - 此時線程開始執行。
            - 當時間片執行完畢後但任務沒有完成時回到就緒狀態。
   消亡狀態 - 當時間片執行完畢後並且任務已經完成時進入的狀態。
            - 此時線程已經終止。
   阻塞狀態 - 當線程在執行的過程中發生了阻塞事件進入的狀態,如:sleep()方法。
            - 當阻塞解除後進入就緒狀態。
 
#####2.4 Thread類的常用方法
   static void yield() - 讓出CPU的執行權,轉而去執行其他的線程(瞭解)。
   static void sleep(long millis) - 讓當前正在執行的線程休眠參數指定的毫秒數。
   static void sleep(long millis, int nanos) - 讓線程休眠參數指定的毫秒 + 納秒。
        - 1秒 = 1000毫秒  1毫秒 = 1000微秒  1微秒 = 1000納秒
   void interrupt() - 用於中斷線程,通常用於睡眠的打斷(瞭解)。 
   int getPriority() - 用於獲取當前線程的優先級。
   void setPriority(int newPriority) - 用於修改線程的優先級爲參數指定的數值。
       - 優先級高的線程表示獲取時間片的機會越多,但不保證一定先執行。
   boolean isDaemon() - 用於判斷當前線程是否爲守護線程。
   void setDaemon(boolean on) - 用於設置該線程爲守護線程。
void join() - 用於等待調用對象所描述的線程終止。
   void join(long millis) - 等待調用對象終止的最長時間爲參數指定的毫秒。
   void join(long millis, int nanos) - 用於等待參數指定的毫秒 + 納秒。
- 守護線程又叫做後臺線程,當所有非守護線程結束時,守護線程隨之結束。

####3.線程的同步機制(重點)
#####3.1 基本概念
   當多個線程在同一時刻訪問同一種共享資源時,可能會造成數據的不一致問題,此時就需要對線程的操作進行協調,而線程之間的協調和通信就叫做線程的同步機制。  
#####3.2 解決方案
  由程序可知:當線程一還沒有來得及將最新餘額寫入後臺數據庫時,線程二已經開始執行, 導致最終的結果不正確。
  解決方案:  將多個線程的並行操作改爲串行操作即可。 
  引發問題:  當多個線程依次串行執行時,會導致執行的效率比較低,因此能不用則不用。
#####3.3 實現方式
   爲了解決上述問題,可以使用Java語言中synchronized關鍵字來保證線程操作的原子性,也就是說當線程執行鎖定的代碼時必須執行完畢纔會釋放CPU的執行權。
   具體方式如下:
      (1)使用同步語句塊的方式來保證原子性,語法格式如下:
         synchronized(類類型的引用){//可以用synchronized(this)
             編寫需要鎖定的代碼塊;
         }
         注意:
            多個線程所使用的鎖對象必須是同一個對象,否則無法實現同步的效果。
            因此通常推薦使用this關鍵字。
     (2)使用synchronized關鍵字來修飾整個方法。 
#####3.4 原理分析
   當多個線程啓動後各自獨立運行都去搶佔對象鎖,若其中一個線程搶到了對象鎖則可以放心地執行鎖定的所有代碼,其他線程進入阻塞狀態,直到該線程執行完畢所有鎖定代碼後自動釋放對象鎖,此時等待的其他線程又可以搶佔對象鎖,搶到的線程去執行鎖定的代碼,搶佔不到的線程繼續保持阻塞狀態。
#####3.5 死鎖的概念
線程一執行的代碼:
   void run(){
       synchronized(a){      持有對象鎖a,等待對象鎖b
          ...
          synchronized(b){
              ... ...
          }
       }
   }
線程二執行的代碼:
   void run(){
       synchronized(b){     持有對象鎖b,等待對象鎖a
          ...
          synchronized(a){
              ... ...
          }
       }
   }
   在以後的開發中儘量不要使用同步語句塊的嵌套結構!!!
 
#####3.6 Object類中的常用方法
   void wait() - 用於讓當前正在執行的線程進入阻塞狀態,直到其他線程調用notify()或者notifyAll()方法(開發中推薦)。
   void wait(long timeout) - 用於讓當前線程進入阻塞狀態,直到其他線程調用方法或者參數指定的毫秒數已經過去了。 
   void notify() - 用於喚醒等待的單個線程(隨機)。
   void notifyAll() - 用於喚醒等待的所有線程。
#####3.7 線程池 

### 第十四章 網絡編程
示例代碼:

####1.網絡編程的常識(記住)
#####1.1 七層網絡協議模型
   ISO(國際標準委員會組織)將數據的傳遞從邏輯上劃分爲了以下七層:
       應用層、表示層、會話層、傳輸層、網絡層、數據鏈路層、物理層。
   當發送數據時需要按照上述七層的先後次序一層層進行加包處理,然後再發出。
   當接收到數據時需要按照上述七層的相反次序一層層進行拆包處理,然後再解析。
#####1.2 常見的網絡協議
   http - 超文本傳輸協議,瀏覽網頁時可以使用該協議。
   ftp  - 文件傳輸協議,  上傳和下載文件時使用該協議。
   tcp  - 傳輸控制協議,  進行網絡通信時使用該協議。
   udp  - 用戶數據報協議,進行網絡通信時使用該協議。視頻緩存。
   ip   - Internet Protocol互聯網協議,是上述協議的底層協議。
  
   協議 - 本質上就是一種約定/規則,用於實現雙方有效的通信。
#####1.3 IP地址(重點)
如:
   192.168.1.1  - 絕大多數路由器的登錄地址,進行Mac地址過濾。  
   
   IP地址 - 是互聯網中的唯一標識,可以通過IP地址定位到具體某一臺主機。
   IP地址本質上是由32位二進制組成的整數,叫做ipv4,當然也有128位二進制組成的整數,叫做ipv6,目前使用主流的還是ipv4.
   日常生活中採用點分十進制表示法來進行IP地址的描述,也就是將IP地址的每個字節轉換爲一個十進制整數,不同的十進制整數之間採用小數點分隔。
   如:
       0x01 02 03 04 => 1.2.3.4
    
查看IP地址:
   在windows系統的dos窗口中使用命令: ipconfig   ipconfig/all
   在linux系統的終端窗口中使用命令:  ifconfig   /sbin/ifconfig 
1.4 端口號(重點)
   IP地址 - 可以定位到具體某一臺設備/主機。
   端口號 - 可以定位某臺設備/主機中的具體某個進程。
   網絡通信/編程提供:IP地址 + 端口號。
   
   端口號本質上就是由16位二進制組成的整數,範圍是:0 ~ 65535,其中0 ~ 1024之間的端口號通常被系統佔用,因此編程時需要從1025開始使用。
   
####2. 基於tcp協議的編程模型(重點)
#####2.1 基本概念
   C/S架構 - C(Client 客戶端)/S(Server 服務器)    
   B/S結構 - B(Browser 瀏覽器)/S(Server 服務器)
   Socket - 本意"插座",在網絡編程中表示用於通信的邏輯載體/端點,俗稱“套接字”。
#####2.2 編程模型
服務器:
   (1)創建ServerSocket類型的對象,並綁定參數指定的端口號。
   (2)等待客戶端的連接請求,調用accept()方法。
   (3)得到Socket類型的對象並使用輸入輸出流進行通信。
   (4)關閉Socket並釋放有關的資源。

客戶端:
   (1)創建Socket類型的對象,並提供服務器的IP地址和端口號。
   (2)使用輸入輸出流進行通信。
   (3)關閉Socket並釋放有關的資源。
#####2.3 相關類和方法的解析
(1)ServerSocket類
   java.net.ServerSocket類用於描述服務器套接字。
   ServerSocket(int port) - 根據參數指定的端口號來創建對象並綁定。
   Socket accept() - 監聽並接收客戶端的連接請求,若無客戶端連接則進入等待狀態。
   void close() - 用於關閉套接字。

(2)Socket類
   java.net.Socket類用於描述客戶端套接字。套接字是兩臺機器間通信的端點。
   Socket(String host, int port) - 根據參數指定的IP地址和端口號創建對象。
   InputStream getInputStream() - 用於獲取當前套接字的輸入流。
   OutputStream getOutputStream() - 用於獲取當前套接字的輸出流。
void close() - 用於關閉套接字。
    
 
####3.tcp協議和udp協議的比較
(a)tcp協議
   tcp協議 - 傳輸控制協議,是一種面向連接的協議,類似於打電話。
           - 建立連接 => 進行通信  => 斷開連接
           - 在通信的整個過程中全程保持連接
           - 保證了數據傳遞的可靠性和有序性    
           - 是一種全雙工的字節流通信方式
           - 服務器壓力比較大,資源消耗比較多,而且數據傳遞的效率相對比較低。

(b)udp協議
   udp協議 - 用戶數據報協議,是一種非面向連接的協議,類似於寫信。
           - 在通信的整個過程中不需要保持連接。
           - 不保證數據傳遞的可靠性和有序性
           - 是一種全雙工的數據報通信方式
           - 服務器壓力比較小,資源消耗比較少,但數據傳遞的效率相對比較高。
####4.基於udp協議的編程模型(重點)
#####4.1 編程模型
主機A(接收方):
   (1)創建DatagramSocket類型的對象,並與參數指定的端口綁定。
   (2)創建DatagramPacket類型的對象,等待接收數據。
   (3)調用receive()方法來接收數據。
   (4)關閉Socket並釋放有關的資源。

主機B(發送方):  
   (1)創建DatagramSocket類型的對象。
   (2)創建DatagramPacket類型的對象,並提供接收方的IP地址和端口號。
   (3)調用send()方法來發送數據。
   (4)關閉Socket並釋放有關的資源。
#####4.2 相關類和方法的解析
(1)DatagramSocket類
   java.net.DatagramSocket類用於描述發送或接收數據報的套接字,也就是包裹投遞/接收點 
   DatagramSocket() - 使用無參的形式構造對象。
   DatagramSocket(int port) - 根據參數指定的端口號來構造對象。
   void receive(DatagramPacket p) - 用於接收數據並存放到參數指定的包裹中。
   void send(DatagramPacket p) - 用於將參數指定的包裹發送出去。
   void close() - 關閉套接字並釋放有關的資源。

(2)DatagramPacket類
   java.net.DatagramPacket類用於描述數據報信息的。
   DatagramPacket(byte[] buf, int length) 
        - 用於構造一個能接收長度爲length的數據包,將數據存放在buf中。
   DatagramPacket(byte[] buf, int length, InetAddress address, int port) 
        - 用於構造一個將長度爲length的數據報,發送給主機address上的port端口。
   InetAddress getAddress() - 用於獲取發送方/接收方的IP地址信息。
   int getPort() - 用於獲取發送方/接收方的端口號信息。
   int getLength() - 用於獲取發送/接收的數據長度。

(3)InetAddress類
   java.net.InetAddress類用於描述互聯網協議地址,也就是IP地址信息。
   static InetAddress getLocalHost() - 用於獲取本地主機的地址信息。
   static InetAddress getByName(String host) - 用於根據主機名來獲取地址信息。
   String getHostName() - 用於獲取主機名信息並返回。
   String getHostAddress() - 用於獲取ip地址信息並返回。  

### 第十五章  反射

####1. 基本概念
```
如:
   Person p = new Person();   - 在運行階段只能創建Person類型的對象
   p.show();                  - 在運行階段只能調用show()方法   
```
 - 反射本質上就是一種實現動態編程的機制,也就是說在運行階段才能確定創建何種類型的對象以及調用何種方法的機制,具體的類型和方法由實參決定。
 - 目前主流的框架技術底層都是採用反射機制實現的。

####2. Class類   
#####2.1 基本概念
 - Class類的實例表示正在運行的Java應用程序中的類和接口,也就是代表一種數據類型。
 - Class類沒有公共構造方法,Class類的實例是在類加載的過程中由Java虛擬機和類加載器自動構造的。

#####2.2 獲取Class類實例/對象的主要方式
 - a.使用數據類型.class的方式來獲取對應的Class對象。 
 - b.使用對象.getClass()方法的調用來獲取對應的Class對象。
 - c.使用包裝類.TYPE的方式可以獲取對應基本類型的Class對象。
 - d.使用Class.forName()的方式來獲取參數指定類型的Class對象。  
 - 總結:基本數據類型:a和c  引用數據類型:a和b和d 
#####2.3 常用的方法
 - T - 由此 Class 對象建模的類的類型(要實例化的對象類型)
 -   static Class<?> forName(String className) - 用於獲取參數指定類型的Class對象。
 -   T newInstance() - 使用當前正在調用對象所代表的類來構造新對象。
  - 若當前正在調用對象代表String類,調用此方法就相當於new String()來構造對象。
  - 若當前正在調用對象代表Person類,調用此方法就相當於new Person()來構造對象。
 - Constructor<T> getConstructor(Class<?>... parameterTypes) 
      - 用於獲取當前正在調用對象所代表的類中參數指定的單個公共構造方法並返回。
 - Constructor<?>[] getConstructors() 
      - 用於獲取當前正在調用對象所代表的類中所有的公共構造方法並返回。
 - Field getDeclaredField(String name) 
      - 用於獲取當前正在調用對象所代表的類中參數指定的單個成員變量並返回。
 - Field[] getDeclaredFields() 
      - 用於獲取當前正在調用對象所代表的類中所有的成員變量並返回。
 - Method getMethod(String name, Class<?>... parameterTypes) 
      - 用於獲取當前正在調用對象所代表的類中參數指定的單個公共成員方法並返回。
 - Method[] getMethods() 
      - 用於獲取當前正在調用對象所代表的類中所有的公共成員方法並返回。

####3. Constructor類
#####3.1 基本概念
 - java.lang.reflect.Constructor<T>類用於描述獲取到的單個構造方法。

#####3.2 常用的方法
   T newInstance(Object... initargs)     
- 用於當前正在調用對象所代表的構造方法來構造新實例,參數進行新實例初始化工作
參數(Object... initargs):  其中…代表可變長參數,  
initargs - 將作爲變量傳遞給構造方法調用的對象數組;基本類型的值被包裝在適當類型的包裝器對象(如 Float 中的 float)中。
例如: (Object... initargs)就是  ("zhangfei", 30)
Class c1 = Class.forName("xdl.day21.Person");//獲得class
Constructor ct = c1.getConstructor(String.class, int.class);//獲得Constructor類ct
System.out.println(ct.newInstance("zhangfei", 30)); //用ct構造新實例

 
####4 Field類
#####4.1基本概念
   java.lang.reflect.Field類用於描述獲取到的單個成員變量。

#####4.2常用的方法   
   Object get(Object obj) 
      - 用於獲取對象obj中當前正在調用對象所代表成員變量的數值並返回。 
      - 若參數傳入Person類型的p對象,當前正在調用的對象代表成員變量name時,
        調用該方法表示返回p.name的數值。 
   void set(Object obj, Object value) 
      - 用於將obj對象中當前正在調用對象所代表成員變量的數值修改爲value。
      - 若參數傳入Person類型的p對象,當前正在調用的對象代表成員變量name時,
        調用該方法則表示p.name = value的效果。
   void setAccessible(boolean flag)
      - 用於設置是否進行Java語言的訪問檢查,若給true則表示取消檢查。 
####5 Method類
#####5.1基本概念
   java.lang.reflect.Method類用於描述獲取到的單個成員方法。
#####5.2常用的方法
   Object invoke(Object obj, Object... args) 
      - 用於使用obj對象調用當前正在調用對象所代表的成員方法,實參傳遞args並返回。
      - 若參數傳入Person類型的p對象,當前正在調用的對象代表成員方法getName()時,調用該方法則表示p.getName(args)的效果。
 
####6. JavaBean的概念
  JavaBean本質上就是一種習慣性的編程規範,並不是明確的編程規則/語法要求,具體如下:
     (1)要求遵循JavaBean規範的類必須在一個包中;
     (2)要求遵循JavaBean規範的類必須有無參的構造方法;
     (3)要求遵循JavaBean規範的類必須私有化成員變量;
     (4)要求遵循JavaBean規範的類必須提供公有的get和set成員方法;
     (5)要求遵循JavaBean規範的類支持序列化操作;

### 第十六章設計原則、模式
示例代碼:
D:\兄弟連視頻day21\code\
####1. 設計原則
#####1.1 項目/軟件開發的流程
    需求分析文檔 => 概要設計文檔 => 詳細設計文檔 => 編碼和測試 => 安裝和調試
=> 維護和升級
#####1.2 常用的設計原則
http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html 
(1)開閉原則(Open Close Principle  OCP)
- 對擴展開放,對修改關閉。
                   - 爲了保證程序的可維護性和複用性更高,儘量避免錯誤的發生。
                   - 任何軟件都是bug(臭蟲、漏洞)的。
如:
   public class Person{                  
      private String name;
      ... ...  
   }   

   public class SubPerson extends Person{
      private int age;
   } 

   (2)里氏代換原則(Liskov Substitution Principle  LSP)
 - 任何父類可以出現的地方,子類一定可以出現。
  - 子類 is a 父類,體現在繼承和多態方面。
如:
   public class TestShape{
       public void draw(Shape s){
           s.show();
       }
   }
   
   TestShape ts = new TestShape();
   ts.draw(new Circle(1, 2, 3));
   
  (3) 依賴倒轉原則(Dependence Inversion Principle  DIP)
- 儘量依賴於抽象類和接口,而不是具體實現類。
- 抽象類和接口對子類具有強制性和規範性。
如:
   public abstract class A{
      void show();
   }

   public class B extends A{
      @Override
      void show(){
           ....
      }
   }

   (4)接口隔離原則(Interface Segregation Principle  ISP)
- 儘量依賴於小接口而不是大接口,避免接口的污染。
如:
   public interface RunAnimal{  
       public void run();
   }
   public interface FlyAnimal{
       public void fly();
   }


   public class Dog implements RunAnimal{
       public void run(){  ...}
   }

   (5) 迪米特法則(Demeter Principle最少知道原則)(DP)
- 高內聚,低耦合。
       - 內聚就是指一個實體/模塊儘量將該模塊需要具備的所有功能都聚集在內部。
       - 耦合就是指一個實體/模塊儘量少於其他實體/模塊有關聯。
      
  (6)合成複用原則(Composite Reuse Principle  CRP)
- 儘量使用合成的原則,而少使用繼承。
如:
   public class A{
      public void show(){ ... ...}
   }

   public class B{
      A a;
      public B(A a){
         this.a = a;
      }
      public void test(){
          //調用A類中的show()方法
          a.show();
      }
   }

####2.常用的設計模式
#####2.1 基本概念
http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html 
   設計模式(Design pattern)是一套被反覆使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。
   通俗來說,就是使用在固定場合中的固定套路。
#####2.2 基本分類
   創建型模式 - 工廠方法模式、抽象工廠模式、單例設計模式、...(要求會寫)
   結構型模式 - 裝飾器模式、代理模式、...(要求看懂)
   行爲型模式 - 模板方法模式、觀察者模式、...(以後講到)      

####3.常見算法
示例代碼:

#####1.常用的查找算法(重點)
######1.1 線性查找算法(順序查找算法)
(1)算法流程
   a.使用目標元素與樣本數列中的第一個元素起依次進行比較;
   b.若找到與目標元素相等的元素,則表示查找成功;
   c.若目標元素與樣本數列中的所有元素都比較完畢也沒找到相等的元素,則表示查找失敗;
######1.2 二分查找算法(折半查找算法)
示例代碼:D:\兄弟連視頻day22\code\TestFind.java
(1)算法流程
   a.假定樣本數列中的元素都是從小到大排列的;
   b.使用目標元素與樣本數列中的中間元素比較大小,若相等則表示查找成功;
   c.若目標元素小於中間元素,則去中間元素的左邊進行查找,重複步驟b;
   d.若目標元素大於中間元素,則去中間元素的右邊進行查找,重複步驟b;
   e.若目標元素與所有該比較元素比較完畢後也沒有相等的元素,則表示查找失敗; 

#####2.常用的排序算法(重點)

######2.1 冒泡排序算法(重中之重) 
示例代碼:

(1)算法流程  
   a.比較相鄰位置的兩個元素,若第一個元素比較大則交換兩個元素的位置;
   b.從開始的第一對一直到結尾最後一對,經過這一步最後的元素將是這組元素中的最大值;
   c.重複步驟b持續對越來越少的元素進行兩兩比較,直到處理完畢所有元素爲止;
     (直到任意兩個相鄰位置的元素都無需發生交換爲止) 

######2.2 插入排序算法(熟悉)  
(1)算法流程
  a.從第一個元素起,認定該元素已經有序;
  b.取出下一個元素與左邊的有序數列從右向左依次進行比較;
  c.若取出的元素小於左邊的元素,則將左邊的元素右移;
  d.重複步驟c,直到取出元素大於等於左邊的元素時,則將取出的元素插入到左邊元素的右邊   e.重複步驟b,直到處理完畢所有元素爲止;

######2.3 選擇排序算法(熟悉)
(1)算法流程
   a.從第一個元素起依次取出,並且假定取出的元素爲這一組元素中的最小值,
     使用min記錄下標;
   b.使用min記錄的元素與後續元素依次比較大小;
   c.若找到了比min記錄的元素還小的元素,則使用min變量重新記錄該元素的下標;
   d.直到min記錄的元素與後續所有元素比較完畢後,交換min記錄的元素與最開始假定的
     元素,經過這一步最前面的元素將是這組元素中的最小值;
   e.重複步驟a,直到處理完畢所有元素爲止;

######2.4 快速排序算法(重點)
(1)算法流程
   a.找到樣本數列中的中間元素作爲基準值單獨保存起來;
   b.分別使用左右兩邊的元素與基準值比較大小,將所有比基準值小的元素放在基準值
     的左邊,將所有比基準值大和相等的元素放到基準值的右邊,這個過程叫做分組;  
   c.經過這一步,左邊的元素小於基準值,右邊的元素大於等於基準值,但左右兩邊
     的分組內部不一定有序,此時需要對左右兩邊的分組進行再次分組;
   d.直到處理完畢所有元素爲止;
 

####常見面試題:
1. wait()和 sleep()區別:
http://www.cnblogs.com/renhui/p/6069353.html  
解釋:
sleep(有參數)方法是Thread類裏面的,主要的意義就是讓當前線程停止執行,讓出cpu給其他的線程,但是不會釋放對象鎖資源以及監控的狀態,當指定的時間到了之後又會自動恢復運行狀態。
wait()方法是Object類裏面的,主要的意義就是讓線程放棄當前的對象的鎖,進入等待此對象的等待鎖定池,只有針對此對象調動notify方法後本線程才能夠進入對象鎖定池準備獲取對象鎖進入運行狀態。
區別是:
(a)sleep()有參數:毫秒            wait()無參數
(b)sleep()睡眠時,保持對象鎖,仍然佔有該鎖;而wait()睡眠時,釋放對象鎖。
但是wait()和sleep()都可以通過interrupt()方法打斷線程的暫停狀態,從而使線程立刻拋出InterruptedException(但不建議使用該方法)。
2. final, finally ,finalize
http://www.cnblogs.com/xiaomoxian/p/5184520.html 
 final:關鍵字通常指的是“無法改變的”
final可以修飾變量(必須給賦值且值不能更改)、方法(無法被重寫)和類(無法被繼承)。
finally:關鍵字。對於一些代碼,可能會希望無論try塊中的異常是否拋出,它們都能夠執行。這通常適用於善後(內存回收之外)的工作。
finalize():方法。垃圾回收器準備釋放內存的時候,會先調用finalize()。
       (1).對象不一定會被回收。
       (2).垃圾回收不是析構函數。
       (3).垃圾回收只與內存有關。
     (4).Java GC(Garbage Collection,垃圾收集,垃圾回收)機制和finalize()都是靠不住的,只要JVM還沒有快到耗盡內存的地步,它是不會浪費時間進行垃圾回收的。
3. 修飾詞順序:
[訪問權限] [abstract] [static] [final] [transient] [volatile] [synchronized] [native] [strictfp]
4. run方法和start方法
java Thread中,run方法和start方法的區別,下面說法錯誤的是?
這裏需要注意Thread的start()與run()方法: 
用start()方法才能真正啓動線程,此時線程會處於就緒狀態,一旦得到時間片,就會調用線程的run()方法進入運行狀態; 
而run()方法只是普通的方法,如果直接調用run()方法,則會按照順序執行主線程這一個線程
1.start方法          
用 start方法來啓動線程,是真正實現了多線程, 通過調用Thread類的start()方法來啓動一個線程,這時此線程處於就緒(可運行)狀態,並沒有運行,一旦得到cpu時間片,就開始執行run()方法。但要注意的是,此時無需等待run()方法執行完畢,即可繼續執行下面的代碼。所以run()方法並沒有實現多線程。     
2.run方法          
run()方法只是類的一個普通方法而已,如果直接調用Run方法,程序中依然只有主線程這一個線程,其程序執行路徑還是隻有一條,還是要順序執行,還是要等待run方法體執行完畢後纔可繼續執行下面的代碼。

5.Collection與Collections的區別?  
java.util.Collection:
1、是一個集合接口。它提供了對集合對象進行基本操作的通用接口方法。
2、Collection接口在Java類庫中有很多具體的實現。比如SET LIST
3、Collection接口的意義是爲各種具體的集合提供了最大化的統一操作方式。
實例: public interface Collection<E> extends Iterable<E> {}
    List l1 = new LinkedList();  l1.add(new Name("Kael","M"));
java.util.Collections:
1、是一個包裝類。它包含有各種有關集合操作的靜態多態方法。此類不能實例化,就像一個工具類,服務於Java的Collection框架。但是可以被調用。
實例:Collections.sort(l1); 
http://blog.csdn.net/hz_lizx/article/details/54909082 
6.構造器Constructor是否可被override(覆蓋)?
https://www.cnblogs.com/guweiwei/p/6596542.html
構造器Constructor不能被繼承,因此不能重寫Override,但可以被重載Overload。
Constructor不能被繼承,所以Constructor也就不能被override。每一個類必須有自己的構造函數,負責構造自己這部分的構造。子類不會覆蓋父類的構造函數,相反必須負責在一開始調用父類的構造函數。
7.數組有沒有length()這個方法? String有沒有length()這個方法?

數組有
static int    getLength(Object array) 
          以 int 形式返回指定數組對象的長度。

 String有
 int    length() 
          返回此字符串的長度。
8.什麼是反射API?它是如何實現的?
http://blog.csdn.net/BuddyUU/article/details/52458241
在JDK中,主要由以下類來實現Java反射機制,這些類(除了第一個)都位於java.lang.reflect包中
  Class類:代表一個類,位於java.lang包下。
  Field類:代表類的成員變量(成員變量也稱爲類的屬性)。
  Method類:代表類的方法。
  Constructor類:代表類的構造方法。
  Array類:提供了動態創建數組,以及訪問數組的元素的靜態方法。
short s1 = 1; s1 = s1 + 1;有什麼錯? short s1 = 1; s1 += 1;有什麼錯? 
http://bbs.itheima.com/thread-127149-1-1.html
short s1 = 1; s1 = s1 + 1; 第二句Type mismatch: cannot convert from int to short 1默認爲INT類型。
對於+=Java也會自動強轉。對於b+=1,Java會轉成b = (short)(b+1)。
同樣,對於+=Java也會自動強轉。對於b+=1,Java會轉成b = (short)(b+1)
9.abstract class和interface有什麼區別?
 抽象類{
抽象方法();
}只能被繼承無法被實例化
Interface接口{
抽象方法和成員變量集合
}
1.一個類可以實現多個接口 ,但卻只能繼承最多一個抽象類。
2.抽象類可以包含具體的方法 , 接口的所有方法都是抽象的。
3.抽象類可以聲明和使用字段 ,接口則不能,但接口可以創建靜態的final常量。
4.接口的方法都是public的,抽象類的方法可以是public,protected,private或者默認的package;
5.抽象類可以定義構造函數,接口卻不能。 
什麼時候使用接口和抽象類?
看你想實現什麼功能。使用抽象類是爲了代碼的複用,而使用接口的動機是爲了實現多態性。

10.Integer和int的區別?
int 是基本類型,直接存數值,而integer是對象,用一個引用指向這個對象
1.Java 中的數據類型分爲基本數據類型和複雜數據類型
int 是前者而integer 是後者(也就是一個類);因此在類進行初始化時int類的變量初始爲0.而Integer的變量則初始化爲null.
 int i =1;Integer i= new Integer(1);(要把integer 當做一個類看);但由於有了自動裝箱和拆箱  (http://www.cnblogs.com/shenliang123/archive/2012/04/16/2451996.html),
  使得對Integer類也可使用:Integer i= 1;       
總而言之:如果我們定義一個int類型的數,只是用來進行一些加減乘除的運算or作爲參數進行傳遞,那麼就可以直接聲明爲int基本數據類型,但如果要像
對象一樣來進行處理,那麼就要用Integer來聲明一個對象
11.JAVA內省機制
http://blog.csdn.net/hahalzb/article/details/5972421 
1).內省(Introspector)是Java 語言對Bean類屬性、事件的一種缺省處理方法。例如類 A 中有屬性 name, 那我們可以通過 getName,setName 來得到其值或者設置新的值。通過 getName/setName 來訪問 name 屬性,這就是默認的規則。 

JAVA內省反射機制三部曲:http://www.cnblogs.com/zqmingok/articles/1713520.html 
   

12.黑盒測試白盒測試
白盒測試:是通過程序的源代碼進行測試而不使用用戶界面。這種類型的測試需要從代碼句法發現內部代碼在算法,溢出,路徑,條件等等中的缺點或者錯誤,進而加以修正。
黑盒測試:又被稱爲功能測試、數據驅動測試或基於規格說明的測試,是通過使用整個軟件或某種軟件功能來嚴格地測試, 而並沒有通過檢查程序的源代碼或者很清楚地瞭解該軟件的源代碼程序具體是怎樣設計的。測試人員通過輸入他們的數據然後看輸出的結果從而瞭解軟件怎樣工作。
13.hashcode和equals
https://www.jianshu.com/p/893231579218
1、如果兩個對象相等(equals() 返回 true),那麼它們的 hashCode()一定要相同;
2、如果兩個對象hashCode()相等,它們並不一定相等(equals() 不一定返回 true)。
14.HashTable和HashMap的區別詳解
http://blog.csdn.net/fujiakai/article/details/51585767 
HashMap是基於哈希表實現的,每一個元素是一個key-value對,其內部通過單鏈表解決衝突問題,容量不足(超過了閥值)時,同樣會自動增長。
      HashMap是非線程安全的,只是用於單線程環境下,多線程環境下可以採用concurrent併發包下的concurrentHashMap。
      HashMap 實現了Serializable接口,因此它支持序列化,實現了Cloneable接口,能被克隆。
二、Hashtable簡介
      Hashtable同樣是基於哈希表實現的,同樣每個元素是一個key-value對,其內部也是通過單鏈表解決衝突問題,容量不足(超過了閥值)時,同樣會自動增長。
      Hashtable也是JDK1.0引入的類,是線程安全的,能用於多線程環境中。
      Hashtable同樣實現了Serializable接口,它支持序列化,實現了Cloneable接口,能被克隆。
15.mybatis中#{}和${}的區別
1. #將傳入的數據都當成一個字符串,會對自動傳入的數據加一個雙引號。如:order by #user_id#,如果傳入的值是111,那麼解析成sql時的值爲order by "111", 如果傳入的值是id,則解析成的sql爲order by "id".
  
2. $將傳入的數據直接顯示生成在sql中。如:order by $user_id$,如果傳入的值是111,那麼解析成sql時的值爲order by user_id,  如果傳入的值是id,則解析成的sql爲order by id.
  
3. #方式能夠很大程度防止sql注入。
  
4.$方式無法防止Sql注入。

5.$方式一般用於傳入數據庫對象,例如傳入表名.
  
6.一般能用#的就別用$.

MyBatis排序時使用order by 動態參數時需要注意,用$而不是#
16.redis、memcache、mongoDB有哪些區別
https://segmentfault.com/q/1010000002588088 
Memcached
Memcached的優點:
Memcached可以利用多核優勢,單實例吞吐量極高,可以達到幾十萬QPS(取決於key、value的字節大小以及服務器硬件性能,日常環境中QPS高峯大約在4-6w左右)。適用於最大程度扛量。
支持直接配置爲session handle。
坑少。
Memcached的侷限性:
只支持簡單的key/value數據結構,不像Redis可以支持豐富的數據類型。
無法進行持久化,數據不能備份,只能用於緩存使用,且重啓後數據全部丟失。
無法進行數據同步,不能將MC中的數據遷移到其他MC實例中。
Memcached內存分配採用Slab Allocation機制管理內存,value大小分佈差異較大時會造成內存利用率降低,並引發低利用率時依然出現踢出等問題。需要用戶注重value設計。
Redis
Redis的優點:
支持多種數據結構,如 string(字符串)、 list(雙向鏈表)、dict(hash表)、set(集合)、zset(排序set)、hyperloglog(基數估算)
支持持久化操作,可以進行aof及rdb數據持久化到磁盤,從而進行數據備份或數據恢復等操作,較好的防止數據丟失的手段。
支持通過Replication進行數據複製,通過master-slave機制,可以實時進行數據的同步複製,支持多級複製和增量複製,master-slave機制是Redis進行HA的重要手段。
單線程請求,所有命令串行執行,併發情況下不需要考慮數據一致性問題。
支持pub/sub消息訂閱機制,可以用來進行消息訂閱與通知。
支持簡單的事務需求,但業界使用場景很少,並不成熟。
Redis的侷限性:
Redis只能使用單線程,性能受限於CPU性能,故單實例CPU最高才可能達到5-6wQPS每秒(取決於數據結構,數據大小以及服務器硬件性能,日常環境中QPS高峯大約在1-2w左右)。
支持簡單的事務需求,但業界使用場景很少,並不成熟,既是優點也是缺點。
Redis在string類型上會消耗較多內存,可以使用dict(hash表)壓縮存儲以降低內存耗用。
:)以下是我個人的補充
Mc和Redis都是Key-Value類型,不適合在不同數據集之間建立關係,也不適合進行查詢搜索。比如redis的keys pattern這種匹配操作,對redis的性能是災難。
Mogodb
mogodb是一種文檔性的數據庫。先解釋一下文檔的數據庫,即可以存放xml、json、bson類型系那個的數據。這些數據具備自述性(self-describing),呈現分層的樹狀數據結構。redis可以用hash存放簡單關係型數據。
mogodb存放json格式數據。
適合場景:事件記錄、內容管理或者博客平臺,比如評論系統。
nosq的產品目前很多,架構師的選擇導向主要有以下兩個因素:
1)適合應用程序的使用場景,比如評論系統用比較適合使用mogodb,而mc也可以實現(應用程序把數據轉化成json存入,但是部分數據更新不方便)
2)團隊開發比較熟悉的技術,比如一個團隊一直在使用mc,因而有限選擇mc,而不是redis。
還有中嚴重的狀況,開發團隊一直使用mogodb,在適合kv nosq的場景下而繼續選擇mogodb。
17.Request中getContextPath、getServletPath、getRequestURI、request.getRealPath的區別。
假定你的web application 名稱爲news,你在瀏覽器中輸入請求路徑:
http://localhost:8080/news/main/list.jsp 
1.1 System.out.println(request.getContextPath());得到工程名
打印結果:/news1.2 System.out.println(request.getServletPath());得到當前頁面所在目錄下全名稱
打印結果:/main/list.jsp
1.3 System.out.println(request.getRequestURI()); 得到包含工程名的當前頁面全路徑
打印結果:/news/main/list.jsp
1.4 System.out.println(request.getRealPath("/"));  得到頁面所在服務器的全路徑:
打印結果:F:\Tomcat 6.0\webapps\news\test

18. 4種創建線程池的方式。
http://blog.csdn.net/yellowjianokok/article/details/52550257 
newCachedThreadPool創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閒線程,若無可回收,則新建線程。

newFixedThreadPool 創建一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。

newScheduledThreadPool 創建一個定長線程池,支持定時及週期性任務執行。

newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。
19. synchronized(class)、synchronized(this)與synchronized(object)
Synchronized:在多線程的情況下,由於同一進程的多個線程共享同一片存儲空間,在帶來方便的同時,也帶來了訪問衝突這個嚴重的問題。Java語言提供了專門機制以解決這種衝突,有效避免了同一個數據對象被多個線程同時訪問。
JAVA中synchronized關鍵字能夠作爲函數的修飾符,也可作爲函數內的語句,也就是平時說的同步方法和同步語句塊。
synchronized void f() { /* body */ } 和void f() { synchronized(this) { /* body */ } }是完全等價的。
class與this的幾種情況:
synchronized(class)
synchronized(this)

線程各自獲取monitor,不會有等待。
synchronized(this)
synchronized(this)

如果不同線程監視同一個實例對象,就會等待;如果不同的實例,不會等待。
synchronized(class)
synchronized(class)
如果不同線程監視同一個實例或者不同的實例對象,都會等待。
20. 靜態代碼塊(static block )作用
靜態代碼塊(static block ),不包含在任何方法體中當類被載入時,自動執行靜態代碼塊,且只被執行一次經常用於類屬性的初始化。
21. 類加載機制和雙親委派模型
http://www.importnew.com/18548.html  
類從被加載到虛擬機內存中開始,到卸載出內存爲止,它的整個生命週期包括:加載(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸載(Unloading)7個階段。其中準備、驗證、解析3個部分統稱爲連接(Linking)。如圖所示。
 
加載:
1.通過一個類的全限定名來獲取定義此類的二進制字節流
2. 將這個字節流所代表的靜態存儲結構轉化爲方法區的運行時數據結構;
3. 在內存中生成一個代表這個類的java.lang.Class對象,作爲方法區這個類的各種數據的訪問入口;
連接:
1.驗證:確保Class文件的字節流中包含的信息符合當前虛擬機的要求,並且不會危害虛擬機自身的安全。
2.準備:正式爲類變量分配內存並設置類變量初始值的階段,內存放在方法區。
3. 解析:是虛擬機將常量池內的符號引用替換爲直接引用的過程。
初始化:才真正開始執行類中定義的java程序代碼。初始化階段是執行類構造器<clinit>()方法。

雙親委派模型:
從Java虛擬機的角度來說,只存在兩種不同的類加載器:一種是啓動類加載器(Bootstrap ClassLoader),這個類加載器使用C++語言實現(HotSpot虛擬機中),是虛擬機自身的一部分;另一種就是所有其他的類加載器,這些類加載器都有Java語言實現,獨立於虛擬機外部,並且全部繼承自java.lang.ClassLoader。
 

某個特定的類加載器在接到加載類的請求時,首先將加載任務委託給父類加載器,依次遞歸,如果父類加載器可以完成類加載任務,就成功返回;只有父類加載器無法完成此加載任務時,才自己去加載。

快捷鍵:
Eclipse常見快捷鍵:
重置Eclipse界面:Windows--Perspective--Reset Perspective 重置ECLIPSE

alt+/   : 代碼聯想 *

shift+alt+s:代碼構建工具

ctrl+shift+x|y :切換選中字符大小寫

ctrl+d : 刪除鼠標所在當前行 * 

ctrl+t : 查看選中類名的子父類結構 * 
    
ctrl+o : 查看光標所在類的成員(方法,屬性,代碼塊) *

alt+↑  : 光標所在行代碼向上移動一行

alt+↓  : 光標所在行代碼向下移動一行

ctrl+alt+↑ : 光標所在行代碼向上複製一行 

ctrl+alt+↓ : 光標所在行代碼向下複製一行

shift+回車 : 向當前光標所在位置的下一行插入一行空行, 並將光標移至新的空行中 (忽略代碼的回車鍵) *

ctrl+1 : 幫助 * 

ctrl+2 : 快捷變量的生成 * 

ctrl+shift+o : 全局導包
開發工具快捷鍵
ctrl+N:新建
ctrl+1:提示錯誤信息
ctrl+D:刪除
ctrl+/:行註釋
ctrl+\:取消行註釋
ctrl+shift+/:代碼段註釋
ctrl+shift+\:取消代碼段註釋
ctrl+H:快速查找任何文件信息、字符信息
ctrl+shift+O:導包
ctrl+T:查找類(支持模糊查找)
ctrl+R:查找文件(支持模糊查找、支持資源文件查找)
ctrl+shift+I:debug模式下,查看當前執行代碼信息
ctrl+G:定位文件(不常用)


F5:進入方法內
F6:執行下一步
F7:跳出方法外
F8:執行到下一個斷點


  [1]: http://static.zybuluo.com/cnxielong/3e7b5jotwai0qwppv171yt1q/1.jpg
  [2]: http://static.zybuluo.com/cnxielong/jpy3e3grlsekhx2izsysp2pm/%E6%88%90%E5%91%98%E5%8F%98%E9%87%8F%E5%88%9D%E5%A7%8B%E5%8C%96.jpg
  [3]: http://static.zybuluo.com/cnxielong/syxe3gltmycic2ukkenhgw78/%E7%BB%A7%E6%89%BF.jpg
  [4]: http://static.zybuluo.com/cnxielong/diat6zso4rsn6a4840dbft02/%E4%BE%9D%E8%B5%96.jpg
  [5]: http://static.zybuluo.com/cnxielong/4ee25pl15g2b7vxdu0xtqr7s/%E8%81%9A%E5%90%88.jpg
  [6]: http://static.zybuluo.com/cnxielong/jpy3e3grlsekhx2izsysp2pm/%E6%88%90%E5%91%98%E5%8F%98%E9%87%8F%E5%88%9D%E5%A7%8B%E5%8C%96.jpg
  [7]: http://static.zybuluo.com/cnxielong/eso806kiunnylxp2m4h5ujsh/%E5%BC%95%E7%94%A8%E7%B1%BB%E5%9E%8B.jpg
  [8]: http://static.zybuluo.com/cnxielong/4cfj55ihick99ckcwtjukh0i/image.png

 

 

 String有

 int

length()
          返回此字符串的長度。

8.什麼是反射API?它是如何實現的?

http://blog.csdn.net/BuddyUU/article/details/52458241

在JDK中,主要由以下類來實現Java反射機制,這些類(除了第一個)都位於java.lang.reflect包中

  Class類:代表一個類,位於java.lang包下。

  Field類:代表類的成員變量(成員變量也稱爲類的屬性)。

  Method類:代表類的方法。

  Constructor類:代表類的構造方法。

  Array類:提供了動態創建數組,以及訪問數組的元素的靜態方法。

short s1= 1; s1 = s1 + 1;有什麼錯? shorts1 = 1; s1 += 1;有什麼錯?

http://bbs.itheima.com/thread-127149-1-1.html

short s1= 1; s1 = s1 + 1; 第二句Typemismatch: cannot convert from int to short 1默認爲INT類型。

對於+=Java也會自動強轉。對於b+=1,Java會轉成b = (short)(b+1)。

同樣,對於+=Java也會自動強轉。對於b+=1,Java會轉成b = (short)(b+1)

9.abstract class和interface有什麼區別?

 抽象類{

抽象方法();

}只能被繼承無法被實例化

Interface接口{

抽象方法和成員變量集合

}

1.一個類可以實現多個接口 ,但卻只能繼承最多一個抽象類。

2.抽象類可以包含具體的方法 , 接口的所有方法都是抽象的。

3.抽象類可以聲明和使用字段 ,接口則不能,但接口可以創建靜態的final常量。

4.接口的方法都是public的,抽象類的方法可以是public,protected,private或者默認的package;

5.抽象類可以定義構造函數,接口卻不能。 

什麼時候使用接口和抽象類?

看你想實現什麼功能。使用抽象類是爲了代碼的複用,而使用接口的動機是爲了實現多態性。

 

10.Integer和int的區別?

int 是基本類型,直接存數值,而integer是對象,用一個引用指向這個對象

1.Java 中的數據類型分爲基本數據類型和複雜數據類型

int 是前者而integer 是後者(也就是一個類);因此在類進行初始化時int類的變量初始爲0.而Integer的變量則初始化爲null.

 int i =1;Integeri= new Integer(1);(要把integer當做一個類看);但由於有了自動裝箱和拆箱  (http://www.cnblogs.com/shenliang123/archive/2012/04/16/2451996.html),

  使得對Integer類也可使用:Integeri= 1;       

總而言之:如果我們定義一個int類型的數,只是用來進行一些加減乘除的運算or作爲參數進行傳遞,那麼就可以直接聲明爲int基本數據類型,但如果要像

對象一樣來進行處理,那麼就要用Integer來聲明一個對象

11.JAVA內省機制

http://blog.csdn.net/hahalzb/article/details/5972421

1).內省(Introspector)是Java 語言對Bean類屬性、事件的一種缺省處理方法。例如類 A 中有屬性 name, 那我們可以通過getName,setName 來得到其值或者設置新的值。通過getName/setName 來訪問 name 屬性,這就是默認的規則。 

 

JAVA內省反射機制三部曲:http://www.cnblogs.com/zqmingok/articles/1713520.html

  

 

 

 

12.黑盒測試白盒測試

白盒測試:是通過程序的源代碼進行測試而不使用用戶界面。這種類型的測試需要從代碼句法發現內部代碼在算法,溢出,路徑,條件等等中的缺點或者錯誤,進而加以修正。

黑盒測試:又被稱爲功能測試、數據驅動測試或基於規格說明的測試,是通過使用整個軟件或某種軟件功能來嚴格地測試, 而並沒有通過檢查程序的源代碼或者很清楚地瞭解該軟件的源代碼程序具體是怎樣設計的。測試人員通過輸入他們的數據然後看輸出的結果從而瞭解軟件怎樣工作。

13.hashcode和equals

https://www.jianshu.com/p/893231579218

1、如果兩個對象相等(equals()返回 true),那麼它們的hashCode()一定要相同;
2、如果兩個對象hashCode()相等,它們並不一定相等(equals()不一定返回 true)。

14.HashTable和HashMap的區別詳解

http://blog.csdn.net/fujiakai/article/details/51585767

HashMap是基於哈希表實現的,每一個元素是一個key-value對,其內部通過單鏈表解決衝突問題,容量不足(超過了閥值)時,同樣會自動增長。

      HashMap是非線程安全的,只是用於單線程環境下,多線程環境下可以採用concurrent併發包下的concurrentHashMap

      HashMap 實現了Serializable接口,因此它支持序列化,實現了Cloneable接口,能被克隆。

二、Hashtable簡介

      Hashtable同樣是基於哈希表實現的,同樣每個元素是一個key-value對,其內部也是通過單鏈表解決衝突問題,容量不足(超過了閥值)時,同樣會自動增長。

      Hashtable也是JDK1.0引入的類,是線程安全的,能用於多線程環境中。

      Hashtable同樣實現了Serializable接口,它支持序列化,實現了Cloneable接口,能被克隆。

15.mybatis中#{}和${}的區別

1. #將傳入的數據都當成一個字符串,會對自動傳入的數據加一個雙引號。如:orderby #user_id#,如果傳入的值是111,那麼解析成sql時的值爲order by"111", 如果傳入的值是id,則解析成的sql爲order by"id".
  
2. $將傳入的數據直接顯示生成在sql中。如:order by $user_id$,如果傳入的值是111,那麼解析成sql時的值爲order byuser_id,  如果傳入的值是id,則解析成的sql爲order byid.
  
3. #方式能夠很大程度防止sql注入。
  
4.$方式無法防止Sql注入。

5.$方式一般用於傳入數據庫對象,例如傳入表名.
  
6.一般能用#的就別用$.

MyBatis排序時使用order by動態參數時需要注意,用$而不是#

16.redis、memcache、mongoDB有哪些區別

https://segmentfault.com/q/1010000002588088

Memcached
Memcached的優點:
Memcached可以利用多核優勢,單實例吞吐量極高,可以達到幾十萬QPS(取決於keyvalue的字節大小以及服務器硬件性能,日常環境中QPS高峯大約在4-6w左右)。適用於最大程度扛量。
支持直接配置爲sessionhandle
坑少。
Memcached的侷限性:
只支持簡單的key/value數據結構,不像Redis可以支持豐富的數據類型。
無法進行持久化,數據不能備份,只能用於緩存使用,且重啓後數據全部丟失。
無法進行數據同步,不能將MC中的數據遷移到其他MC實例中。
Memcached內存分配採用SlabAllocation機制管理內存,value大小分佈差異較大時會造成內存利用率降低,並引發低利用率時依然出現踢出等問題。需要用戶注重value設計。

Redis
Redis的優點:
支持多種數據結構,如 string(字符串)、 list(雙向鏈表)dict(hash)set(集合)、zset(排序set)hyperloglog(基數估算)
支持持久化操作,可以進行aofrdb數據持久化到磁盤,從而進行數據備份或數據恢復等操作,較好的防止數據丟失的手段。
支持通過Replication進行數據複製,通過master-slave機制,可以實時進行數據的同步複製,支持多級複製和增量複製,master-slave機制是Redis進行HA的重要手段。
單線程請求,所有命令串行執行,併發情況下不需要考慮數據一致性問題。
支持pub/sub消息訂閱機制,可以用來進行消息訂閱與通知。
支持簡單的事務需求,但業界使用場景很少,並不成熟。

Redis的侷限性:
Redis只能使用單線程,性能受限於CPU性能,故單實例CPU最高才可能達到5-6wQPS每秒(取決於數據結構,數據大小以及服務器硬件性能,日常環境中QPS高峯大約在1-2w左右)。
支持簡單的事務需求,但業界使用場景很少,並不成熟,既是優點也是缺點。
Redisstring類型上會消耗較多內存,可以使用dicthash表)壓縮存儲以降低內存耗用。

:)以下是我個人的補充
McRedis都是Key-Value類型,不適合在不同數據集之間建立關係,也不適合進行查詢搜索。比如rediskeys pattern這種匹配操作,對redis的性能是災難。

Mogodb
mogodb是一種文檔性的數據庫。先解釋一下文檔的數據庫,即可以存放xmljsonbson類型系那個的數據。這些數據具備自述性(self-describing),呈現分層的樹狀數據結構。redis可以用hash存放簡單關係型數據。
mogodb存放json格式數據。
適合場景:事件記錄、內容管理或者博客平臺,比如評論系統。

nosq的產品目前很多,架構師的選擇導向主要有以下兩個因素:
1)適合應用程序的使用場景,比如評論系統用比較適合使用mogodb,而mc也可以實現(應用程序把數據轉化成json存入,但是部分數據更新不方便)
2)團隊開發比較熟悉的技術,比如一個團隊一直在使用mc,因而有限選擇mc,而不是redis
還有中嚴重的狀況,開發團隊一直使用mogodb,在適合kv nosq的場景下而繼續選擇mogodb

17.Request中getContextPath、getServletPath、getRequestURI、request.getRealPath的區別。

假定你的webapplication 名稱爲news,你在瀏覽器中輸入請求路徑:

http://localhost:8080/news/main/list.jsp

1.1 System.out.println(request.getContextPath());得到工程名

打印結果:/news1.2System.out.println(request.getServletPath());得到當前頁面所在目錄下全名稱

打印結果:/main/list.jsp

1.3System.out.println(request.getRequestURI()); 得到包含工程名的當前頁面全路徑

打印結果:/news/main/list.jsp

1.4System.out.println(request.getRealPath("/"));  得到頁面所在服務器的全路徑:

打印結果:F:\Tomcat6.0\webapps\news\test

 

18. 4種創建線程池的方式。

http://blog.csdn.net/yellowjianokok/article/details/52550257

newCachedThreadPool創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閒線程,若無可回收,則新建線程。


newFixedThreadPool 創建一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。


newScheduledThreadPool 創建一個定長線程池,支持定時及週期性任務執行。
 

newSingleThreadExecutor創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO,LIFO, 優先級)執行。

19. synchronized(class)、synchronized(this)與synchronized(object)

Synchronized:在多線程的情況下,由於同一進程的多個線程共享同一片存儲空間,在帶來方便的同時,也帶來了訪問衝突這個嚴重的問題。Java語言提供了專門機制以解決這種衝突,有效避免了同一個數據對象被多個線程同時訪問。

JAVA中synchronized關鍵字能夠作爲函數的修飾符,也可作爲函數內的語句,也就是平時說的同步方法和同步語句塊。

synchronized void f() { /* body */ } void f() { synchronized(this) { /*body */ } }是完全等價的。

class與this的幾種情況:
synchronized(class)
synchronized(this)
 

線程各自獲取monitor,不會有等待。

synchronized(this)
synchronized(this)
 

如果不同線程監視同一個實例對象,就會等待;如果不同的實例,不會等待。

synchronized(class)
synchronized(class)
如果不同線程監視同一個實例或者不同的實例對象,都會等待。

20.靜態代碼塊(static block )作用

靜態代碼塊(staticblock ),不包含在任何方法體中當類被載入時,自動執行靜態代碼塊,且只被執行一次經常用於類屬性的初始化。

21.類加載機制和雙親委派模型

http://www.importnew.com/18548.html 

類從被加載到虛擬機內存中開始,到卸載出內存爲止,它的整個生命週期包括:加載(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸載(Unloading)7個階段。其中準備、驗證、解析3個部分統稱爲連接(Linking)。如圖所示。

加載:

1.通過一個類的全限定名來獲取定義此類的二進制字節流

2. 將這個字節流所代表的靜態存儲結構轉化爲方法區的運行時數據結構;

3. 在內存中生成一個代表這個類的java.lang.Class對象,作爲方法區這個類的各種數據的訪問入口;

連接:

1.驗證:確保Class文件的字節流中包含的信息符合當前虛擬機的要求,並且不會危害虛擬機自身的安全。

2.準備:正式爲類變量分配內存並設置類變量初始值的階段,內存放在方法區。

3. 解析:是虛擬機將常量池內的符號引用替換爲直接引用的過程。

初始化:才真正開始執行類中定義的java程序代碼。初始化階段是執行類構造器<clinit>()方法。

 

雙親委派模型:

從Java虛擬機的角度來說,只存在兩種不同的類加載器:一種是啓動類加載器(BootstrapClassLoader),這個類加載器使用C++語言實現(HotSpot虛擬機中),是虛擬機自身的一部分;另一種就是所有其他的類加載器,這些類加載器都有Java語言實現,獨立於虛擬機外部,並且全部繼承自java.lang.ClassLoader。

 

 

某個特定的類加載器在接到加載類的請求時,首先將加載任務委託給父類加載器,依次遞歸,如果父類加載器可以完成類加載任務,就成功返回;只有父類加載器無法完成此加載任務時,才自己去加載。

 

 

 

 

 

 

 

快捷鍵:

Eclipse常見快捷鍵:

重置Eclipse界面:Windows--Perspective--Reset Perspective 重置ECLIPSE
 
alt+/   : 代碼聯想 *
 
shift+alt+s:代碼構建工具
 
ctrl+shift+x|y :切換選中字符大小寫
 
ctrl+d : 刪除鼠標所在當前行 * 
 
ctrl+t : 查看選中類名的子父類結構 * 
       
ctrl+o : 查看光標所在類的成員(方法,屬性,代碼塊) *
 
alt+  : 光標所在行代碼向上移動一行
 
alt+  : 光標所在行代碼向下移動一行
 
ctrl+alt+ : 光標所在行代碼向上複製一行
 
ctrl+alt+ : 光標所在行代碼向下複製一行
 
shift+回車 : 向當前光標所在位置的下一行插入一行空行, 並將光標移至新的空行中 (忽略代碼的回車鍵) *
 
ctrl+1 : 幫助 * 
 
ctrl+2 : 快捷變量的生成 * 
 
ctrl+shift+o : 全局導包

開發工具快捷鍵

ctrl+N:新建
ctrl+1:提示錯誤信息
ctrl+D:刪除
ctrl+/:行註釋
ctrl+\:取消行註釋
ctrl+shift+/:代碼段註釋
ctrl+shift+\:取消代碼段註釋
ctrl+H:快速查找任何文件信息、字符信息
ctrl+shift+O:導包
ctrl+T:查找類(支持模糊查找)
ctrl+R:查找文件(支持模糊查找、支持資源文件查找)
ctrl+shift+Idebug模式下,查看當前執行代碼信息
ctrl+G:定位文件(不常用)

DUBUG模式開發

注意:從今天開始,包括後續進入企業中,所有開發環境下的項目啓動,都要用debug模式啓動。
 
F5:進入方法內
F6:執行下一步
F7:跳出方法外
F8:執行到下一個斷點

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章