Item 5:不要なオブジェクトの作成を避ける

1881 ワード

このアイテムは、再利用できる時には新しいオブジェクトを作成しない方がいいです。
String自動箱詰めの例
まずStringの例を挙げた。Stringを作成する時、new一つのSteringではなく、直接Javaの自動箱詰め方法を使います。
String s = new String("stringette"); // DON'T DO THIS!
このようにします
String s = "stringette";
これはsingle String instanceです。仮想的に同じ文字列の文字列の文字列がある限り、このオブジェクトは再利用されます。
基本データの種類は=で判断して等しいことを知っています。包装後のデータの種類はObjects.equalsで判断します。Stringにはまた==equals方法があります。Stringのprmitive typeとwrapper classは全部Stringです。
この問題は前にも考えましたが、サイクル内の変数宣言問題です。コンパイラは最適化されます。そうしないと多くのオブジェクトが作成されます。
String自動箱詰めの面白い例もあります。newは同じ文字列で、equalsはtrueと判断しますが、==判断はfalseです。
           String str1 ="abc";
           String str2 ="abc";
           System.out.println(str2==str1);  //    true 
System.out.println(str2.equals(str1));  //    true 
            
           String str3 =new String("abc");
           String str4 =new String("abc"); 
           System.out.println(str3==str4);  //    false 
System.out.println(str3.equals(str4));  //    true
これはequalsがString内の値を判断し、==元のデータタイプを判断したからです。str 1とstr 2は同じ対象を引用していますが、str 3とstr 4は異なる対象を引用しています。
第二の例
isBabyBoomerの例を挙げると、再利用できる2つの定数をstatic finalと定義するのが主な考え方です。呼出ごとに新しいオブジェクトを作るのではなく、static finalと定義します。
後にMapの例を挙げましたが、よく分かりませんでした。
第三の例、Longの自動箱詰め
package com.czgo.effective;

public class TestLonglong {

    public static void main(String[] args) {
        Long sum = 0L;
        for(long i = 0; i < Integer.MAX_VALUE; i++){
            sum += i;
        }
        System.out.println(sum);
    }
    
}
このプログラムで計算した結果は正しいですが、実際の状況より遅いのは1文字を間違えただけです。変数sumはlongではなくLongとして宣言されており、プログラムは約2の31乗の余分なLongインスタンスを構成している(Long sumにlongを追加するたびに一例を作成する)。sumの声明をLongからlongに変更しました。スピードが速くなりました。結論ははっきりしています。引用タイプではなく基本タイプを優先して使います。無意識の自動箱詰めに注意してください。