我思故我強

          JAVA概念總結

          傳值與傳引

          嚴格來說,Java中所有方法參數都是傳值。因為即使是傳遞的參數是對象的引數時,引數本身也是傳值的。所有基本類型都是傳值的。

          傳值:被傳入的參數被視為內部的局域變量,其變化不影響外部變量的原始值。

          傳引對于引數本身來講也是傳值的,但是在方法內部若對引數所指向的對象屬性有改變,則會直接實時地影響所指向的對象屬性。

          理解傳引這一概念的最佳方式就是畫出指向圖。eg. Aà(Object)O 對于A本身而言它是傳值的,也就是說當A作為參數傳遞的時候,假若在方法內部把其它的引數賦給了A,但是當方法返回時,A仍舊是指向原來的對象,而不會改變。其次,對于傳引來說,假若在方法內部對A所指向的對象屬性有改變,那么對象屬性的改變會是直接實時的。

          再次強調,Java中所有的參數傳遞都是傳值的。

          傳值這種題型的考試很多,基本類型傳值問題考的較多的是對某一變量,故意用某一方法試圖改變它,然后方法返回時再打印它。按傳值的說法,實際上該變量并沒有改變。

          構造函數

          a.構造器沒有任何返回類型,哪怕是void也不行。假如指定了返回值,那么Java會視為一個普通的方法。

          b.如果沒有顯示地調用父類的構造器,Java總是自動地調用父類的默認構造器。(也就是第一行會默認為super( ))

          c.只要類中顯式地定義一個或多個構造器,那么Java不會再為你定義一個默認的構造器

          d.構造函數可以被重載,并且在其體內可以用this()和super()來調用其它的構造器。但是this()和super()只能放在構造函數體的第一行進行調用。

          e.構造器的修飾符只可以是接入控制符public、private、protected、(default)。其它修飾符一律不可。

          f.構造方法不可被繼承。

          重載與覆蓋

            重載的英文為Overload,而覆蓋的英文為Override。重載是出現在同一類中多個同名函數,而覆蓋是出現在類繼承體系中同名函數。(注意:覆蓋有時被稱為重寫)

            重載是依據同名方法參數的個數參數的類型參數的順序來確定的。方法的修飾符、返回值、拋出的異常均不能作為區分重載方法的依據。(繼承體系中也有重載現象)

            覆蓋是在繼承體系中子類覆蓋超類中定義的方法。子類中覆蓋方法的返回類型參數類型必須精確匹配。接入控制符只能更加公有化;拋出的異常是超類拋出的子集或不拋。

               (static方法不能覆蓋,private方法也不能覆蓋。Java視它們為被隱藏

                · 參數類型一致,返回類型不同,編譯錯誤,提示“試圖用不兼容的返回類型覆蓋”。

                · 只要參數類型不一致,返回類型同與不同,編譯都能通過,此不為覆蓋而是重載。

          多態

            多態是出現于類的繼承層次中,通過向上轉型方法重寫的機制來實現的。

            面向對象程序設計的目標是:希望所撰寫的程序代碼都只對基類進行操作。這么一來,當加入新的繼承類時,大部分程序代碼都不會受影響而改寫(也即是說代碼具有擴充性)。所以當調用新加入的繼承類時,都會首先向上轉型為基類。這就是多態的向上轉型。

            當你希望通過調用基類的方法而能讓繼承類產生正確的行為時,這顯然需要在繼承類進行重寫該方法。而究竟是該調用哪個繼承類,這是由Java的動態綁定決定的。

            多態最重要的一點在于run-time binding。多態是面向對象程序設計的目標。

            關于多態中覆蓋注意如下:

          屬性既可以繼承,也是可以“覆蓋”的。但是對屬性而言沒有動態綁定這一特性,所以覆蓋的屬性被認為是子類的特別屬性。從某種意義上來講,屬性決定了類(性質)。另一方面,申明的類型就決定了對象的屬性。這是因為,任何對象或變量等號右面是用來賦值給符合等號左面所申明類型的,所以左面的類型是先決條件,賦值必須要符合申明類型。對于向上轉型而言,因為等號右面的對象is a申明類型,所以是成立的。一定要記住,屬性永遠都是跟著申明類型走。但是,對方法而言是在運行時動態綁定的,它取決于對象自身的實際類型(實際上對方法而言,也是先檢查向上轉型后的基類該方法,若無該方法的定義,則編譯錯,然后再動態綁定到繼承類的覆蓋方法)。

          另外,static方法不能覆蓋,private方法也不能覆蓋。

          還需特別注意,方法覆蓋時,若覆蓋得不對(例如參數一致,僅依靠返回類型不同),則編譯會出錯,而不是被Java認為方法重載(除非參數類型也不一樣,這樣java會認為不是override,實際上它是overload)。

          類初始化

            類的初始化大致上有這么幾個方面。

          a.靜態變量的初始化 b.一般實例變量的初始化 c.構造函數的初始化

            初始化的難點在于繼承體系中。當有繼承體系時,初始化始終要遵循的原則就是,無論如何必先初始化基類

             0.當載入當前類時,若當前類有繼承體系,則依次無條件載入基類

             0’.先從最頂的基類開始順序初始化其靜態static變量,接著初始化當前類的靜態static變量(也就是說,static變量的初始化是伴隨著類被裝載時而初始化的,它的初始化在任何構造函數執行前)

             1.先從最頂端基類,構造基類對象。

               (假如構造函數中有this或super調用,則先執行此調用)

               1.1.首先按出現次序初始化其實例變量

                 1.2.再執行其構造函數體

             2.依次遞歸上述步驟

            <此外,實例變量可以不顯式初始化(系統會賦默認值),但是局部變量必須顯式初始化>

          異常

          throws是異常的申明,它置于方法的定義處;throw是異常的擲出,它置于方法體內。

          異常可分為可檢測異常和非檢測異常,調用申明為可檢測異常的方法時必須捕獲異常。

          a.方法申明了可檢測異常,則調用該方法的塊一定要捕獲異常,否則編譯出錯

             b.throw后面不能跟任何語句,否則編譯提示語句不可到達

               c.多個catch語句,要求更具體的異常在前,超類異常在后,否則編譯出錯

               d.finally語句會在return語句之前執行,即在跳出方法之前一定會執行finally語句

               e.假如遇到的是System.exit(0),則無論如何,程序馬上退出,finally語句不會執行

               f.方法申明了異常,但是在方法體內可以不顯示地用throw拋出異常

               g.沒有申明可檢測異常的方法調用時,不可用catch捕獲,否則編譯出錯

          其它注意:

          a子類中覆蓋的方法只能拋出父類方法拋出異常的子集,也可以不拋出任何異常(這本身就是子集)

             b 但是對于非檢測異常RuntimeException則不會受到上面的約束,它們可以被隨時拋出。也不受范圍限制。

              c 當繼承的子類沒有申明異常時,假如它的一個實例被申明為超類(向上轉型),這時再調用子類沒有申明異常的方法,而用了catch,程序也會編譯通過。(實際運行中調用的還是子類中的方法)

          equals()和==

            對于上述關于equals()總結如下:

             a.類型不兼容的兩個對象可以用equals(),但是只要比較的對象類型不同(哪怕值相同),永遠返回false

             b.對于沒有覆蓋equals()的類,即使對象類型相同,值也相同,但返回的仍舊是false,因為它用的是object的默認equals方法(與==相同)

             c然而對于覆蓋equals()的類,只要值相同,便返回true。這些類是String,Wrappers,Date,Calendar,BitSet等

            對于==總結如下:

             a.類型不兼容的兩個對象不可以用==,若用則編譯錯誤

             b.同種類型的對象,假如不是指引同一個對象,則返回為false(只有指向同一個內存塊的對象才返回true)

             c.對于String情況有些不同,因為String對象有字面量和構造函數之分。字面量對象是放在緩沖池中的,這意味著,如果兩個字面量值相同,則第二個對象會指向第一個已經存在的對象,而不會新產生,所以==返回的是true。用構造器產生的對象同一般對象。對于字面量來說,多個類共享的是同一個緩沖池。這意味著在另外一個類中創建一個先前類中已有的字面量字符串,則仍舊是同一對象。

                另外,注意,toUpperCase()、toLowerCase()方法而言,如果大小寫形式與原始String沒什么差別,方法返回原始對象,==返回true。

             d.對于基本類型而言,系統會自動先歸一精度,然后再比較值,若值相同則返回true。

          String

            String類最重要的一點在于“不變性(immutable)”。它的意思是一旦String類產生了就不會再改變了,若試圖改變它都會產生新的對象。

            String對象有字面量和構造函數之分。字面量對象是放在緩沖池中的,這意味著,如果兩個字面量值相同,則第二個對象會指向第一個已經存在的對象,而不會新產生,所以==返回的是true。用構造器產生的對象同一般對象。對于字面量來說,多個類共享的是同一個緩沖池。這意味著即使在另外一個類中創建一個先前類中已有的字面量字符串,則仍舊是同一對象。

            考試中需要注意的是:s=new String(“abc”);s+=”def”;System.out.println(s);

                                s=new String(“abc”);s.concat(“def”);System.out.prinln(s);

            前一程序打印為“abcdef”,后一程序打印為“abc”。區別是第一個程序又重新賦值給了s。而第二個程序中s.concat(“def”)只是產生了一個新的對象但沒有賦給誰,但原來的s不變。

            另外,對于StringBuffer而言是可變的,對它的任何改變都是實時的。

          包裝類

            包裝類是為了方便對基本數據類型操縱而出現的。有了包裝類就可以用很多的方法來操縱基本數據類型(沒有包裝類想直接對基本數據類型操作是不方便的,除非自己編寫方法)。

            要熟悉包裝類應該著種理解下面幾點:

            a.包裝類的構造器。一般說來,包裝類的構造器參數有兩種:基本數據值字符串

               注意:Boolean包裝類構造器當傳入字符串時,除了不分大小寫的true返回true外,其它字符串一律返回false

            b.常見的操作方法。例如:轉換為本基本類型或其它基本類型的方法

               eg. byteValue(),intValue()…;parseByte(String s),parseInt(String s)…

                 c.valueOf(各基本類型或字符串)的使用。ValueOf(str)是包裝類的靜態方法,作用等同于構造器。它會解析傳入的參數,然后構造一個相同類型的包裝類,并返回該包裝類。

                 例子:原始類型à字符串  (new Integer(101)).toString();String.valueOf(“101”)

                       字符串à(包裝類)à原始類型 Integer.parseInt(“string”);

          (new Integer(“101”)).doubleValue();Integer.valueOf(“101”).intValue()

          Math

            Math類中都是靜態方法。其中最易錯的是三個方法:ceil(),floor(),round()

          另外還需注意,有許多方法隨基本數據類型不同有多個重載版本。eg.abs(),max()

          a.ceil()方法。該方法返回類型為double,往單一的正坐標方向取最近的整數

          b.floor()方法。該方法返回類型類double,取最靠近其負向的整數。

          c.round()方法。它有兩個重載版本:double和float,返回分別為long和int

             long round(double a);int round(float)

             round()方法=Math.floor(a+0.5),這意味著正數5入,負數6入

             eg.System.out.println(Math.ceil(Double.MIN_VALUE))     //1.0

          System.out.println(Math.floor(-0.1))                //-1.0

          System.out.println(Math.round(-9.5))                //-9

          System.out.println(Math.round(-9.6))                //-10

          System.out.println(Math.round(Double.MIN_VALUE))    //0

          collection

            collection類提供了持有對象的便利性,并對持有對象的操作便利性。正如其名,收集意為將各種類型的對象收在一起,且數目不限(有點像收集袋)。收集會將放入其中的所有對象均視為Object(向上轉型),所以在取出元素對象時,必須顯式(即強制轉型)指出其類型。

            對象收集從整體上分為Collection接口和Map接口。這種分類的標準是:某個元素位置上放置元素對象的個數。顯然,Map接口放置的是一對。

            Collection接口又可擴展為兩個基本接口:List接口和Set接口。

            依上所述,對象收集可以劃分為四個基本的類型:Collection、List、Set、Map

            · Collection 它是一個基類的接口,對元素沒有任何的限制,可以重復并且無序。

            · List  從其名就知是有序的列表。它描述的是按順序將對象放入其中。顯然,后放入的元素有可能與先前放入的對象是相同的。所以,List是允許對象重復出現的有序列表。

            · Set   其實就是數學上所說的集合,它不允許有重復的元素。其中可以有空集(即null對象)。Set中的元素不要求有序。

            · Map   即映射,借助于key和value來描述對象的搜索。key域中要求唯一性(其實就是一個Set),value域可以允許有重復的元素(其實就是一個Collection)。另外注意:常見的HashMap是無序的,而TreeMap是有序的。

          標識符

            a.所有標識符的首字符必須是字母(大小寫)、下劃線_、美元符號$(或符號¥)

          b.接下來的可以是由數字(0-9)及首字符相同類型的字符(字母、_、$),其它任何特殊字符均不可

          c.標識符不能使用Java關鍵字和保留字(50個)。但是注意像java,Integer,sizeof,friendly等都不是Java的關鍵字

          d.標識符大小寫是敏感的,但沒有長度的限制。

          Switch(i)

            a.switch(i)中的參數最高精度是int(或者short,byte,char),但不可是long,float,double

            b.default語句可以放置于任何地方(default意為都不匹配case中的值)

            c.當語句中未加break語句時,則程序會從匹配的地方開始執行(包括匹配default語句),接下來所有的語句都會被執行(而不管匹配否),直到遇到break語句或switch尾部。

          垃圾收集

            a.只要一個對象失去了所有的reference,就可以考慮收集到垃圾收集堆了。

            B.當失去對一個對象的所有引用時,JVM只是考慮垃圾收集,但并不意味著就立刻收回這個對象的內存,甚至根本不收回。JVM僅會在需要更多的內存以繼續執行程序時,才會進行垃圾收集。

          C.多數情況下,你永遠不會知道垃圾收集什么時候會發生。Java將垃圾收集進程作為一個低優先級線程在運行。在Java中垃圾收集是不能被強迫立即執行的。調用System.gc()或Runtime.gc()靜態方法不能保證垃圾收集器的立即執行,因為,也許存在著更高優先級的線程。

          D.如果你想人工調用垃圾收集,并想在收集對象時執行一些你想要的任務,你就可以覆蓋一個叫finalize()的方法。java會為每一個對象只調用一次finalize()方法。finalize()方法必須被申明為protected的,不返回任何值(viod),而且要申明拋出一個Throwable對象,并一定要調用超類的finalize()方法(super.finalize())。

             eg.protected void finalize() throws Throwable(){

                   super.finalize();

                   …………;}

          is a & has a

            is a  描述的是一個超類和一個子類的關系,也即是繼承的關系。

            has a 描述的是一個對象的部分是另一個對象,也即是組合的關系(或稱為調用)。

          內類與匿名類

            內類是被包含的類中類,有三個方面需要注意:一般內類、方法內類、靜態內類。

            · 一般內類它可以被當做外類的一個“實例變量”來看待。因此,四個接入控制符public、protected、default、private。只是注意:要在外類的non-static函數外產生該內類對象,必須以OuterClassName.InnerClassName的形式指定該內類對象的類型申明一般內類必須得關聯至其外類的某個對象

                          一般內類不可擁有static成員。

          · 方法內類它屬于范圍型內類,也就是說你無法在方法外來調用內類,從這一點來講它可視為方法的局部變量。但是,雖然有它的范疇性,畢竟內類還是類,它不會像局部變量那樣隨著方法的返回就消失了,它仍舊被java視為類。

                        A.方法內類可以直接訪問外類的任何成員

                        B.方法內類只能訪問該方法中final型局部變量和final型的方法參數

                        C. 方法內類不可有任何接入控制符修飾(這一點與局部變量相同)

            · 靜態內類它在產生其對象時不需要存在一個外類對象。它可被視為static函數。

                       static內類可以置于接口中。

            · 匿 名 類它實際上是繼承自new類的一個無名類。New傳回的reference會被自動向上轉型。匿名類不能擁有構造器,但是可以通過其基類默認或帶參數的構造器來申明。

          匿名類添加任何修飾符(遵循超類的修飾符),也不可實現接口、拋出異常。

          斷言

            斷言是Java 1.4中新添加的功能,是Java中的一種新的錯誤檢查機制,它提供了一種在代碼中進行正確性檢查的機制,但是這項功能可以根據需要關閉。斷言包括:assert關鍵字,AssertionError類,以及在java.lang.ClassLoader中增加了幾個新的有關assert方法。

          assert最重要的特點是assert語句可以在運行時任意的開啟或關閉,默認情況下是關閉的。

          斷言語句有兩種合法的形式:a.assert expression_r1; b.assert expression_r1 : expression_r2;

          expression_r1是一條被判斷的布爾表達式,必須保證在程序執行過程中它的值一定是真;expression_r2是可選的,用于在expression_r1為假時,傳遞給拋出的異常AssertionError的構造器,因此expression_r2的類型必須是合法的AssertionError構造器的參數類型。AssertionError除了一個不帶參數的缺省構造器外,還有7個帶單個參數的構造器,分別為:object(eg.String)  boolean  char  int  long  float  double。第一種形式如果拋出異常,則調用AssertionError的缺省構造器,對于第二種形式,則根據expression_r2值的類型,分別調用7種單參數構造器中的一種。

          A.assert程序的編譯:javac -source 1.4 TestAssert.java(提示java按1.4版本編譯)

          B.assert程序的運行:java –ea TestAssert 或者 java –ea:TestAssert TestAssert

             其它的運行參數:java -ea:pkg0... TestAssert;java –esa;java –dsa(系統類斷言),另外,還可以同時組合用。當一個命令行使用多項 -ea -da 參數時,遵循兩個基本的原則:后面的參數設定會覆蓋前面參數的設定,特定具體的參數設定會覆蓋一般的參數設定

          C.AssertinError是Error的直接子類,因此代表程序出現了嚴重的錯誤,這種異常通常是不需要程序員使用catch語句捕捉的。

          D.使用assert的準則:assert語句的作用是保證程序內部的一致性,而不是用戶與程序之間的一致性,所以不應用在保證命令行參數的正確性。可以用來保證傳遞給private方法參數的正確性。因為私有方法只是在類的內部被調用,因而是程序員可以控制的,我們可以預期它的狀態是正確和一致的。公有方法則不適用。此外,assert語句可用于檢查任何方法結束時狀態的正確性,及在方法的開始檢查相關的初始狀態等等。

          assert語句并不構成程序正常運行邏輯的一部分,時刻記住在運行時它們可能不會被執行。

          線程

            線程是將程序中容易消耗大量cpu且易陷入死循環的片斷代碼獨立出來作為一個線程來運行(也即線程是一個代碼塊)。

            線程一經啟動start,就會進入ready狀態(實際上就是runnable狀態,只是等待分配cpu)。這也說明線程并不會馬上就running,其運行具有不確定性。線程啟動后,只要不跳出run()方法,則一直都有機會running,它由系統自動在各線程間分配cpu時間來running。要牢記的是:線程運行與中斷具有不確定性,你永遠也不知道線程何時會運行,何時會中斷。

            線程從對象的角度來看,它自身也可以是一個對象。它可視為其它對象中的一個代碼塊。

            在線程的概念中要特別注意幾個概念:單線程多線程多線程的運行多線程間的同步(資源訪問)多線程間的通信

            · 單線程 對于單線程而言,編寫其程序是比較簡單的,也比較容易理解,因為它并不涉及到synchronized和communication問題。創建單線程的方法有兩種,其一、擴展Thread類,即class A extends Thread{public void run(){};……};其二、實現Runnable接口,class B implements Runnable{Thread t=new Thread(this);public void run(){};……};

            · 多線程 相對于單線程而言,多線程會復雜很多,原因就是它們會涉及到多線程間的資源訪問多線程間通信問題。這就涉及到下面所說的三個方面:多線程的運行多線程間的同步(資源訪問)多線程間的通信

            · 多線程的運行 對于多個可運行runnable的線程來說,運行與中斷具有不確定性,永遠也無法知道線程何時會運行,何時會中斷。但是多線程運行也遵循幾個原則:如果多個線程具有同樣的優先級,則系統會在它們之間切換cpu時間運行;JVM基于優先級來決定線程的運行,但是這并不意味著一個低優先級的線程一直不運行

            · 多線程的同步 被線程可訪問的每個對象都有一個僅被一個線程訪問控制的鎖,鎖控制著對對象的同步碼的存取。這個可被多個線程訪問的對象就是所說的資源共享問題。

          A.在程序中,可以通過定義一個synchronized代碼塊或多個synchronized方法來使得調用的線程獲得該對象的控制鎖。通過獲得對象的鎖,該線程就會阻止其它線程對該對象所定義的同步塊同步方法進行操作(特別注意的是,此時并不能保證其它線程對該對象的非同步變量和非同步方法進行操作)。

          B.線程只有在同步塊或同步方法返回后才釋放鎖。

          C.synchronized并不能保證程序的運行連續性,而只是保證同一性。也就是說即使在synchronized塊或方法中,線程的運行仍舊會有中斷的可能性。盡管如此,但它卻能確保別的線程不會再訪問該對象的其它同步塊和方法,因為對象鎖并未釋放。這一事實說明了“多線程的運行”與“多線程間的同步”是兩個獨立的概念。

          D.多線程的同步塊或方法可以放在任何可被線程訪問的對象中(包括線程本身,它實際上也可被其它的線程訪問)。

            · 多線程間的通信 多線程間的同步消除了一個線程在改變另一個線程的穩定對象狀態時發生的并發錯誤,但是就線程間通信而言,同步不起任何作用,也就是說“多線程間的通信”又是一個獨立的概念。多線程間的通信通常是靠wait(),notify()兩個方法來實現的,有關這兩個方法的總結如下:

              1.wait(),notify()屬于object方法,并不是線程的方法

          2.object.wait()  意為:調用我(指該object)的當前線程你得等等,也就是使...(調用我的當前線程)...等待

          object.notify()意為:該喚醒其它先前調用過我的且在等待的線程

                從上述意義可知,wait(),notify()的對象是指線程所要用到的共享對象(當然共享對象也可以是線程對象),但是它的方法動作卻是針對調用它的線程。(通常情況下,對象的方法是作用于自己的屬性,而很少作用于其它對象。若要作用于其它對象,則用調用object.method())

          3.wait(),notify()必須成對出現,出現的方式可有3種形式。

                A.{wait();.... notify();}

                B.{wait();}... {object.notify();}

                C.{notify();}... {object.wait();}

          4.wait(),notify()必須出現在synchronized方法或塊中,否則會出現異常。原因是因為wait()會釋放對象鎖,而鎖必然是出現在同步方法或塊中。另外,wait()同sleep()一樣,也必須捕捉異常InterruptedException

          5.wait(),notify()的執行一般與外在的條件有關,只有條件改變了才觸發喚醒等待的線程。這種條件的改變通常是以旗標(Tag)的方式出現,也即當某一方法執行完后,應當立即改變旗標值。假若需要讓線程交替執行,則還需要加入互斥條件的判斷。eg.同步方法1中{if(a)},則同步方法2中{if(!a)}

          6.當執行完notify()時,程序并不會立即去運行調用wait()的線程,而直到釋放notify()的對象鎖。當釋放完鎖后,程序重新分配cpu,要注意的是,此時系統并不一定就讓wait的線程去運行,而有可能是剛才調用notify()的線程接著繼續運行。這一點正說明了線程運行與中斷的不確定性。

          7.一般說來,notify()是喚醒等待池中等待時間最長的線程;而notifyAll()是喚醒等待池中所有等待線程,然后線程去競爭對象鎖。這里說的是一般情況,有時情況并非如此,這是由系統中線程運行與中斷的不確定性決定的。

          8.wait(),notify()通常情況下需要sleep()的配合,否則屏幕中的運行顯式會“飛速”。

          9.多線程間的通信會出現死鎖現象,即wait的線程有可能永遠也得不到對象鎖。

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

          其他注意問題

          ☆     數組

          a.數組在使用之前,必須要保證給其分配內存(系統會用默認值初始化),不可只定義。否則編譯通過運行也會出現空指針錯誤。分配內存只需通過new就可以了。

          b.二維數組的第二維可以是變長的,而且可以在定義時不指定具體值。這意味著java中的二維數組不必像矩陣那樣要求每一維長度都相同。

          ☆     變量賦值

          a.實例變量只可在定義時顯式賦值,不可先定義,再賦值(這樣的話編譯出錯)。

          b.方法變量既可以在定義時顯式賦值,又可以先定義以后再賦值。

          c.static變量可以在類的任何地方賦值(若在方法中賦值,實際上是重賦值了)。

          d.final變量可以在任何地方賦值,但是一旦賦值,就不允許再次重賦值。

          e.static final變量只能在定義處賦值(即:常量)。

          ☆     移位

          a.>>  首位的拷貝右移位。等同于有符號的除法。

          b.>>> 零填充右移位。

          c.<<  左移位。等同于有符號乘法,但是必須遵循整數的溢出原則。

          d.>>32 >>>32任何移多少位都是移模32的余數。eg.移32位即不移。

          ☆     byte、char和int

          由于char的取值范圍和int的正取值范圍相同,所以,整型字面量可以直接賦給char。但是要是明確將一個整型(int)變量直接賦給char變量則編譯錯誤。

          另外,int i=5;char c=’a’;c+=i;編譯是通過的。

          byte類型在強制轉型的情況下,當范圍超出時會循環溢出。

          ☆     求模%

          求余只管左邊的符號,右邊不管。

          eg. int a=-5;int b=-2;System.out.println(a%b) //-1

             int a=-5;int b=2;System.out.println(a%b) //-1

             int a=5;int b=-2;System.out.println(a%b) //1

           

          posted on 2009-10-16 11:49 李云澤 閱讀(599) 評論(0)  編輯  收藏 所屬分類: 面試筆試相關的

          主站蜘蛛池模板: 阿拉善左旗| 蚌埠市| 赣州市| 尼玛县| 运城市| 连州市| 隆化县| 玉山县| 江北区| 仁寿县| 海城市| 商都县| 慈溪市| 德清县| 太仆寺旗| 霍州市| 双城市| 乌什县| 黑龙江省| 盐山县| 徐闻县| 哈尔滨市| 乌审旗| 金川县| 襄垣县| 大英县| 和平区| 凤山县| 临城县| 长垣县| 东城区| 文成县| 宁陵县| 黔东| 鄄城县| 桑日县| 西城区| 民权县| 驻马店市| 南充市| 东源县|