1. 程式人生 > >【計算機基礎】Java學習篇(四) 認識類與物件(打包器、陣列和字串)

【計算機基礎】Java學習篇(四) 認識類與物件(打包器、陣列和字串)

介紹完基本型別,下面介紹類型別。

瞭解物件與參考的關係,認識打包器,以及陣列物件、字串物件。

一、類與物件

      1.建立類 

        編寫程式需要使用物件(Object),產生物件必須先定義類(Class),類就像是設計圖,而物件是類的一個例項。(Instance)

        類定義用關鍵詞class。比如定義一個衣服類:class Clothes;

        新建一個物件:new Clothes();

        要給物件起名字:Clothes c;術語稱:宣告參考名稱(Reference Name)或參考變數(Reference Variable)

這個名字要和新建的物件進行繫結。術語稱:將c名稱參考(Refer)至新建物件,用“=”指定。

        new Clothes()= Clothes c;

        類擁有自己的變數,也叫作域(Field)成員、資料成員。比如衣服的顏色和尺碼。

class Clothes{
    String color;
    char size;

}

        我們建立好物件後可以用 物件名.資料成員的格式指定值。 比如c.color="red";       

      2.介紹兩個基本標準類

        1)獲取使用者輸入  java.util.Scanner 

        用System.in物件的read()方法可以取得使用者輸出,但此方法是以int型別返回讀入的字元編碼。

        還是用Scanner ——————————————————————————

        Scanner scanner=new Scanner(System.in);     // 建立例項,同時必須傳入java.io.InputStream的例項。

        scanner物件會幫你掃描標準輸入。

        獲取輸入:使用方法 nextInt()、nextByte()、nextFloat()……

        獲取整行:nextLine()

        2)java.math.BigDecimal

        Java語言遵守IEEE754浮點數運算(Floating-Point Arithmetic),使用分數和指數來表示浮點數。

0.5用1/2表示;0.75用1/2+1/4表示;0.875用1/2+1/4+1/8表示;0.1用1/16+1/32+1/256+1/512+1/4096…無限迴圈累加表示。因此,由於浮點數誤差的關係,double 0.1相加 ≠ 0.2,為了有更好的精確度,使用這個類。

BigDecimal a =new BigDecimal(“1.0”);         // 建立物件
BigDecimal b =new BigDecimal(“0.8”);

BigDecimal result =a.plus(b);                  // 呼叫方法

        加減乘除 plus()、substract()、multply()、divide()     

        因為做完運算後,還是BigDecimal型別,所以可以連續運算

        3)剩下還有許許多多的類和方法,我們可以查詢Java API文件來了解。在搜尋引擎查詢更方便。

          3.物件指定與相等性

              區分一下=和==的不同。(底層記憶體的實際運作沒有不同)

              對於基本型別,=是值複製;==是比較兩個變數的值。

              對於類型別的物件,=是指定參考名稱參考某個物件;==是比較兩個參考名稱是否參考同一個物件

              判斷物件的值是否相同可以用equals()方法

三、基本型別打包器     

      1.打包基本型別

         基本型別 int、long、double、float、boolean,使用在於效率,然而很多時候我們操縱的都是物件,物件能攜帶更多資訊。

         我們需要使用Integer、Long、Double、Float、Boolean等類打包成物件來操作。這些所謂的類即打包器(Wrapper)目的就是提供物件例項作為“殼”

打包器是類,是Number抽象類的子類,擁有自己的方法,在java.lang包裡。

int a=10;

Integer aa=new Integer(a);              // 打包基本型別


         打包器可以使用方法,如doubleValue()將打包值以double型別返回,這樣可以進行運算

         比較Number類的物件值大小,使用compareTo(),如a.compareTo (b),值相同為0,小於為-1,大於為1

       2.自動裝箱與拆箱

         J2SE 5以後支援自動裝箱(Autoboxing)、拆箱(Unboxing)。

比如:自動裝箱Integer a=10;可以直接使用,執行時會參考Integer的例項。       

          自動拆箱:int b = a;     自動取得打包的int型別再指定給b。

          運算也可以自動裝箱、拆箱:    int型別和Integer型別可以相互運算。

       3.自動裝箱拆箱的內幕

實質是編譯程式蜜糖(Compiler Sugar),也就是說寫的方便,編譯的時候會將程式程式碼展開。

          比如Integer num=100;編譯程式會展開為,Integer localInteger = Integer.valueOf(100);

          (我們可以通過反編譯程式比如JD、JAD來看到)

          ※ 自動拆箱實際程式碼 intValue()

          比如,Integer i = null; int j=i;這兩句編譯沒有問題,但是執行會產生NullPointerException空指向錯誤。

          實際程式碼是:Object localObject=null;int i=localObject.intValue();

也就是說實質上建立了一個空物件,然後進行設值,然而null是特殊物件,是空的,這個名稱沒有參考到任何物件實體上,所以無法呼叫方法。 

          ※ 自動裝箱實際程式碼 valueOf()

          比如,Integer i1=100;Integer i2=100;那麼i1是否等於i2呢?答案是:i1=i2。

                    Integeri1=200; Integer i2=200;換了數值答案卻是i1≠ i2。

          實際程式碼是打包器呼叫了valueOf(int i)這個方法進行拆箱。這個方法的意思是如果傳入的int在IntegerCache.low(-128)與IntegerCache.high(127)之間,那就嘗試看前面快取(Cache)中有沒有打包過相同的值,如果有就返回。

          明白了其中的原理,我們也就明白了為什麼100和200的兩個物件會不一樣,因為i2在100的時候會從前面i1的快取中直接傳回Integer例項。而i2=200的時候就要重新建立例項了。

          當然,數值也是可以修改的。自行查閱。

三、陣列物件

       1.陣列基礎

          陣列基本上是用來收集資料的,是具有索引的資料結構。索引i從0開始。                

           宣告陣列建議把[ ]放在類關鍵詞的後面。這是Java的開發習慣。

           陣列建立方法一:int[ ]  a={1,2,3,4,5};  

           指定索引:a[i]

           陣列長度:a.length

           遍歷輸出每一個元素:for迴圈。(但只是從頭遞增到尾,和索引值毫無關係)

           循序的輸出陣列值:增強式for迴圈(Enhanced for Loop)

           語法:for(int x:陣列名){

           輸出x}

           編譯程式蜜糖。實際程式碼是把原陣列複製到新陣列上,然後用新陣列的長度進行for迴圈遍歷,把遍歷的值存給一個int變數進行輸出。

           二維陣列宣告並賦值:int[ ] [ ] a={

                                 {1,2,3},

                                 {4,5,6}

             };

           指定索引:a[x] [y]

           有幾行:a.length

           一行多長:a[x].length

          遍歷輸出每一個元素:雙重for迴圈,外迴圈用x<a.length迴圈列,內迴圈用y<a[x].length迴圈每列的元素,最後輸出a[x][y]

          循序的輸出陣列值:增強式for迴圈。        

for(int[ ] x:a){                   // 抽出每一個組
    for(int y:x){                  // 抽出每一個元素
        輸出 y
    }
                                    
} 

       2.陣列物件

          前面介紹了陣列基礎知識,下面我們把陣列看作物件

          建立陣列方法二:int[ ]  a=new int[2]                     //  定義陣列可以用int[ ] a;但建立物件必須指定陣列長度。

          建立陣列方法三:int[ ] a=new int [ ] {0,0};          //  賦值書寫,不用指定陣列長度

          不同的型別的陣列元素有不同的初始值,我們可以使用java.util.Arrays的fill()方法設定新的初始值

          Arrays.fill(陣列名,初始值);

               

          建立陣列物件的類定義是由JVM動態產生。  

下面看二維陣列。

          實際上,Java的多維陣列都是由一維陣列組成。我們可以看作是int[ ]   [ ] a;

          比如int[ ] [ ] a=new int[2] [3]{

                                 {1,2,3},

                                 {4,5,6}

           };

          定義兩個一維陣列,每個陣列能存三個值。

          術語也就是,其中有2個int[ ]型別的索引,分別參考了長度為3的一維陣列。

           a.length等同於陣列a的參考物件有幾個索引,即也就是有幾個一維陣列

           a[x].length等同於索引x的參考物件的長度,即這個一維陣列的元素個數

當然二維陣列也可以是不規則陣列,不一定是矩陣。

int[ ] [ ] a=new int[2] [ ];

           a[0] =new int[ ]{1,2,3};

           a[1]=new int[ ]{1,2};

           這段程式碼先宣告有兩個索引,每個索引對應的物件都是null,即建立0個物件再分別參考一維陣列。

以上都是基本型別的例子,類型別也是同理,且可以結合自動裝箱而省略new物件。                   

        3.陣列複製

           首先我們明白陣列是物件,所以用=不是複製,而是繫結參考。

           基本型別陣列的複製:

           1、建立一個和原陣列等長的新陣列。int [ ] b=new int [a.length],然後for迴圈複製。

           2、建立等長新陣列,使用System.arraycopy(源陣列,源陣列的起始索引,目的陣列,目的陣列的起始索引,複製長度),這個方法有五個引數,使用原生方法複製比迴圈要快。

           3、不用建立新陣列,使用更方便的Arrays.copyOf(),可以自由建立更長的陣列。

                  int[ ]  新陣列名=Array.copyOf(源陣列名,新陣列長度)     

           類型別陣列的複製:

           1、淺層複製(Shallow Copy):for迴圈內,每個陣列物件複製,c2[i] = c1[i]。

                 複製陣列索引的物件,即複製了原陣列物件的參考,改變原陣列物件的資料成員,新陣列的物件也會改變。繫結在了一起。使用上面的兩個方法應用在類型別陣列,也一樣是淺層複製。

           2、深層複製(Deep Copy):for迴圈內,型別 c=new 型別(原陣列名[i].資料成員,……);新陣列名[i]=c;

                 重新建立物件,包括資料成員進行復制。即複製的物件也有自己的資料成員。

四、字串物件

            1.字串基礎

                1)字串:由字元組成的文字元號 

                2)本質打包字元陣列的物件。java.lang.String的例項。可以用雙引號建立。

                3)String類的幾個方法長度length(),顯示索引字元charAt(0),轉換大寫toUpperCase()

                4)字串與字元陣列的相互轉換:

                            作參new一個String例項:String 字串名=new String(字元陣列名)

                            呼叫方法拆穿字元陣列  :char[ ]  字元陣列名=字串名.toCharArray()

                5)字串解析成基本型別的方法:XXX.parseXXX(字串)。比如可以通過鍵盤輸入,解析成基本型別進行操作,但如果你的字串不包含可以轉換的基本型別,則會丟擲數字格式化錯誤NumberFormatException這個異常。

                6)程式進入點main()中的String[ ] args

                      在啟動JVM的時候,指定執行類的同時,還可以指定命令自變數(Command Line Arguments),

在命令列指定:>java com.faceno.FirstString 1 2 3 4

                      在IDE指定:專案配置引數

指定以後,這些自變數會收整合String陣列,由args參考。

                      相當於內建的String字串陣列,儲存初始化引數。

            2.字串特性

            3.字串編碼