Java的不變類

來源:互聯網
上載者:User

不變類的意思就是不會發生變化的類,就是當類的執行個體被建立後,狀態不會發生變化的類。

 

舉個例子:如果人是一個class,那麼我們中的每一個都是人這個類的具體的instance,如果人這個類只有一個狀態就是生身父母,那麼它就是一個不變類,因為每一個人在出生的那一刹那,生身父母就已經被設定了值,而且終生都不會發生變化。

不變類有什麼好處呢?

1)  不變類是安全執行緒的,由於不變類的狀態在建立以後不再發生變化,所以它可以線上程之間共用,而不需要同步。

2)  不變類的instance可以被reuse

 

建立類的執行個體需要耗費CPU的時間,當這個執行個體不再被引用時,將會被記憶體回收掉,這時候,又需要耗費CPU的時間。對於不變類而言,一個好處就是可以將常用的執行個體進行緩衝,從而減少了對象的建立。舉個例子,對於布爾型,最常用的便是true and false。JDK中的Boolean類就是一個不變類,並且對這兩個執行個體進行了緩衝。

public final class Boolean implements java.io.Serializable{

    /**

     * The <code>Boolean</code> object corresponding to the primitive

     * value <code>true</code>.

     */

    public static final Boolean TRUE = new Boolean(true);

    /**

     * The <code>Boolean</code> object corresponding to the primitive

     * value <code>false</code>.

     */

public static final Boolean FALSE = new Boolean(false);

// 這個方法不會建立新的對象,而是重用已經建立好的instance

  public static Boolean valueOf(boolean b) {

        return (b ? TRUE : FALSE);

}

}
3)  不變類的某些方法可以緩衝計算的結果

hashCode這個方法來自於Object這個類,這個方法用來返回對象的hashCode,主要用於將對象放置到hashtable中時,來確定這個對象的儲存位置。對於一個不變類的執行個體,它的hashCode也是不變的,所以就可以緩衝這個計算的結果,來提高效能,避免不必要的運算,JDK中的String類就是一個例子。

public final class String{

       /** Cache the hash code for the string */

private int hash; // Default to 0

      public int hashCode() {

int h = hash;

if (h == 0) {

       // compute the value

            hash = h; // cache the value
       }
        return h;
    }
}

在JDK中, String, the primitive wrapper classes, and BigInteger and BigDecimal都是不變類。

如果一個類是不變類,這個類是不是就不能有改變狀態的方法呢?

答案當然是否定的,String是一個不變類,仍然有replace,replaceAll這樣的方法,而String仍然是一個不變類,那是因為在這些改變狀態的方法中,每次都是新建立一個String對象。

如果大家理解了不變類,那也就不難理解為什麼在做String的concatenate時,應當用StringBuffer而不是用+的操作符。

如何正確使用String呢?

1)  不要用new去建立String對象。

如果使用new去建立String,那麼每次都會建立一個新對象。

    public static void main(String[] args) {

        String A1 = "A";

        String A2 = "A";  // It won't create a new object

        checkInstance(A1, A2);  // Result:  They are same instances

        String B1 = new String("A"); // create a new object

        String B2 = new String("A"); // creat a new object

        checkInstance(B1, B2); // Result:  They are different instances

    }

    private static void checkInstance(String a1, String a2) {

        if (a1 == a2) {

            System.out.println("They are same instances");

        } else {

            System.out.println("They are different instances");

        }

    }

2)  應當用StringBuffer來做串連操作

因為String是一個不變類,那麼在做串連操作時,就會建立臨時對象來儲存中間的運算結果,而StringBuffer是一個mutable class,這樣就不需要建立臨時的對象來儲存結果,從而提高了效能。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.