機能Java 2章:オブジェクトの作成と破壊


1.生成者に代わってスタティックファクトリメソッドを考える


工場方法説明
  • 静的ファクトリメソッド:クラスインスタンスを返す単純な静的メソッド
  • 
    public static Boolean valueOf(boolean b) {
    	return b ? Boolean.TRUE : Boolean.FALSE;
    }
    
    メリット:
    1)名前を付けることができます
    2)呼び出しのたびに新しいインスタンスを作成する必要はありません.
    3)戻り戻りタイプを返すサブタイプオブジェクトを返す能力がある
    4)入力パラメータに複数のパラメータがあり、毎回異なるクラインを持つオブジェクトを返すことができる
    5)スタティックファクトリメソッドを作成する場合、オブジェクトのクラスに戻る必要はありません.
    欠点:
    1)サブクラスを作成できません
    2)プログラマーはなかなか見つからない.
    例)jdbc
    :クラスに他のオブジェクトを生成するロジックがあります.
    	// 드라이버 가져와서 디비 생성, 연결하는 아이
    	public static Connection getConnection() {
    		try {
    			//어떤 DB 를 사용할 지 선택, 연결하려는 드라이버 명
    			Class.forName("org.h2.Driver"); 
    			
    			//내가 사용하고자 하는 DB(URL)에 ID/PW 로 접근
    			return DriverManager.getConnection("jdbc:h2:tcp://localhost/~/testsq",
    									"sa","");
    		} catch ( Exception e) {
    			e.printStackTrace();
    		}
    		return null;
    	}
    

    2.コンストラクション関数に多くのパラメータがある場合は、コンストラクタを考慮します。

  • コンパイラのクライアントコードの読み書きは、階層ごとのジェネレータよりも簡潔で、JavaBeansよりも安全です.
  • パラメータが多い場合は、クライアントコードの作成や読み取りが困難です.
  • getterとsetterは、コンストラクタとして一度に割り当てるのではなく、ソースコードを混合します.
  • public class Applepie {
    	
        private final int flour;
        public final int apple;
        public final int suger;
        public final int powder;
        
        public static class Builder {
           // 필수 매개변수
           private final int flour;
           public final int apple;
        
           // 선택 매개변수 : 기본값 초기화
           public final int suger = 1;
           public final int powder = 3;
        	
           // 필수 매개변수는 생성자를 사용해 초기화
           Builder( int flour, int apple ) {
             this.flour = 5;
             this.apple = 3
           }
        	
           // 선택 매개변수는 setter 메서드를 사용함
           
           Builder amount0fsuger(int suger) {
           		this.suger =suger;
                return this;
           }
           
           Builder amount0fpowder( int powder) {
           		this.powder;
                return this;
           
          	}
        }
    
    
    }
    

    3.privateジェネレータまたは列挙タイプで単一ループであることを保証

  • 単一インスタンス:
  • クラスには1つのインスタンスしか作成できません
  • クラスを単転に設定すると、クライアントをテストするのは難しいです.mock(偽)実現に代わることができないからだ.
  • 部屋1)共通静的最終使用,ジェネレータprivate
    
    public class Elvis {
    
        // 딱 한번만 인스턴스 호출하였다.
    	public static final Elvis INSTANCE = new Elvis();
       	private Elvis() { }
        
        public void  mynameis() { }
    }
    
  • publicは、保護された作成者がいないため、直感的には、インスタンスは一度だけ呼び出される明確な友人である.AccessibleObject.setAccessibleを使用して、プライベートジェネレータを呼び出す攻撃を行うことができます.この攻撃は、2番目のオブジェクトを生成しようとすると例外を放出します.
  • 部屋2)private static final,ジェネレータはprivate,publicインスタンスを呼び出すことができる
    
    public class Elvis {
         // 변수가 private 라 외부에서 호출 불가
    	private static final Elvis INSTANCE= new Elvis();
       	private Elvis() { ..}
        
        // public으로 된 인스턴스 호출 메서드가 생김
        public static Elvis getInstance() { return INSTANCE; }
        
        public void  mynameis() { }
    }
  • apiは影響を受けず、単輪変更が可能です.ファクトリメソッドを使用するため、サブオブジェクトに複数のオブジェクトを宣言できます.
  • オブジェクトの汎用
  • 部屋3)enumを唯一の要素とする列挙タイプの単一周
    
    public enum Elvis {
    	INSTANCE; 
        public void  mynameis() { .. }
    }
    ほとんどの場合、最良の方法は、1つの要素のみの列挙タイプの単輪を作成することです.

    4.インスタンス化を阻止するには、プライベートジェネレータを使用します。

  • 明示的なジェネレータはprivateであり、クラス外から
  • にアクセスできません.
  • Javaでは、コンストラクション関数がない場合、共通コンストラクション関数が生成されるため、外部からアクセスできるため、プライベートコンストラクション関数を作成すると、エラーコンストラクション関数は自動的に生成されません.
  • 	
        private UtilityClass() {
        	throw new AssertionError();
            
       }
    	

    5.リソースを直接宣言するのではなく、依存オブジェクト注入を使用する

  • 의존성 주입:
  • インスタンスの作成に必要なリソースを作成者に渡します.
  • で使用されるリソースによっては、動作の異なるクラスでは、単一のループは適切ではありません.マルチスレッドを使用する場合.
  • public class daliycheck() {
    	
        private final Todolist todo;
        
        public daliycheck( Todolist todo) {
        	this.todo = Objects.requireNonNull(todo);
        }
    
    }
    
  • クラスの内部で1つ以上のリソースに依存し、これらのリソースがクラスのダイナミック性に影響を及ぼす場合は、単一インスタンスおよび静的ユーティリティクラスは使用しないほうがよい.逆に、必要なリソースを依存オブジェクトに注入します.クラスは生成時に自動的に生成されます.この方法はクラスの柔軟性、再利用性、テスト性に優れている.
  • 6.不要なオブジェクトの生成を避ける


    Stringクラスのmatchは、正規表現に違反する文字列をフィルタできる良いオブジェクトです.
    これも使い捨てのゴミ呼び機の主な対象です.以下の미리 캐싱の方法を使用すると、パフォーマンスの向上に役立ちます.関数を呼び出すたびに、事前にインポートしたほうがパフォーマンスが向上します.
    public class RomanNumerals{
    	private static final Pattern ROMAN = 
    		Pattern.compile("^(?=[MDCLXVI])M*D?C{0,4}L?X{0,4}V?I{0,4}$");
            
    	public static boolean isRomanNumeral(String s){
    		return ROMAN.matcher(s).matches();
    	}
    }

    7.書き上げた相手への引用を解除する

  • メモリ漏れは表面的にははっきり見えず、発見しにくく、放置されることが多い.ダソンへの参照を解除することが重要です.簡単な解決策は、すべてのリソースを使用してnullを次のように処理することです.
  • public Object pop() {
    	if(size == 0) {
            throw new EmptyStackException() ;
         }
        Object res = elements[--size]'
        element[size] = null;
        return res;
    }

    8.定型機とクリーナーの使用を避ける

  • javaでは、オブジェクト消滅者におけるターミネータは予測不可能であり、場合によっては不要である可能性があるので、一般的には使用しないほうがよい.代わりのクリーナーも危険だ.
  • try-finallyではなくtry-with-resourcesを使用


  • try-finallyはたくさん使っていて、よく知っていますが、try-with-resourcesとは何ですか?
    try-with-resourcesは通常、複数のリソースを処理する論理である.

  • why?
    :try-finallyを使用すると、2つの異常tryブロック、finallyブロックが発生する可能性があります.この状況は追跡できる.
  • static void copy(String src, String dst) throws IOException{
    	try(InputStream in = new FileInputStream(src);
    		OutputStream out = new FileOutputStream(dst)) {
    		byte[] buf = new byte[BUFFER_SIZE];
    		int n;
    		while((n = in.read(buf)) >= 0){
    			out.write(buf, 0, n);
    		}
    	} catch (IOException e) {
        	return defaultval;
        }
    }
    
  • catchセクションとともに使用することもできます.