從制造到創(chuàng)造
          軟件工程師成長之路
          posts - 292,  comments - 96,  trackbacks - 0
          實踐1:參數(shù)以by value方式而非by reference方式傳遞
          實踐2:對不變的data和object reference使用final
          實踐3:缺省情況下所有non-static函數(shù)都可被重寫
          實踐4:在array和Vectors之間慎重選擇
          實踐5:多態(tài)(polymorphism)優(yōu)于instanceof
          實踐6:必要時才使用instanceof
          實踐7:一旦不需要object reference,就將它設為null

          實踐1:參數(shù)以by value方式而非by reference方式傳遞

          import java.awt.Point;

          class PassByValue {
              
          public static void modifyPoint(Point pt, int j) {
                  pt.setLocation(
          55); // 1
                  j = 15;
                  System.out.println(
          "During modifyPoint " + "pt = " + pt + " and j = " + j);
              }

              
          public static void main(String args[]) {
                  Point p 
          = new Point(00); // 2
                  int i = 10;
                  System.out.println(
          "Before modifyPoint " + "p  = " + p + " and i = " + i);
                  modifyPoint(p, i); 
          // 3
                  System.out.println("After  modifyPoint " + "p  = " + p + " and i = " + i);
              }
          }
          這段代碼在//2處建立了一個Point對象并設初值為(0,0),接著將其值賦予object reference 變量p。然后對基本類型int i賦值10。//3調(diào)用static modifyPoint(),傳入p和i。modifyPoint()對第一個參數(shù)pt調(diào)用了setLocation(),將其左邊改為(5,5)。然后將第二個參數(shù)j賦值為15.當modifyPoint()返回的時候,main()打印出p和i的值。

          程序輸出如下:
          Before modifyPoint p  = java.awt.Point[x=0,y=0] and i = 10
          During modifyPoint pt 
          = java.awt.Point[x=5,y=5] and j = 15
          After   modifyPoint p  
          = java.awt.Point[x=5,y=5] and i = 10

          這顯示modifyPoint()改變了//2 所建立的Point對象,卻沒有改變int i。在main()之中,i被賦值10.由于參數(shù)通過by value方式傳遞,所以modifyPoint()收到i的一個副本,然后它將這個副本改為15并返回。main()內(nèi)的原值i并沒有受到影響。

          對比之下,事實上modifyPoint() 是在與“Point 對象的 reference 的復件”打交道,而不是與“Point對象的復件”打交道。當p從main()被傳入modifyPoint()時,傳遞的是p(也就是一個reference)的復件。所以modifyPoint()是在與同一個對象打交道,只不過通過別名pt罷了。在進入modifyPoint()之后和執(zhí)行 //1 之前,這個對象看起來是這樣:

          所以//1 執(zhí)行以后,這個Point對象已經(jīng)改變?yōu)?5,5)。

          實踐2:對不變的data和object reference使用final

          Java 關鍵字 final 用來表示常量數(shù)據(jù)。例如:

          public class Test {
              
          static final int someInt = 10;
              
          // 
          }

          這段代碼聲明了一個 static 類變量,命名為 someInt,并設其初值為10。
          任何試圖修改 someInt 的代碼都將無法通過編譯。例如:

              // 
              someInt = 9// Error
              
          // 

          關鍵字 final 可防止 classes 內(nèi)的 instance 數(shù)據(jù)遭到無意間的修改。如果我們想要一個常量對象,又該如何呢?例如:

          class Circle {
              
          private double rad;

              
          public Circle(double r) {
                  rad 
          = r;
              }

              
          public void setRadius(double r) {
                  rad 
          = r;
              }

              
          public double radius() {
                  
          return rad;
              }
          }

          public class FinalTest {
              
          private static final Circle wheel = new Circle(5.0);

              
          public static void main(String args[]) {
                  System.out.println(
          "Radius of wheel is " + wheel.radius());
                  wheel.setRadius(
          7.4);
                  System.out.println(
          "Radius of wheel is now " + wheel.radius());
              }
          }

          這段代碼的輸出是:

          Radius of wheel is 5.0
          Radius of wheel is now 
          7.4

          在上述第一個示例中,我們企圖改變final 數(shù)據(jù)值時,編譯器會偵測出錯誤。
          在第二個示例中,雖然代碼改變了 instance變量wheel的值,編譯器還是讓它通過了。我們已經(jīng)明確聲明wheel為final,它怎么還能被改變呢?
          不,我們確實沒有改變 wheel 的值,我們改變的是wheel 所指對象的值。wheel 并無變化,仍然指向(代表)同一個對象。變量wheel是一個 object reference,它指向?qū)ο笏诘膆eap位置。有鑒如此,下面的代碼會怎樣?

          public class FinalTest {
              
          private static final Circle wheel = new Circle(5.0);

              
          public static void main(String args[]) {
                  System.out.println(
          "Radius of wheel is " + wheel.radius());
                  wheel 
          = new Circle(7.4); // 1
                  System.out.println(
          "Radius of wheel is now " + wheel.radius());
              }
          }

          編譯代碼,// 1 處出錯。由于我們企圖改變 final 型變量 wheel 的值,所以這個示例將產(chǎn)生編譯錯誤。換言之,代碼企圖令wheel指向其他對象。變量wheel是final,因此也是不可變的。它必須永遠指向同一個對象。然而wheel所指向的對象并不受關鍵字final的影響,因此是可變的。

          關鍵字 final 只能防止變量值的改變。如果被聲明為 final 的變量是個 object reference,那么該reference不能被改變,必須永遠指向同一個對象,但被指的那個對象可以隨意改變內(nèi)部的屬性值。

          實踐3:缺省情況下所有non-static函數(shù)都可以被覆蓋重寫

          關鍵字final 在Java中有多重用途,即可被用于instance變量、static變量,也可用于classes或methods,用于類,表示該類不能有子類;用于方法,表示該方法不允許被子類覆蓋。

          實踐4:在array和vectors之間慎重選擇

          array和Vector的比較

           

          支持基本類型

          支持對象

          自動改變大小

          速度快

          array

          Yes

          Yes

          No

          Yes

          Vector

          No(1.5以上支持)

          Yes

          Yes

          No

          實踐5:多態(tài)(polymorphism)優(yōu)于instanceof

          代碼1:instanceof方式

          interface Employee {
              
          public int salary();
          }

          class Manager implements Employee {
              
          private static final int mgrSal = 40000;

              
          public int salary() {
                  
          return mgrSal;
              }
          }

          class Programmer implements Employee {
              
          private static final int prgSal = 50000;
              
          private static final int prgBonus = 10000;

              
          public int salary() {
                  
          return prgSal;
              }

              
          public int bonus() {
                  
          return prgBonus;
              }
          }

          class Payroll {
              
          public int calcPayroll(Employee emp) {
                  
          int money = emp.salary();
                  
          if (emp instanceof Programmer)
                      money 
          += ((Programmer) emp).bonus(); // Calculate the bonus
                  return money;
              }

              
          public static void main(String args[]) {
                  Payroll pr 
          = new Payroll();
                  Programmer prg 
          = new Programmer();
                  Manager mgr 
          = new Manager();
                  System.out.println(
          "Payroll for Programmer is " + pr.calcPayroll(prg));
                  System.out.println(
          "payroll for Manager is " + pr.calcPayroll(mgr));
              }
          }
          依據(jù)這個設計,calcPayroll()必須使用instanceof操作符才能計算出正確結果。因為它使用了Employee接口,所以它必須斷定Employee對象究竟實際屬于哪個class。程序員有獎金而經(jīng)理沒有,所以你必須確定Employee對象的運行時類型。

          代碼2:多態(tài)方式
          interface Employee {
              
          public int salary();

              
          public int bonus();
          }

          class Manager implements Employee {
              
          private static final int mgrSal = 40000;
              
          private static final int mgrBonus = 0;

              
          public int salary() {
                  
          return mgrSal;
              }

              
          public int bonus() {
                  
          return mgrBonus;
              }
          }

          class Programmer implements Employee {
              
          private static final int prgSal = 50000;
              
          private static final int prgBonus = 10000;

              
          public int salary() {
                  
          return prgSal;
              }

              
          public int bonus() {
                  
          return prgBonus;
              }
          }

          class Payroll {
              
          public int calcPayroll(Employee emp) {
                  
          // Calculate the bonus. No instanceof check needed.
                  return emp.salary() + emp.bonus();
              }

              
          public static void main(String args[]) {
                  Payroll pr 
          = new Payroll();
                  Programmer prg 
          = new Programmer();
                  Manager mgr 
          = new Manager();
                  System.out.println(
          "Payroll for Programmer is " + pr.calcPayroll(prg));
                  System.out.println(
          "Payroll for Manager is " + pr.calcPayroll(mgr));
              }
          }
          在這個設計中,我們?yōu)镋mployee接口增加了 bonus(),從而消除了instanceof的必要性。實現(xiàn)Employee接口的兩個 classes:Programmer和Manager,都必須實現(xiàn)salary()和bonus()。這些修改顯著簡化了calcPayroll()。


          實踐6:必要時才使用instanceof

          import java.util.Vector;

          class Shape {
          }

          class Circle extends Shape {
              
          public double radius() {
                  
          return 5.7;
              }
              
          // 
          }

          class Triangle extends Shape {
              
          public boolean isRightTriangle() {
                  
          // Code to determine if triangle is right
                  return true;
              }
              
          // 
          }

          class StoreShapes {
              
          public static void main(String args[]) {
                  Vector shapeVector 
          = new Vector(10);
                  shapeVector.add(
          new Triangle());
                  shapeVector.add(
          new Triangle());
                  shapeVector.add(
          new Circle());
                  
          // 
                  
          // Assume many Triangles and Circles are added and removed
                  
          // 
                  int size = shapeVector.size();
                  
          for (int i = 0; i < size; i++) {
                      Object o 
          = shapeVector.get(i);
                      
          if (o instanceof Triangle) {
                          
          if (((Triangle) o).isRightTriangle()) {
                              
          // 
                          }
                      } 
          else if (o instanceof Circle) {
                          
          double rad = ((Circle) o).radius();
                          
          // 
                      }
                  }
              }
          }
          這段代碼表明在 這種場合下 instanceof 操作符是必需的。當程序從Vector 取回對象,它們屬于java.lang.Object。利用instanceof確定對象實際屬于哪個class后,我們才能正確執(zhí)行向下轉型,而不至于在運行期拋出異常。

          實踐7:一旦不再需要object reference,就將它設為null

          posted on 2008-02-26 17:56 CoderDream 閱讀(303) 評論(0)  編輯  收藏 所屬分類: 學習筆記

          <2008年2月>
          272829303112
          3456789
          10111213141516
          17181920212223
          2425262728291
          2345678

          常用鏈接

          留言簿(9)

          我參與的團隊

          隨筆分類(245)

          隨筆檔案(239)

          文章分類(3)

          文章檔案(3)

          收藏夾(576)

          友情鏈接

          搜索

          •  

          積分與排名

          • 積分 - 458389
          • 排名 - 114

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 漾濞| 来凤县| 庆城县| 革吉县| 定兴县| 安义县| 铜鼓县| 黎城县| 博兴县| 东兴市| 阜南县| 荆门市| 五莲县| 蒙阴县| 棋牌| 稷山县| 永靖县| 九龙坡区| 章丘市| 沧州市| 兴文县| 邹平县| 达孜县| 靖安县| 仁化县| 左云县| 乳山市| 勐海县| 嘉义市| 永安市| 江永县| 体育| 靖宇县| 蚌埠市| 铜梁县| 汤阴县| 通江县| 浙江省| 徐汇区| 如东县| 潞城市|