2010年9月23日 星期四

Java 的 method 參數

最早之前工作是寫 C# 與 VB.Net,後來轉寫 C++ 以後很習慣清楚的標示 function 參數是傳值、傳址或傳參考,最近寫起 Java 發現 Java 和 C# 對於 method 參數是傳值還是傳參考是差不多的觀念,參數簡單的分為兩類

原生型態 (built-in type) 與程式庫內定義的型態 (library type)

built-in type 在方法參數中會採用 call by value 的方式產生副本,而library type 在參數會採用 call by reference 的方式,原因是為了安全與效率,built-in type 僅是資料型態,copy 的成本低,利用call by value 的方式可以降低修改錯誤發生,library type 通常是是宣告出來的 object 實體,可大可小,預設採用 reference 的方式傳遞,若需要 call by value 可用 obj.clone() 來產生副本,使用 obj.clone() 產生副本當然要額外付出的就是複製的時間與記憶體成本。

以下記錄幾個簡單範例


class CJavaMethodExample
{
  public static void main ( String args[ ] )
  {
    double dbl = 5.0;
    tripleValue(dbl); // dbl 還是 5.0,因為 double 為 built-in type

    Double Dbl = 5.0;
    tripleValue(Dbl); // Dbl 變成 15,因為 Double 是 library type

    ArrayList<StockInfo> stocklist_A;
    calculatePrice_A((ArrayList<StockInfo>)stocklist_A.clone());
    // stocklist_A 沒任何影響

    ArrayList<StockInfo> stocklist_B;
    calculatePrice_B(stocklist_B);
    // stocklist_B 被清空了
  }

  public void tripleValue(double dblValue)
  {
    dblValue = dblValue + dblVaulue + dblValue;
  }

  public void calculatePrice(ArrayList<StockInfo> stocklist)
  {
    /*計算總股價*/
    stocklist.clear();
  }
}


另外若我們想要在 listA 上面加上某 obj 的資訊,卻利用傳參考的方式如此設計 obj 內的 function,像這種情況其實容易讓人混淆…


main()
{
  ArrayList<StockInfo> listA;
  obj.addInfo(listA);
}

.....

// obj的Method
public void addInfo(listA)
{
  listA.add(this.m_siCurrentInfo);
}


最好還是利用 return 的方式寫得清楚一些


main()
{
  ArrayList<StockInfo> listA;
  listA.add(obj.getCurrInfo());
}

.....

// obj的Method
public StockInfo getCurrInfo()
{
  return (StockInfo)this.m_CurrentInfo.clone();
}

沒有留言:

張貼留言