Java類與對象

1.使用關鍵字 this來調用其餘本類的構造方法,優勢一樣是最大限度地代碼利用程度,減小程序的維護工做量。
對象開闢的內存圖:在對象建立時,circle1先指向堆地址,暫時無值,當初始化r和pi以後,堆的值再指向circle1的棧地址
20160902111900.gif
2.當成員變量和局部變量同名時,用this.成員變量名來修飾成員變量。
構造方法:
  (1)方法名與類名一致
  (2)不寫返回值類型(實際上是有返回值,只是不寫)
  (3)用new關鍵字調用
   (4)系統默認分配無參構造,一旦有自定義構造,則只能使用自定義的構造
           (已有自定義構造,系統再也不分配無參構造)  

3.
   (1)基本數據類型傳遞:

  (2)引用傳遞: clone: http://lovelace.iteye.com/blog/182772
4.封裝:
    成員變量和成員方法的修飾符:public,protected,  默認 ,private(權限依次從大到小)
   (1).private:只在本類中能直接操做,本包其餘類也不能訪問。
   (2).protected:同包全部類及不一樣包的 子類能夠訪問。
   (3).默認(不寫修飾符):同包類能夠訪問--->包權限
   (4).public:同包及不一樣包的因此類均可以訪問-->整個項目
        類修飾符:public 和默認
   a.成員方法設置private,只能在類內使用
   b.
    類的訪問:
     public和默認
   優勢:1.隱藏實現細節,使得程序安全
               2.對用戶而言,簡單

5.繼承:extends
  1,優勢:
    a.提取公共代碼,實現代碼共用,節省代碼
    b.若是須要修改公共代碼,只需修改父類,程序維護方便。
   2.重寫:
      (a )被重寫的方法在父類中已經定義過
      (b)重寫要求:1.方法名和參數列表要相同;發生在父類與子類中               //重載:方法名相同,參數列表不一樣,發生在同一個類中
                              2.重寫的方法,訪問權限不小於父類方法     父類:private方法a()    子類public 重寫方法a()  是能夠的
                                     3.返回值類型和父類的返回值類型相同,或者父類返回值類型的子類
                              4.拋出異常類型不大於父類的異常類型的範圍()
    繼承特色: 
   a.父類不能知足子類要求,子類能夠重寫父類方法;子類調用時,調用的是子類重寫的方法,而不是父類的
    b.super.父類方法()   //調用父類方法
    c.調用子類構造,子類構造會 默認先調用 父類無參構造      
            class   B extends A      B b=new B();   ->會先調用A(),再調用B();--> B()至關於B(){super();//可寫可不寫,默認調用父類無參}
                調用父類有參,則super(a,b)進行顯式調用

    d.一個類只能繼承一個父類,可是能夠多層繼承;若 C extends B; B extends A ;  
          C c=new C();會先調用B的無參構造,再調用A的無參構造,最後再執行C的構造
        局部變量、子類成員變量、父類成員變量同名
         局部變量:  直接寫變量名
        子類成員變量: this.變量名
        父類成員變量: super.變量名
    
        避免繼承的濫用:繼承的語義:is-a,是一種
             子類 : 是一種   父類:用繼承

    e:子類從父類繼承哪些內容:
        (1).public和protected修飾的成員,同包都能繼承;不一樣包protected不能被繼承                super.父類方法 //super.父類屬性  均可調用
        (2).默認:同包能繼承
        (3).private成員不能繼承
        (4).構造方法不能被繼承,能夠被子類調用             
 
    f.Object類是全部的類的頂層父類,若是一個類沒有顯式的繼承於一個某個父類,默認繼承Object類
        Object類裏的經常使用方法:
              obj. toString()  沒有重寫打印的是對象的地址;  重寫以後打印對象的屬性值
            obj.equals()   沒有重寫比較的是內存地址;重寫以後比較的是內容(如String類)
            obj.getClass()
            obj.wait()         //暫停一個線程
            obj.notify()
            obj.notifyAll()      //喚醒一個線程
            obj.finalize()      //內存回收
 
      一個構造方法不能同時調用this和super();一個有參(??)構造方法若是調用的是this,也能執行父類構造
  //由於都要放在第一個位置
如:A(){ }          A(int a){this();}
    父類與子類繼承的內存關係: http://blog.csdn.net/u010697982/article/details/46389635

6.super相似this的關鍵字
   值域的隱藏,子類有與父類同名屬性,則不調用父類 已有 的屬性(如父類a ,子類也有a,則在子類中this.a就是調用子類的a,super.a調用父類的a;
          父類有a,子類沒有a,則在子類中this.a和super.a都是指向父類的a)
       this:當前對象自身
      super:當前對象的直接父類對象;

7.繼承條件下static代碼塊、非靜態代碼和構造函數的執行順序
    先父類static代碼塊 -> 子類static代碼塊 -> 父類非靜態代碼塊->父類構造 ->子類非靜態 ->子類構造

8.多態:
    要求:
   (1).創建在繼承的基礎上
   (2).重寫
   (3).  父類引用指向子類對象;   //B extends A    A b=new B();
   (4).調用被子類重寫的方法
    總結:
               a . 父類引用指向哪一個子類對象,則調用的是那個子類對象的方法(重寫後的新方法)
              b. 同一方法(被子類重寫的方法),多種狀態(不一樣的子類有不一樣的實現)
              c. 父類引用只能調用父類已有的方法,不能調用子類特有的方法
   靜態的方法不能被子類覆蓋, 靜態的都不能覆蓋,要麼全靜態,要麼全非靜態。
   A {  static m1()}  B extends A 則父類中的m1()不能被繼承。
   優勢:
    (1).提升代碼的靈活性,可擴展性和可維護性                 
    (2).用父類引用作形參,減小方法的重載      getA(父類 a)
    (3).以父類做爲返回值,獲得不一樣的對象     父類 getA();    //簡單工廠模式

9.多態  轉型:  
    (a) 向上轉型: 把子類引用轉成父類引用變量,不能調用子類獨有的方法
        Father father = new Son(); 父類指向 子類引用對象會遺失除與 父類對象共有的其餘方法(子類新的方法在編譯時會被遺失)
    (b). 向下轉型:把父類引用轉成子類引用變量,必須強制轉型,能調用子類獨有方法
         Son son=(Son)father;    //通常先有向上轉型以後,纔有向下轉型, 應先判斷其真實子類型強轉的應與真實對象一致
         當對象名錶明的真實子類型 和強轉的類是繼承鏈關係時,強轉不會出錯
     總結: 父類引用能夠指向子類對象,子類引用不能指向父類對象

10. instanceof 運算符是用來在運行時指出對象是不是特定類的一個實例
       對象名 instanceof 類名
      Actor extends Person    Person p=new Actor();
            System. out .println(p  instanceof  Actor);    //true
        System.out.println(p instanceof Person);   //true
        System.out.println(p instanceof Object);   //true
        System.out.println(instanceof System);       //編譯錯誤,與System無關係

11.抽象:
   override:重寫,父類已有方法實現,子類重寫
   implements:實現:父類是抽象方法,還未實現,子類提供實現。
   抽象方法,只聲明返回的數據類型、方法名稱和所需參數,可是沒有方法體(由子類來實現)
   抽象類:abstract   修飾類、方法, 不能修飾成員變量
                  abstract 修飾的類,能夠被繼承;修飾的方法,能被子類繼承
      final:修飾類、方法、變量;
      final 修飾的:類不能被繼承;
                             方法  能被繼承,但不能被重寫;
                            修飾基本類型變量,變量的值不能被改變;修飾引用類型變量(如類對象),棧內存的引用變量值(指向堆內存的地址)就不能變;
                            成員變量的值能夠改變;final A a=new A("b");    a.setName("sss");是能夠的(即堆內存的值能夠改變)
                                   (能夠修飾非靜態變量)
                                  
       static:修飾靜態變量         static final:靜態常量
   
   特色:
      (a).類中的抽象方法能夠是0個或者多個;
      (b).抽象類不能經過new關鍵字來實例化類(沒有具體實例對象的類),能夠經過子類來實例化
      (c).抽象類不必定有抽象方法,可是有抽象方法的類必定是抽象類。
      (d).抽象類中能夠有構造方法,但不能聲明抽象
      (e).抽象類不能用final來修飾,抽象方法不能同時被private、static、final或 native(jni使用)同時修飾。
            java 抽象類有構造 爲何不能實例化?
           抽象類只在分配了在棧中的引用, 沒有分配堆中的內存 , 程序都有一個代碼段,在內存中須要佔據必定的內存,
          而抽象類沒有具體的實現方法,沒法具體的給它分配內存空間,

12.接口   i nterface    implements
     a.接口裏面 方法默認是:  public abstract
     b.接口裏的 成員變量默認是:public static final的    靜態常量
     c.子類  實現 接口 (繼承:子類  繼承  父類 )
     d.類能夠繼承父類,並同時實現接口
     e.一樣具備多態的特色,接口類型的引用能夠指向實現類的對象。
     繼承:is-a
     接口:has-a   接口,用於實現一種能力
     接口能夠繼承接口,子類需實現全部接口的方法  如 interface A  B  ;B externds A ;  C implement B  (C需都實現B和A的抽象方法)

     抽象類:
            a.能夠有抽象方法和具體方法        
            b.能夠有變量  
            c.子類必須實現全部抽象方法;子類能夠保持抽象方法,但子類要聲明爲抽象類
            d.能夠用多態
     接口:
            a.只有抽象方法
            b.只能有靜態常量
            c.實現類必須實現全部抽象方法;實現 類能夠保持抽象方法,但子類要聲明爲抽象類
            d.能夠用多態
      二者區別:
            a.抽象類有構造方法,接口沒有構造方法
               面向對象編程:面向接口編程,運用對臺
            java類不能多繼承,可是對接口有多繼承;優勢:定義與實現分離,安全   缺點:繼承功能變少

13.多態(運行時多態):
    1.繼承:具體類     父類 指向子類
                  抽象類     父類指向 子類對象
    2.接口:接口類引用  指向  實現類對象
    3.父類A:
               B extends A          C extends B    ->A  a=new C();//繼承鏈能夠用多態
   4.編譯時多態:重載               

14.內部比較器:
     Compare c1=new Compare(10,20);
     Compare c2=new Compare(20,10);
     c1.compareTo(c2);
         public   int  compareTo(Compare compare){
        int result;
        if(this.length>compare.length){          //this.length等價於c1.length
            result=1;
        }
        return result;                                 //String類型比較"a".compareTo("b")  根據unicode編碼比較
    }          
通用型compareTo(Object obj),由於Object是全部類的頂層父類。
public  Object[] compareTo(Object[] arr) {          //內部比較器
         Cat cat[]=(Cat[])arr;                             //須要強轉
        int tmp;
        for(int i=0;i<cat.length;i++){
            for(int j=0;j<cat.length-i-1;j++){
                if(cat[j].age>cat[j+1].age){
                    tmp=cat[j].age;
                    cat[j].age=cat[j+1].age;
                    cat[j+1].age=tmp;
                }
            }
        }
        return cat;
    }  
對象數組內存分配:

15.外部比較器:
       1.由外部類進行對比較類進行分別比較,能夠寫多個比較在一個比較類中。
public static void CompareArray(Comp obj,Object arr[]){     // Comp外部比較類實現的接口 
        Object temp=null;
        for(int i=0;i<arr.length;i++){
            for(int j=0;j<arr.length-i-1;j++){
                if(obj.compare(arr[j], arr[j+1])>0){         //Comp實現類的方法
                    temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
        }
    }  

16.成員內部類:
     1.成員內部類是類的成員,能夠有四種訪問修飾符。public 默認 protected private;外部類的訪問修飾符 只能默認和public
     2.是類的成員,所以內部類的對象要依附於外部類的對象(要調用內部類對象,由外部類對象去調用)
           Outer out=new Outer();
     Outter.Inner in=out.new Inner();-->或者:Outer.Inner in=new Outer().new Inner();
            out .Inner  iner =out.new Inner();//錯誤,理解爲out生成時,其餘成員已經生成,可是Inner對象還未完成實例化
class Outer{
   public class Inner{
        void show();
  }
}
    3. 內部類能夠直接訪問外部類成員;外部類要訪問內部類成員,需建立內部類的對象。
    4.外部類成員變量、 內部類成員變量、內部類局部變量重名時如下調用方式:編譯:Outter.class   Outter$Inner.class
public class Outter extends A{
    public static int age=10;
    public  int length=10;
    public void print(){
        Inner inner=new Inner();
        System.out.println("外部類"+inner.age);
    }
    public  class Inner extends B{
        private int age=20;
        {
             printA ();    //代碼塊
             printB ();
        }
        public void print(){
            int age=30;
            System.out.println("局部變量"+age);
            System.out.println("內部類成員:"+this.age);
            System.out.println("外部類成員"+Outter.this.age); 
        }
    }
}
class A{
    void  printA (){
        System.out.println("A");
    }
}
class B{
    void  printB (){
        System.out.println("B");
    }
}   
內部類優勢:
    1.能夠獲得private更小的做用範圍;
    2.內部類的private成員只在內部類裏能夠直接訪問
    3.能夠調用A的方法,也能夠調用B的方法,變相的實現多繼承

  17.靜態內部類:是一種特殊的成員內部類(staic)
       (1).同靜態方法同樣,不能訪問外部類非靜態成員。
       (2).靜態內部類不用生成外部類對象
             Outer.Inner in=new Outter.Inner();//???
class Outer{
   public static class Inner{
        void show();
  }
}

   18.方法內部類: 創建在方法裏,而不是在類中
        1.同局部變量相似,方法內部類不能使用訪問修飾符
        2.同局部變量相似,方法內部類只能在方法裏建立對象。
        3.在方法內部類裏,如要訪問方法的局部變量,則這個變量必須爲final類型(出於安全性考慮);
           jdk 1.8能夠不聲明爲final,可是內部數值仍是不能改變。
     class B{
          void  printB(){
        final int b=10;
        class D{
            void showD(){
                System.out.println("方法中獲取的b:"+b);
            }
        }
        D d=new D(). showD() ;
    }  

    19.匿名內部類:
        1.類只用一次,類裏代碼不重複使用,不起名字
        2.看做是特殊的方法內部類。
        3.匿名內部類能夠實現一個接口,也能夠繼承一個抽象類。
        4.匿名內部類一次只能實現一個接口,或者繼承一個抽象類
        5.匿名內部類必須實現全部抽象方法,不能再是抽象類
        6.匿名內部類沒有構造方法,由於無名字
        7.如須要初始化,採用代碼塊。
        8.匿名內部類實質是匿名子對象, 若是訪問局部變量,局部變量仍是要加final。(jdk 1.8除外)
     NoaInterface intface=new  NoaInterface (){     // NoaInterface 爲一個接口或抽象類
            @Override
            public void showInterface() {
                System.out.println("NoInterface");
            }
        };
    intface.showInterface();  

    20.垃圾回收機制:
         1.由JRE對不使用的內存進行回收(GC),只回收JVM堆內存的空間
         2.將引用變量設置null,或者System.gc()或Runtime.getRuntime.gc()通知系統進行垃圾回收,是否執行由系統決定。
         3.在垃圾回收機制回收垃圾以前,老是先調用finalize方法(Object裏的方法)

     21.異常:在程序運行過程當中所發生的不正常事件,會中斷程序的運行。
         1.例子:String s=null;        --> s.equals("abc");    //會報空指針異常  如使用concat()方法
                                                                推薦使用: "abc".equals(s);
                        null 參數傳遞給此類中的構造方法或方法將拋出 NullPointerException
         2.語法:try{....}catch(Exception e){....}
                            try{....}catch(Exception e){.....}finally{....}
                            catch 塊: 若是異常對象爲某個異常類型或其子類的實例,就執行這個catch代碼塊 (異常類型一致時,執行對應的catch塊) ,不會再執行其餘的 catch代碼塊,多重catch,從上到下依次執行catch語句塊,執行完跳出try{...}catch{...}語句塊,繼續執行後續代碼。
    finally 塊:不管是否捕獲或處理異常,finally塊裏的語句都會被執行。 當在try塊或catch塊中遇到return語句時,finally語句塊將在return 方法返回以前被執行 。在如下4種特殊狀況下,finally塊不會被執行:
1)在finally語句塊中發生了異常,或者finally再拋出一個未處理的異常。
2)在前面的代碼中用了System.exit()退出程序。
3)程序所在的線程死亡。
4)關閉CPU。
       throws關鍵字將異常拋給調用者後,若是 調用者 不想處理該異常,能夠繼續向上拋出,但最終要有可以處理該異常的 調用者。
            catch塊不能單獨使用,必須始終與try塊一塊兒;finally能夠單獨使用,不是必須與try一塊兒

         3.提示友好信息,可讓程序繼續運行。
          Error(錯誤): 是程序沒法處理的錯誤,表示運行應用程序中較嚴重問題。
          Exception(異常):程序拋出和處理的非嚴重錯誤。
                           異常 分爲:   可查異常(編譯器要求必須處置的異常): 正確的程序在運行中,很容易出現的、情理可容的異常情況,SQLException和FileNoFoundException、EOFException和 Exception
                                                        不可查異常(編譯器不要求強制處置的異常): 包括運行時異常(RuntimeException 與其子類 )和錯誤(Error)
                                                        運行時異常: Java編譯器不會檢查它,也就是說,當程序中可能出現這類異常, 即便沒有用try-catch語句捕獲 它,也沒有用throws子句聲明拋                      出它,也會編譯經過。(不要求程序必須作出處理)
                            ArithmeticException類和ArrayIndexOutOfBoundsException類都是   RuntimeException 的子類。所以,
                                                       RuntimeException(系統不要求程序必須做出處理)異常類的catch子句應該放在 最後面, 不然可能會屏蔽其後的特定異常處理或引發編譯錯誤。


          
         異常兩種拋出方式:1.系統自動拋出異常
                                                   2.手動拋出異常,關鍵字throw
                                              throw 運行時異常,系統不會檢查;可是throw可查異常,須要手動做出處理。
                                                         如:throw new RuntimeException(不檢查)   可是throw new Exception(要求處理)
                                                  throw和throws:
                                              throw:拋出一個異常對象,用在方法裏;手動拋出異常
                                              throws:(1)異常類型,類名;在方法上聲異常,獨立進行;聲明異常不一樣,不是重載的依據
                                                                        重寫:若是是checked異常,子類是父類的異常類型的子類
                                                                     (2) 若是是運行時異常,調用時就不用處理;但若爲檢查異常,則須要處理。
                                                        (3)若是父類方法拋出異常,則子類重寫是必須處理;可是子類能夠不聲明任何異常。
                                                              (4)子類:拋出 ArithmeticException  父類:拋出 Exception()           //報錯,異常不兼容
                                                                                ArithmeticException                     RuntimeException  //正常,是同一運行時異常
                                                                       繼承條件下,關注父類和子類的checked 異常     
                                                               自定義異常:若是是繼承運行時異常,則系統不會檢查異常。
                                                                   (5).父類沒有聲明異常,子類throw了一個異常,則子類只能用try{...}catch{...}進行捕獲
                                                        (6).子類throws的數量比父類多,只要是父類的子異常,不報錯。
 1 拋出 Exception,當 catch 和 finally 同時趕上 return,catch 的 return 返回值將不會被返回,finally 的 return 語句將結束整個方法並返回
 2 public   static   boolean  finallyTest1()  {
 3        try {
 4            int i = 10 / 0// 拋出 Exception,後續處理被拒絕
 5            System.out.println("i vaule is : " + i);
 6            return true;   // Exception 已經拋出,沒有得到被執行的機會
 7        }
 catch (Exception e) {
 8            System.out.println(" -- Exception --");
 9            return true;  // Exception 已經拋出,得到被執行的機會,但返回操做將被 finally 截斷
10        }
finally {
11            finallyMethod();
12            return false;  // return 將結束整個方法,返回 false,已經return false,就再也不執行catch裏面的return true;
13        }

14    }


21.經常使用工具類:
     1.包裝類(Wrapper):對基本數據類型而言
        基本數據類型不是對象,不能調用方法和屬性;爲了讓基本數據類型當作對象,來調用方法和屬性,全部產生包裝類。
         Integer a=new Integer("abc");   //字符串類型的構造,若是字符串不是數字格式,會有NumberFormatException
         Java.util.concurrent中實現的原子操做類包括: AtomicBoolean、AtomicInteger、AtomicLong、AtomicReference。   //由硬件提供院子操做指令實現。
       優勢:開銷小,速度快, 在線程內部使用,能 應對高併發處理,保障線程安全。
        incrementAndGet()自增方法        decrementAndGet()自減方法
        包裝類特色:
                       (1).自動裝箱:如Integer a=15等價於Integer a2=new Integer("15");   //自動把基本數據類型轉換成對象。
                       (2).自動拆箱: 如int b=10; int c= a+b;    //自動將a對象轉成基本數據類型,參與運算
                                             int d=new Integer("12");
        3.字符串是一個引用類型:字符串本質是由字符數組構成。String中重寫了equals()方法,比較的是內容。
                                                   str="a"常量值時能夠用str=="aa" 比較
        
             str.indexOf() //有存在,則返回對應的索引(至關於字符數組下標);沒有返回-1,多個返回第一個
             str.charAt(10)  //跟索引                        str.substring(5)   //從5開始,截取字符串
           
               lastIndexof("l",6):   到第7個位置,最右一個l出現的位置。
               startWith("aa")      以aa開頭的字符串,有大小寫之分
               trim()                     刪除頭和尾的空格
               split("a");               以a爲拆分點,拆分字符串
  
  * 不用新開內存,使用舊的內存,不斷擴展新的字符串
      StringBuffer:  效率低,安全性高   jdk1.0          一個空的buffer的sb.length()爲0,初始容量sb.capacity()爲16
          StringBuffer sb=new StringBuffer();
          StringBuffer sb2=new StringBuffer("Hello");        //長度爲5,容量16+5
          sb.append("aa")       //追加字符串,相似String中的concat();
          sb.delete(0,5);         //刪除索引0-4的字符串,包括頭,不包含尾
          sb.insert(5,"aa")      //從第6個位置,插入字符串aa
     StringBuilder: jdk1.5 效率高,安全性低
         equals只比是否相同,compareTo();給出返回值,表示大、小或相等
  // abcd引用自常量池

         
        
22.日期:
      「YYYY/MM/dd --HH:mm:ss--SS」  //格式化: 年月日  時 分 秒  毫秒
       SimpleDateFormat實現DateFormat(抽象類)
       格式化:new Date();
                      new 格式化器;格式化器的參數,
                                SimpleDateFormat sdf=new     SimpleDateFormat("yyyy-MM-dd" );
                         sdf.parse();// 格式化時,參數類型要與 SimpleDateForma      t 一致,不然會報錯。

      日曆:Calendar 抽象類     GregorianCalendar()子類
                 Calendar cal=new GregorianCalendar();  //
                 Calendar cal2=Calendar.getInstance();
                 cal.get(Calendar.YEAR)  //獲取年份的字符串
                 cal.set(Calendar.DATE,1) //設置成本月第一天
                 cal.getMaximum(Cal.DATE)    //獲取本月最大天數
                 cal.setTime(date)                    //修改當前系統日期

23.File:
     不能修改文件,需經過IO流才能進行文件輸入輸出操做。
     文件:File f=new File(" d:\\a1 ");     或者  new  File("d:/a1");  兩種文件路徑方式
     f.exist()  //文件是否存在             f. mkdir()  //建立單層目錄(已有,再也不建立 )      f.mkdirs()  //建立多層目錄,帶有子目錄         f.isDirectory()  //是否爲一個目錄
     f.delete()  //刪除文件                  f.getName()  //獲取文件名字                  f.getAbsolutePath() //獲取絕對路徑  如 d:\a1
      File  f1 = new  File( "d://a1" );              //f1指向a1對象,d://只是文件須要的路徑屬性
  File f=new File("d://a1//a.txt");       
     f1 .mkdir(); //多層目錄下建立文件,須要先建立目錄,再建立文件,不然會報找不到指定路徑(IOException)。
  f.createNewFile()  
    String fList[]= file.list()  //獲取文件的名稱字符串數組                                   File fileList[]=file.listFiles();  //獲取文件對象存放在文件類型的數組

24.枚舉類型(數據集,只能使用固定的一組值):
     能夠有本身的屬性、方法和構造方法    
     優勢:只能取特定值中的一個,不能是數字;須要定義一組常量的時候,使用
      public   enum  Sex { ,; }   //男女不加引號,枚舉的值是 public static final ,能夠用枚舉名直接調用
     使用:private Sex msex;                      // Sex  枚舉名   msex 枚舉變量名
      setSex( Gender.男);                       //直接 枚舉類名.屬性名調用
      switch( n)                                          // n能夠是枚舉類型
     Sex  sex =Sex.;
    switch(sex){
       case :
         System.out.println("女");
         break;  
25.Math
     Math.ceil(3.2)    //向上獲得最接近的數,4                 Math.floor(3.2);  //向下獲得最接近的數    3
     Math.round(3.4)    //四捨五入    3
     引用:
         1.讓程序員經過代碼的方式決定某些對象的生命週期;2.有利於JVM進行垃圾回收
     (1).強引用:
            如:Object obj=new Object();      //二者都是強引用, 只要某個對象有強引用與之關聯,JVM一定不會回收這個對象
                   String str="kkkkk";               //即便在內存不足的狀況下,JVM寧願拋出OutOfMemory錯誤也不會回收這種對象
                                                                 // 中斷強引用和某個對象之間的關聯,能夠顯示地將引用賦值爲null
     (2).軟引用: 描述一些有用但並非必需的對象 java.lang.ref.SoftReference類來表示。 Android開發中對於大量圖片下載會常常用到
                        對於軟引用關聯着的對象,只有在內存不足的時候JVM纔會回收該對象 很適合用來實現緩存:好比網頁緩存、圖片緩存等。
                          軟引用能夠和一個引用隊列(ReferenceQueue)聯合使用,若是軟引用所引用的對象被JVM回收,
                        這個軟引用就會被加入到與之關聯的引用隊列中。
     如:   SoftReference<String> sr = new SoftReference<String>(new String("hello"));
            System.out.println(sr.get());
     (3).弱引用:描述有用但非必須的對象 java.lang.ref.WeakReference類
                         當JVM進行垃圾回收的時候,不管內存是否充足,都會回收被弱引用關聯的對象
                        但若是對象同時被強引用關聯的話,就回收不了該對象。
                        也能夠配合一個引用隊列(ReferenceQueue)使用,若是弱引用所引用的對象被JVM回收,
                         則這弱引用會被加入到與之關聯的引用隊列中
            WeakReference<String> sr = new WeakReference<String>(new String("hello"));
	    System.out.println(sr.get());
	    System.gc();                //通知JVM的gc進行垃圾回收
	    System.out.println(sr.get());
     (4).虛引用: 虛引用和前面的軟引用、弱引用不一樣,它並不影響對象的生命週期 PhantomReference
                              若是一個對象與虛引用關聯,則跟沒有引用與之關聯同樣,在任什麼時候候均可能被垃圾回收器回收。
                         虛引用必須和引用隊列關聯使用,當垃圾回收器準備回收一個對象時,若是發現它還有虛引用,
                        就會把這個虛引用加入到與之 關聯的引用隊列中。
                         ReferenceQueue<String> queue = new ReferenceQueue<String>();
	    PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);
	    System.out.println(pr.get());

26.集合:不知道程序運行時須要哪些對象
    (1).集合類:把一些對象存放在一塊兒。


實線邊框 的是 實現類 ,好比ArrayList,LinkedList,HashMap等, 折線邊框 的是 抽象類 ,好比AbstractCollection,AbstractList,AbstractMap等,而 點線邊框 的是 接口 ,好比Collection,Iterator,List等
   Collection:集合框架的根接口:無序,不惟一;
   List:子接口:有序的,不惟一(能夠重複)
   Set:子接口:無序的,惟一

  數組:基本數據類型,引用數據類型,數組的數據類型與其聲明相同。
  集合: 接收Object參數
              只能存放引用數據類型,加入集合後所有轉成Object類型。
若是多個線程同時訪問一個List,則必須本身實現訪問同步。一種解決方法是在建立List時構造一個同步的List:
    List list = Collections.synchronizedList(new LinkedList(...));

ArrayList:   內存分配連續的空間
               優勢:遍歷元素和隨機訪問效率高
            缺點:添加和刪除元素需大量移動元素,效率低,按內容查詢效率低
LinkedList:   以鏈表形式組成
            優勢:插入、刪除效率較高
            缺點:遍歷和訪問元素效率低

  Arraylist list=new ArrayList();      //相對於數組優點:容量自動增加,可變長數組, 有索引的方法都在list中
     list.add(123);      //等價於 Object obj=new Integer(123);
     list.add(p);            //Person p=new Person();
     list.add(1,"kkk")  //在第二個元素位置插入
     list2.add(999);
     list.addAll(list2);  //對於list2時 以元素形式,加入集合
     list.add(list2);     // 對於list2時    對象 形式,加入集合
     for(Object o:list)  //多態遍歷
  刪:
       remove(p);    //多個,刪第一個
       remove(index); //索引刪
       remove( list2) //刪除與list2中相同的元素,不止list2中的元素,在removeAll以前纔算。
  改:
       set(index,ele) //在指定索引改元素
       List  sub=subList(fromIndex,endIndex);// 截取子list,包含from,不包含end
  查:
       size()            //實際元素個數
       get(0)           //ArrayList有索引,但與數組使用索引不一樣
       contains(Object o)     //返回boolean,      list .contains(Color. )   // Color. 枚舉類型
       containsAll()
       isEmpty()
       IndexOf(c)   //查找位置
       list.retainAll(list2)  //在list中保留全部 list與list2裏相同的元素,元素個數有改變
三種遍歷方式:
             for( Object o:list)          //獲得的list集合內元素都是Object
             for(int i=0;i<list.size();i++)  //有索引的能夠,如List
              Iterator it=list.iterator();
             while(it.hasNext()){  it.next() }
             for-each{}  底層也是調用Iterator
迭代器:hasNext()    指向list前方
               next()     返回當前迭代器的下一個對象,同時指向當前對象的下一個對象。
               remove()   
               在使用迭代器遍歷x時,不能對list再進行增長操做,不然會報錯。若是實在須要增長或修改元素時,使用ListIterator進行操做。
   
LinkList:相似Arraylist上面方法基本都有
              addFirst(p)          addLast(p)        鏈尾    //增長頭 加尾
               offerFirst(p1)      offerLast(p1)         //jdk1.6之後新增
              getFirst()             getLast()           //查頭 查尾
              peekFirst()         peekLast()     
              removeFirst()     removeLast()  //刪頭刪尾
              pollFirst()           pollLast()        
Set:無序,惟一: 不存在get()
        HashSet:無序,惟一(哈希表保證其惟一性, 自定義類要重寫hashcode()和equals()),
                       hashcode相同,equals()不必定是true;
                       hashcode不一樣,equals()是false;
                             equals相同,hashcode必定相同。
                              裏面不能存放重複元素,採用散列的存儲方法,沒有順序;
         Set:  Set set=new HashSet();
              set.add(p);
              set.remove(p);     set.removeAll()
              set.retainAll()       //取交集
              set.contains(p)      //boolean
              set.containsAll(collection)

        TreeSet:     實現了SortedSet接口,可以對集合中的對象進行排序
                          有序(升序,二叉樹排序),惟一;查詢速度比List快(按內容比);查詢速度比HashSet慢
                      TreeSet ts=new TreeSet();
                      (1).自定義類,要實現Comparable接口,實現compareTo()來進行比較。不然不知道比較策略,報Comparable異常
                      addAll()  根據所實現的compareTo()方法來進行過濾重複字段值。
                      (2).應用外部比較器,Wcomparatot wc=new Wcomparator();  //自定義外部比較器
                                                         TreeSet ts=new TreeSet(wc);  
       
       
        Map:存儲鍵值對的對象,key與value
                key:無序,惟一;key不能重複(重複時,會把以前的key覆蓋); key能夠爲null,只有一個會存在
                value:無序,不惟一;能夠爲null
                          若是 key爲null,則沒法迭代獲得其對應的value值;對象做爲key,則打印該key是顯示其對象的值。自動排序
                          HashMap: Map map=new HashMap();               //若是Map中key是自定義類;別忘了重寫hashCode()和equals(),以做對象區別。
                          map.put("a","aaa");
                          Set  keySet=map. keySet();   或者用entrySet()   //先將key值提取成一個Set,而後遍歷Set
                          Iterator it=keySet.iterator();
                          while(it.hasNext()){ map.get(it.next()) }    //獲取value值如aaa   it.next()只能獲取key(a)
                             remove(key);       //刪除元素
                              clear();                    //清除元素
                        containsKey(key)          containsValue(value)   //查
       集合泛型: 集合是對數組作的封裝,因此,數組永遠比任何一個集合要快
                              解決數據類型操做不統一而產生的異常,使用泛型限制數據類型,避免強轉類型,保障數據安全。
                        未加特定泛型,默認是Object;
                        1. ArrayList<Dog> d=new ArrayList<Dog>();    //加過泛型以後,只能接受Dog對象,數據統一。                                                                
                                  Iterator<Dog>  it =d.iterator();               //取出的都爲Dog的對象了;不用強轉。
                          hash遍歷:  http://blog.csdn.net/onlyonecoder/article/details/8514443
                           for  (Map.Entry<String, String> entry : hashMap.entrySet()) {  
           System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());  
          }  
           2.Map <Dog,String>  m1=new HashMap<Dog,String>();   //map泛型
                                    Map<Integer,String> m2=new HashMap<Integer,String>();
                             Set keySet=m2.keySet();                             // keySet ()獲取關鍵字key的集合
                             Iterator<Integer> it=keySet.iterator();     //能夠Iterator<Integer>或者  Iterator<String>
                                    Set<Entry<Integer, String>>  keySet=m1.entrySet();     //entry<Integer,String>打印整個鍵值。
              Iterator<Entry<Integer,String>>  it=keySet.iterator();
       自定義泛型:class Stuent< T>{ void show(T t) }     使用時就要對其進行泛型;     T只是一個指代,能夠爲a,b,c..
                                    Student<Song>  tsong=new Student();    tsong.show(new Song());
 
 
 
 
A<String,Integer> t=null; //兩個泛型類型的對象 //Key爲String,Value爲Integer
t.setKey("張三"); t.setValue(10);                 
                             優勢:避免方法的大量重載;
                      Dog<Integer,Cat> d = new Dog<Integer,Cat>();   //存放Integer和Cat的對象

        Dog<Integer,Cat> d2 =new Dog<Integer,Cat>();html

        Dog<Integer,Cat> d3 =new Dog<Integer,Cat>();java

  Dog dd[]={d,d2,d3}; 程序員

  在Dog類中需加上泛型。spring


      Collection:集合根節點 
      Collections:集合工具類
                        Collection.sort(list);          //元素中的自定義類,要實現comparable才能排序,不然會出現相似TreeSet排序時的異常;不理會重複
                                         binarySearch(list);  //返回索引,不存在返回  -(i+1)
                                         reverse(list)           //反轉,不必定排序的
       Arrays:
       靜態導入:import static java.lang.Matc.*;
       Vector是線程安全的;ArrayList不是
        Stack:是Vector的子類,List的實現類,先進後出;
       Queue:繼承Collection接口,先進先出;

      集合和數組區別:編程

              1.數組能存放基本類型和對象,而集合類只能存放對象。數組

              2.數據固定沒法動態改變,集合類的容量能動態改變。緩存

              3.數組沒法判斷其中實際存有多少元素,length只能獲得數組的容量,而集合的size()能夠確切知道元素的個數。安全

              4.集合有多種實現方式和不一樣使用場合,不像數組僅採用順序表方式。服務器

              5.集合以類形式存在,具備封裝、繼承、多態等的特性,經過簡單的方法和屬性便可實現各類複雜操做,提升軟件開發的效率。網絡

    Vector和ArrayList區別:

               1.實現原理相同,功能相同,都是長度可變的數組結構,大多數狀況下能互用。

               2.ArrayList是Vector的替代接口;Vector線程安全,速度比較慢;ArrayList速度快,線程不安全。

               3.長度須要增加時,Vector默認增加一倍,ArrayList增加50%

   HashMap和Hashtable區別:

               1.實現原理相同,功能相同,底層都是哈希表結構,查詢速度快,大多數狀況下能互用。

               2.HashMap是新接口;Hashtable繼承Dictionary類,HashMap實現Map接口

               3.Hashtable是線程安全,HashMap線程不安全。

               4.Hashtable不容許null值,HashMap容許null值。

   

27.IO流: 節點流(InputStream等)和處理流(InputStreamReader)
    InputStream:從外部數據源文件讀到程序內存;  OutputStrem:從程序內存中寫數據到目的文件;


OutputStream out=new FileOutputStream("d:\\a.txt",true);              //有true爲追加文件以後,d:\\a.txt文件內容不會被清空
OutputStream out=new FileOutputStream("d:\\a.txt" );                       //沒有true,文件會被重寫,舊的數據會被清空
源碼打開文件,open(name,append)                            ///append爲boolean表明爲true,追加不重寫舊文件;false重寫,舊文件會被重寫,內容清空。
字符類和字節流區別:
    1.讀寫單位不一樣:字節流以字節(8bit)爲單位,字符流以字符爲單位,根據碼錶映射字符,一次可能讀多個字節。
       處理對象不一樣:字節流能處理全部類型的數據(如圖片、視頻等),而字符流只能處理字符類型的數據(通常爲文本類數據)
     結論:只要是處理文本數據,優先考慮使用字符流;除此之類優先考慮字節流。
節點流:從
RandomAccessFile    隨機存取文件類。
     1.不屬於流體系,但封裝了字節流,同時還封裝了一個緩衝區(字符數組),經過內部指針來操做字符數組中的數組。
     特色:
         a.該對象只能操做文件,構造函數只接受兩種類型的參數:a.字符串文件路徑 b.File對象
         b.該對象能對文件進行讀、寫操做,並能指定具體的操做模式(r,rw);
         c.該對象在建立時候,若文件不存在,則會自動建立;若文件存在,未指定寫的位置,會從頭開始寫(覆蓋原來的內容)。
            能夠用於多線程下載或多個線程同時寫數據到文件。  

 字節流:操做圖片壓縮文件時經常使用
        InputStream is=new FileInputStream("d:\\a.txt");     //InputStream 字節輸入流
         is.read()                      //文件結尾返回-1,讀取首個字節;read()有指針,標記每次讀到的位置。
                                                      // 在輸入數據可用、檢測到流末尾或者拋出異常前,此方法一直阻塞。
         is.read(byte[])          //返回值爲每次讀取到數組的字節個數,沒有則返回-1;漢字佔兩個字節,byte[n]  n需爲偶數
          while ((n=in.read(readArr))!=-1){
         str=new String( readArr ,0,n);  //n爲實際元素個數   readArr爲byte[]    byte[]中的0在String中做爲空格符
     }
         is.available()    獲取最大可讀字符數
                   out.write(‘我’);    //沒法寫入到文件中,中文兩個字節,會出現亂碼
                     out.flush()         //刷新緩衝區;若沒寫,在close()時也會刷新緩衝區。

字符流:操做文檔時經常使用
        Reader reader=new FileReader(file);               //Reader  抽象類   FileReader 子類
                     reader.read()                                                 / /返回一個字符編碼表明的整數,無數據仍返回-1
        Writer writer=new FileWriter(file, true);          //一樣能夠追加內容  
                  writer.write('我');                                      //能夠寫入,一次寫入一個字符
                      char[] arr={'打',‘請’};                           //write(arr)   接收外部數據時使用

字節流到字符流的轉換 //處理流能夠指定編碼
         InputStream in=new FileInputStream("d:\\a.txt");  
        InputStreamReader    isr=new InputStreamReader(in);                  //包裝inputStream成爲InputStreamReader不能直接用Reader來轉。                      
        BufferedReader br=new BufferedReader(isr);                                  //將字符轉換流,再包裝一次。
        OutputStream os=new FileOutputStream("d:\\bb.txt"); 
       OutputStreamWriter  osw=new OutputStreamWriter(os,"gbk");             //包裝字節輸出流; 寫入時加\n能夠進行換行操做
         PrintWriter pr= new  PrintWriter(socket.getOutputStream(), true );
     pr.println("aaaaa" )  //接收方爲BufferedReader時要用此方法,由於readLine()方法的特色。

 字符緩衝流:讀寫效率高,訪問硬盤次數少
       Reader reader=new FileReader("d:\\a.txt");
       BufferedReader br=new BufferedReader( reader);                                                //可使用nextLine()
       Writer writer=new FileWriter("d:\\bb.txt");
       BufferedWriter bw=new BufferedWriter( writer);                                                     //newLine() 換行
    bw .write(str);     
   bw.write("\n");   等價於br.newLine()  //因爲bufferedReader讀數據時採用readLine(),加'\n'能夠進行提醒讀取完畢。
    bw .flush();                     //最好寫上,否則有可能會出現數據沒有正常寫入,停留在緩衝區中
字節緩衝流:
 BufferedInputStream  bin = new  BufferedInputStream( new  FileInputStream( testPath ));  
 BufferedOutputStream bout=new BufferedOutputStream(new FileOutputStream(writePath));                              

 Buffer內部結構
     
   流的關閉順序: 按建立對象的相反順序關閉。】
  過濾流:DataInputStream和ObjectInputStream 
  數據流:主要用於基本數據的讀寫:(寫入的是二進制) 先寫後讀,而且讀的時候應與寫入時順序一致。與平臺無關,適合網絡傳輸。
                       OutputStream os=new FileOutputStream("d:\\bb.txt"); 
                   DataOutputStream dos=new DataOutputStream(os);
                   dos.writeUTF("踩踩踩從");
                   dos.close();
                   os.close();
                   InputStream in=new FileInputStream("d:\\a.txt");  
                   DataInputStream din=new DataInputStream(in);
  
   對象流:寫對象時,自定義的類要實現序列化。先寫ObjectOutputStream,再寫ObjectInputStream
                      Java序列化 是指把 Java對象轉換爲字節序列的過程 ;而 Java反序列化 是指 把字節序列恢復爲Java對象的過程
       優勢:一是, 實現了數據的持久化,經過序列化能夠把數據永久地保存到硬盤上(一般存放在文件裏),
                        二是,利用序列化實現遠程通訊,即在網絡上傳送對象的字節序列。
           implements  Serializable   才能保證獨享能夠以byte形式寫進文件,接口裏沒定義任何常量和抽象      方法。
         public   static   final   long  serialVersionUID=1111l;
         private transient String pwd;     //保證敏感信息字段不被序列化,不會被讀出
        transient特色,
                  a.一旦變量被transient修飾,變量將再也不成爲對象持久化的部分,該變量內容在序列化後沒法被訪問。
                  b.transient只能修飾非靜態成員變量,不能修飾類和方法。而且本地變量不能被transient修飾,若是變量是自定義變量須要實現Serializable接口。
                  c.被transient關鍵字修飾的變量不能再被序列化,靜態變量無論是否被transient修飾,均不能被序列化。

                 OutputStream os=new OutputStream();
                 ObjectOutputStream oos=new ObjectOutputStream( os);
                 oos.writeObject(new User());
                 //輸入流相似
  輸出流:                                                                                     //System.err-->PrintStream的對象;
                   PrintStream ps=new PrintStream(file);       //System.out-->PrintStream的對象;標準輸出流,輸出到控制檯
               ps.prinf("%d+%d=%d",5,2,8);                    //System.in-->InputStream的對象;標準輸入流,鍵盤輸入
               PrintWriter pw=new PrintWriter(file);        //字符輸出流
                  pw . prinf ("%d+%d=%d",5,2,8);
               Scanner scan=new Scanner(file);
                  PrintWriter pr=new PrintWriter("e:\\aa.txt","utf-8");   最快速度寫,aa.txt若不存在,會自動幫忙建立。
28.多線程:(eclipse啓動後即爲進程,main()執行時即爲一個線程)
       一個具體的線程也是由虛擬的   CPU      、代碼和數據組成,其中代碼與數據構成了線程體,線程的行爲由它決定。
     進程(資源分配):一種正在運行的程序,有本身的地址空間。  特色: 1.動態 2.併發  3.獨立
     線程(只能共享進程資源):進程內部的一個執行單元,程序中一個單一的程序控制流程。
     多線程: 一個進程中同時運行多個線程,完成各自不一樣的工做
     
    線程特色:
                 1.輕量級進程          2.獨立調度的基本單元         3.可併發執行      4.共享進程資源。     
    線程建立的兩種方式:
                 1.extends Thread  重寫run()   
                    / /run()不能聲明拋出任何異常,父類方法沒有聲明異常,不能大於父類異常範圍。 
                    // 不要重寫start(),不然容易出現異常。
                     a.結構簡單清晰,代碼量少
                     b.沒法繼承其餘的類,進行其餘功能的擴展
                      2.class A  implements Runnable  實現run()       //內部使用 Thread.currentThread() 獲取當前線程
                     Thread a=new  Thread(new A());                    //Thread 實現Runnable,能夠做爲A的構造參數。
                     a.能夠繼承別的類,但代碼略複雜
                     b.線程資源共享,複用率高(推薦)
    線程啓動方式:
                 1.線程必須經過 start()方法啓動( 就緒狀態
                 2. 不能經過run()來啓動線程,執行完畢前其餘線程沒法並行執行。
                 3.Java程序啓動時,會立刻建立主線程( main在此線程上運行);當再也不產生新線程時,程序即爲單線程。
    經常使用方法:
                Thread.setName("sss");                
                Thread.currentThread().getName()
    優先級:
                  setPriority(Thread. MAX_PRIORITY );
        若是線程A建立了線程B,那麼線程B將和線程A具備一樣的優先級。  若是優先級爲3的A線程中,建立了B線程,那麼B的優先級也爲3
                 移植到不一樣的操做系統中,最好只使用java提供的三個優先級,不然可能會報錯。(java與不一樣系統的優先級映射不徹底)
  經常使用方法:
              Join()    強行插入執行,插入的線程必須先執行完,才能執行被插入的線程和其餘線程,按順序執行。
                           如線程 A、B、C、D     在main()中執行,c.join()後main()線程會等待c線程執行結束以後才執行結束。
                           順序    1.thread.start();    2.thread.join(); 必須放在start()以後。 
              Sleep()  線程中止一段時間,轉入阻塞狀態,等到沒有其餘等待的線程,再執行(不會立刻恢復執行)。
                             給其餘線程執行的機會,不考慮其餘線程的優先級,低優先級也能夠執行。
              yield()   將當前線程暫停,非阻塞線程,而是轉入就緒狀態等到沒有其餘等待的線程,立刻恢復執行
                            只給相同優先級或者更高優先級的線程一次運行的機會。
                           
              setDaemon()  指定線程設置成後臺線程,子線程隨着主線程的結束而結束。必須在線程啓動以前把其設爲後臺線程
                                        jvm的垃圾回收器其實就是一個後臺線程; setDaemon函數必須在start函數以前設定,
不然會拋出IllegalThreadStateException異常;                                            
                                        順序: 1. thread.setDaemon(true);   2.thread.start();    必須在start以前。(在main()是這樣)
                stop()    結束線程,不推薦使用。
        當一個線程執行System.out.println()或Syste.in.read()方法是,就會發出一個I/O請求,
                該線程會放棄CPU,進入阻塞狀態直到I/O結束纔會恢復執行。
                當線程退出run()時,就進入死亡狀態,結束聲明週期。
                   jvm採用搶佔式調度模型:優先讓可運行池中優先級高的線程佔用cpu。
   同步:
              synchronized ( this ){      //同步代碼,同一時間只能由一個線程操做;推薦使用Runnable方式
          ticket--;
          System.out.println("票:"+ticket+"--"+Thread.currentThread().getName());
      }
  線程安全:
      當多個線程訪問同一個共享資源的時候,要保證某一個時刻只有一個線程控制和操做資源,使用同步代碼鎖和同步監視器來完成。  
        synchronized ( this ){       // this表明當前線程(同步監視器,臨界資源)
         ticket--;
         System.out.println("票:"+ticket+"------------------"+Thread.currentThread().getName());
     }   
   同步代碼塊兩種方式:
      synchronized  (Thread.currentThread())  或 synchronized(this) 或  synchronized(obj)   
         //obj須是一個共享對象,基本類型無效,  靜態方法也能夠加 synchronized,不會被繼承
  同步方法:
           public  synchronized  void sell (){}    //同步控制方法     
 正確?  new關鍵字創建一個線程對象後,該線程對象就處於新生狀態。處於新生狀態的線程有本身的內存空間,經過調用start進入就緒狀態。    
       1. 當兩個併發線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內只能有一個線程獲得執行。
                  另外一個線程必須等待當前線程執行完這個代碼塊之後才能執行該代碼塊
              2. 當一個線程訪問object的一個synchronized(this)同步代碼塊時,另外一個線程 仍然能夠訪問該object中的非synchronized(this)同步代碼塊。
       3. 一個線程訪問object的一個synchronized(this)同步代碼塊時 其餘線程對 object中全部其它synchronized(this)同步代碼塊的訪問將被阻塞   
       4. 當一個線程訪問object的一個synchronized(this)同步代碼塊時,就 會得到這個object的對象鎖 。其它線程對該object對象全部同步代碼部分的訪問都被暫時阻塞
              5.兩個不一樣的線程,在 加同步鎖時應對同一種共享對象或者線程加鎖。 同步鎖不能用於實現不一樣線程之間的消息通信。
     線程通信: 均是java.lang.Object類的方法,只能在同步方法或者同步代碼塊中使用,不然會拋出異常。
              final void wait()   表示線程一直等待,直到其餘線程通知; 會釋放持有的鎖資源
              void wait(long timeout)   線程等待指定毫秒參數的時間
              final void notify()    喚醒一個處於等待的線程(隨機的喚醒)
              final void notifyAll()  喚醒同一個對象上多有調用wait()方法的線程,優先級別高的線程優先運行
              interrupt()   打斷線程讓出cpu
      死鎖,是指多個進程循環等待它方佔有的資源而無限期地僵持下去的局面。
     線程組:線程A建立線程B,默認跟A所屬的線程組。一旦加入某個線程組,不能中途改變所屬的線程組。 
    activeCount() 返回當前活着的線程。
    enumerate(Thread []arr)  把當前活着的線程引用拷貝到arr中。

      ThreadLocal:存放線程的局部變量,每一個線程都有單獨的局部變量,彼此不會共享。
                           解決多線程中數據因併發產生不一致問題。 耗費了內存,單大大減小了線程同步所帶來性能消耗,也減小了線程併發控制的複雜度。
     對於多線程資源共享的問題,同步機制採用了「以時間換空間」的方式,而ThreadLocal採用了「以空間換時間」的方式。前者僅提供一份變量,讓不一樣的線程排隊訪問,然後者爲每個線程都提供了一份變量,所以能夠同時訪問而互不影響。
      經常使用方法:
                       public T get(): 返回當前線程的局部變量       //ThreadLocal<T>
                       protected T initialValue():返回當前線程局部變量的初始值   //ThreadLocal類中有Map緩存,存儲每一個線程的局部變量。
                       public void set(T value): 設置局部變量值。

  public static final ThreadLocal session = new ThreadLocal(); //建立線程局部變量session,用來保存Hibernate的Session
    public static Session currentSession() throws HibernateException {
        Session s = (Session) session.get();   
        if (s == null) {
            s = sessionFactory.openSession()    ; // 若是Session尚未打開,則新開一個Session
            session.set(s);                                       //將新開的Session保存到線程局部變量中
        }
        return s;
    }

    Timer time=new Timer(true);                   //計時器,true表明成爲後臺線程
        TimerTask task=new TimerTask() {          //計時任務,實現了Runnable接口。
            @Override
            public void run() {
                while(true){
                    a++;
                }
            }
        };
       time.schedule(task, 10, 500);                    // time.schedule(task,  delay period)
29.非阻塞與阻塞:  
     1.非阻塞: 把整個過程切換成小的任務,經過任務間協做完成。 事件驅動機制:事件到的時候觸發,而不是同步的去監視事件。
        線程通信:線程之間經過 wait,notify 等方式通信。保證每次上下文切換都是有意義的。減小無謂的進程切換

      2.阻塞:若鏈接還沒到來,那麼 accept 會阻塞 , 程序運行到這裏不得不掛起, CPU 轉而執行其餘線程。

       異步結構圖:

       
 
     網絡通信協議:計算機網絡中實現通信須要的遵照的約定。     
    數據傳輸過程涉及的通信協議:
集線器只涉及一層    //物理層
交換機涉及兩層       //物理層+數據鏈路層
路由器涉及三層       //物理層+數據鏈路層+網絡層
計算器涉及全部層次
應用層:Telenet:遠程登陸    FTP文件傳輸協議  SMTP:簡單郵件傳輸協議   Http:超文本傳輸    DNS域名解析協議
   Tcp:1.面向鏈接   2.點對點通信  3.高可靠性  4.佔用系統資源多、效率低
   Udp: 1.無鏈接,傳輸不可靠,可能丟失
            2.發送無論對方是否準備好,接收方收到也不確認
            3.能夠廣播發送,很是簡單的協議,開銷小。
    IP: 127.0.0.1  本機地址(localhost),路由器修改密碼是要用
         192.168.0.0--192.168.255.255 私有地址,非註冊地址,給阻止結構內部使用。
    >>> 無符號右移      >>右移
 經常使用方法:
   InetAddress.getLocalHost();     //獲取主機名,如kkk    InetAddress不能實例化
   InetAddress.getByName("www.sina.com") ;   //獲取域名對應的ip
   addr=InetAddress.getByName("61.135.253.15");       
   addr.getHostAddress()   //返回163服務器的ip: 61.135.253.15
   addr.getHostName();     //輸出ip而不是域名。若是這個ip地址不存在或者DNS服務器不容許進行ip地址和域名的映射,
                                              //getHostName方法直接返回這個ip地址。
   InetSocketAddress能夠實例化,帶端口

 Socket通信:Socket實際是網絡傳輸層供給應用層的編程接口。 

       客戶端程序建立一個套接字,並嘗試鏈接服務器的套接字。當鏈接創建時,服務器會建立一個Socket對象。

       客戶端和服務器如今能夠經過對Socket對象的寫入和讀取來進行進行通訊。

 兩臺計算機之間使用套接字創建TCP鏈接時會出現:鏈接成功後使用I/O進行通信。

  • 服務器實例化一個ServerSocket對象,表示經過服務器上的端口通訊。
  • 服務器調用 ServerSocket類 的accept()方法,該方法將一直等待,直到客戶端鏈接到服務器上給定的端口。
  • 服務器正在等待時,一個客戶端實例化一個Socket對象,指定服務器名稱和端口號來請求鏈接。
  • Socket類的構造函數試圖將客戶端鏈接到指定的服務器和端口號。若是通訊被創建,則在客戶端建立一個Socket對象可以與服務器進行通訊。
  • 在服務器端,accept()方法返回服務器上一個新的socket引用,該socket鏈接到客戶端的socket。

    
  在請求和應答的通信過程當中,不能立刻關閉I/O流,不然會報異常,應放到最後才關閉。
  I/O和JDBC等的鏈接,須要本身手動關閉,JVM不負責關閉。
  next()只接受空格以前的數據   nextLine()接收回車以前的數據
UDP:(I/O流的操做不是必須的)
        DatagramSocket ds = new DatagramSocket();      //創建客戶端鏈接,使用系統分配的一個本機未用端口。通常客戶端的鏈接不必指定端口。
     流程:一、在發送數據時,將須要發送的數據內容先轉換爲byte數組,再將數據內容、服務器IP和服務器端口號一塊兒
                      構形成一個DatagramPacket類型的對象,發送時直接發送該對象便可。 進行數據傳輸時,系統只是盡全力
                      傳輸數據,可是並不保證數據必定被正確傳輸,若是數據在傳輸過程當中丟失,那就丟失了。
                  二、接收數據在Java語言中的實現是這樣的:首先構造一個數據緩衝數組,該數組用於存儲接收的服務器端反饋
                       數據,該數組的長度必須大於或等於服務器端反饋的實際有效數據的長度。而後以該緩衝數組爲基礎構造一
                      個DatagramPacket數據包對象,最後調用鏈接對象的receive方法接收數據便可。接收到的服務器端反饋數
                      據存儲在DatagramPacket類型的對象內部。
 UDP數據包: 需先啓動server端等待接收,再啓動客戶端發送數據。
                      res=scan.nextLine();      //直接使用res.getLength()形成數據丟失。
          byte arr[]=res.getBytes();   
          dp2 = new DatagramPacket(res.getBytes(), arr. length , dp.getAddress(), dp.getPort());  
          //arr. length 在此處只能只用數組的長度,不然會出現少字符。
          ds.send(dp2);   
                         DatagramSocket:發送或接受數據包    //沒有指定端口時,系統會隨機分配一個端口。
     client:     DatagramSocket ds=new DatagramSocket(9999)  //9999爲client本身發送和接收數據的端口
       server :    DatagramSocket ds=new DatagramSocket( 9999 )  //9999爲服務器本身發送和接收數據的端口
                     兩臺機器通信才能寫一樣的端口;若是是電腦上調試,不能寫同一個端口,不然會報錯。
              new DatagramPacket(buflengthaddressport)   //port爲指定服務器的接收端口
                     DatagramPacket:數據包
                     DatagramPacket receiveDp = new DatagramPacket(b,b.length);           //接收的數據包,存放在b數組中   
                     receiveDp.getData(); //得到緩衝數組
                     receiveDp.getLength(); //得到有效數據長度

URL:統一資源定位符,格式:協議、存放資源的主機域名、端口號和資源文件名
UDP傳輸對象:
                 User user= new   User ( "kkk" , "aaa" );
            bao=new  ByteArrayOutputStream();   // ByteArrayOutputStream() 使用字節數組流來轉化對象
            obj=new ObjectOutputStream(bao);   //將對象寫入對象流,而後再經過字節數組流獲取user的字節數組。
            obj.writeObject(user);
            byte[] arr=bao.toByteArray();
            dp=new DatagramPacket(arr, arr.length,
                    InetAddress. getByName ( "localhost" ), 8888);    

類的靜態加載:編譯時查找須要的類,都會要求已存在,沒有則編譯不經過。  
類的動態加載:把編譯時的檢查異常移到運行時去檢查,只對須要的邏輯進行檢查,其餘地方不檢查。
     Class<?> c=Class.forName("com.kkk.Apple");         //未知類型,用?
     cmd下動態執行加載類命令,java -d  .  test.java
    int arr[]={1,2};
        int brr[]={2,2};
        int crr[][]={{1},{2,3,4}};
        Class<?> c1=arr.getClass();
        Class<?> c2=brr.getClass();
        Class<?> c3=crr.getClass();
        System.out.println(c1==c2);   //都是一維數組 true
        System.out.println(c2==c3);       //一維和二維不同,false
反射技術:(反編譯)
       在運行狀態中,對於任意一個類,都可以知道這 個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意一個方法;   
       這種動態獲取的以及動態調用對象的方法的功能成爲反射機制。
       在編譯時不肯定哪一個類被加載,而在程序運行時才進行加載、探知、使用。
  1.     idF.setAccessible(true); //使用反射機制能夠打破封裝性,致使了java對象的屬性不安全。  
功能體現:
        在運行時斷定任意一個對象所屬的類;在運行時構造任意一個類的對象;在運行時斷定任意一個類所具備的成員變量和方法;
       在運行時調用任意一個對象的方法;生成動態代理。
                                    http://blog.csdn.net/liujiahan629629/article/details/18013523
           //第一種方式:
Class c1 = Class.forName("com.Student");    //包名+類名,得到模板類的對象
c1.getName();               //獲取全路徑名
c1.getSimpleName()    //獲取類名
Modifier.toString(c1.getModifier())             //獲取權限修飾符
//第二種方式:
//java中每一個類型都有class 屬性.
Class c2 = Employee.class;  
//第三種方式:
//java語言中任何一個java對象都有getClass 方法
Employee e = new Employee();
Classc3 = e.getClass(); //c3是運行時類 (e的運行時類是Employee)
反射的主要類:

JDK中,主要由如下類來實現Java反射機制,這些類都位於java.lang.reflect包中

Ø  Class類:表明一個類

Ø  Field 類:表明類的成員變量(屬性)

     getField()  獲取共同屬性

Ø  Method類:表明類的成員方法

     getMethod()返回本類、父類和父接口聲明的public方法

     Method m6=getMethod("getName",null)  //對void能夠這樣用

     m6.invoke(stu,20)     //設置年齡

Ø  Constructor 類:表明類的構造方法    //最好提供一個空參的構造,在框架學習中能夠發現不少都是靠反射無參構造生成

     getConstructors()  只獲取public構造函數

     getDeclaredConstructors 獲取聲明的構造函數

     Student stu=(Student)getConstructor(String.class).newInstance("aa")  獲取public有參構造

Ø  Array類:提供了動態建立數組,以及訪問數組的元素的靜態方法

           List<String> mlist=new ArrayList<String>();
                  mlist.add("aaa");
                  Class cc2=mlist.getClass();
                  Method mt=cc2.getMethod("add", Object.class);  //不能使用add()
                  mt.invoke(mlist, 123);//能夠插入123  
        //利用反射能夠繞過泛型對於源文件數據類型的檢查,換句話說,泛型只是在編譯期間起做用,以後泛型意義不大  
              利用反射實現工廠方法:
                 Class  c=Class.forName(str);     //Factory加載 reflect.reflcet02.Apple
       return (Fruit)c.newInstance();
                 Factory. getFruit ( "reflect.reflcet02.Apple" ).show();   //Test
            或者用Properties來動態讀取配置文件
        File f=new File("fruit.properties");        //將屬性文件存在properties中
                Properties pro= new  Properties();         
                  if (f.exists()){
                      pro.load(new FileInputStream(f));    }      //讀取屬性
               Factory.getFruit(Factory.getPro().getProperty("Apple")).show();     //測試












相關文章
相關標籤/搜索