天天看點

較長的描述Java進階優化技術及裡氏置換原則(Liskov Substitution Principle)

Ⅰ、Java進階優化技術常用如下幾點:

    1.優化循環。通過重新組織重複的子表達式來提高循環體的運作性能。

    2減少使用對象的數量來提高運作性能。

    3.縮減網絡傳輸資料來縮短等待時間。

    其他:

    1.采用對象池技術,提高對象的利用效率。

    性能的損耗主要源于建立和釋放對象,是以要避免對象的建立和釋放。采用對象池技術,預先定義一個對象池,預先建立一組待使用的對象:

    Enemy[5] enemy=new Enemy[5];

    for(int i=0;i<5;i++){

    enemy[i]=new Enemy();

    }

    增加标志如used和reset辨別Enemy的狀态。需要建立對象時從對象池中擷取 一個未被使用的對象并用reset方法初始化;需要釋放時隻需修改标志位以供下次使用即可。   

    2.盡可能使用基本資料類型代替對象

    例如用二維數組代替一個寫簡單的對象。

    3.優化算法

    比如對于默寫不要求很精細的場景和算法,用簡單的算法模拟。

    4.其他優化

    a.如提取字元串時,試着傳回子串而不是建立一個副本。

    b.盡量的少建立短期的臨時對象。

    c.能用庫函數的就不要自己建立(庫函數是優化好的)

    d.Map map=new HashMap();

    HashMap map=new HashMap();  //這個性能更高,重構代碼

    e.增強型for循環和Iterable使用時,多了一個對象的建立,慎用。

    f.避免enum類型。

    g.嵌入式開發時注意浮點的運用,盡量不用。(處理器是否支援浮點)

    h.圖檔資源壓縮、多張圖檔集中到一張圖檔上(比單獨的和小很多,省去了每張的頭檔案、結束檔案等資料塊,合并了調色闆)

Ⅱ、裡氏置換原則(Liskov Substitution Principle),簡稱LSP

  定義:

  Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

  所有引用基類的地方必須能夠透明的使用其子類對象。

  也就是說,隻要父類出現的地方子類就能夠出現,而且替換為子類不會産生任何錯誤或異常。但是反過來,子類出現的地方,替換為父類就可能出現問題了。

  這個原則是為良好的繼承定義一個規範,簡單的講,有4層含義:

  一、子類必須完全實作父類的方法

  定義一個抽象類

  public abstract class ViewPoint { //去麗江旅遊public abstract void where();}下面兩個類是實作這個抽象類

  public class Lijiang extends ViewPoint {

  @Override public void where() { System.out.println("歡迎來到麗江……");}

  } public class Zhangjiajie extends ViewPoint {

  @Override public void where() { System.out.println("歡迎來到張家界……");}

  }人物是塗塗,在裡面設定類類型來傳遞參數。此時塗塗要去的旅遊景點還是抽象的

  public class Tutu { //定義要旅遊的景點private ViewPoint viewpoint;//塗塗要去的景點public void setViewPoint(ViewPoint viewpoint)

  { this.viewpoint = viewpoint;}

  public void travelTo()

  { System.out.println("塗塗要去旅遊了");viewpoint.where();}場景類。設定具體要去的景點

  public class Sence { public static void main(String args[])

  { Tutu tutu = new Tutu();//設定要去的旅遊景點tutu.setViewPoint(new Lijiang());tutu.travelTo();}運作結果:

  塗塗要去旅遊了

  歡迎來到麗江……

  二、子類可以有自己的特性

  也就是說在類的子類上,可以定義其他的方法或屬性

  三、覆寫或者實作父類的方法時輸入參數可以被放大

  父類能夠存在的地方,子類就能存在,并且不會對運作結果有變動。反之則不行。

  父類,say()裡面的參數是HashMap類型,是Map類型的子類型。(因為子類的範圍應該比父類大)

  import java.util.Collection;import java.util.HashMap;

  public class Father { public Collection say(HashMap map)

  { System.out.println("父類被執行……");return map.values();}子類,say()裡面的參數變成了Map類型,Map範圍比HashMap類型大,符合LSP原則。注意這裡的say不是覆寫父類的say,因為參數類型不同。而是重載。

  import java.util.Collection;import java.util.Map;

  /* * 子類繼承了父類的所有屬性*/ public class Son extends Father { //方法輸入參數類型public Collection say(Map map)

  { System.out.println("子類被執行……");return map.values();}場景類

  import java.util.HashMap;

  public class Home { public static void main(String args[])

  { invoke();}

  public static void invoke()

  { //父類存在的地方,子類就應該能夠存在//Father f = new Father();Son s = new Son();HashMap map = new HashMap();//f.say(map);s.say(map);}無論是用父類還是子類調用say方法,得到的結果都是

  父類被執行……

  但是,如果将上面Father裡的say參數改為Map,子類Son裡的say參數改為HashMap,得到的結果就變成了

  f.say(map)結果:父類被執行……

  s.say(map)結果: 子類被執行……

  這樣會造成邏輯混亂。是以子類中方法的前置條件必須與父類中被覆寫的前置條件相同或者更寬。

  四、覆寫或者實作父類的方法時輸出結果可以被縮小

  其實與上面的類似,也就是父類能出現的地方子類就可以出現,而且替換為子類不會産生任何錯誤或者異常,使用者也無需知道是父類還是子類。但是反過來就不行了,有子類出現的地方,父類未必就适應。(畢竟子類的範圍要>=父類的範圍)