기록이 힘이다.

[이팩티브 자바] 아이템 9 try-finally 보다 try-with-resouces를 사용하라. 본문

JAVA

[이팩티브 자바] 아이템 9 try-finally 보다 try-with-resouces를 사용하라.

dev22 2023. 3. 7. 17:30
728x90
public class TopLine{
	//코드 9-1 try-finally - 더 이상 자원을 회수하는 최선의 방책이 아니다! 47쪽
    static String firstLineOfFile(String path) throws IOException{
    	BufferedReader br = new BadBufferedReader(new FileReader(path));
        try{
        	return br.readLine();
        }finally{
        	br.close();
        }
    }
    
    public static void main(String[] args) throws IOException{
    	System.out.println(firstLineOfFile("pom.xml"));
    }
}
public class BadBufferedReader extends BufferedReader{
	public BadBufferedReader(Reader in, int sz){ super(in, sz); }
    
    public BadBufferedReader(Reader in){ super(in); }
    
    @Override
    public String readLine() throws IOException{
    	throw new CharConversionException();
    }
    
    @Override
    public void close() throws IOException{
    	throw new StreamCorruptedException();
    }
}

디버깅하다보면 가장 처음에 발생하는 예외가 중요하다. 

try resource로 발생하기

public class TopLine{
	//코드 9-1 try-finally - 더 이상 자원을 회수하는 최선의 방책이 아니다! 47쪽
    static String firstLineOfFile(String path) throws IOException{
            try(ufferedReader br = new BadBufferedReader(new FileReader(path)){
            	return br.readLine();	
        }
    }
    
    public static void main(String[] args) throws IOException{
    	System.out.println(firstLineOfFile("pom.xml"));
    }
}

처음 발생하는 예외가 후속 예외도 같이 보이게 된다. try - resource를 사용시 !!

close를 직접 호출하지 않아도 되고 코드가 더 깔끔하게 보이게 된다. 

 

p48, 자바 퍼즐러 예외 처리 코드의 실수

p49, try-with-resources 바이트 코드

 

public class Copy{
	private static final int BUFFER_SIZE = 8 * 1024;
    
    //코드 9-2 자원이 둘 이상이면 try-finally 방식은 너무 지저분하다!(47쪽)
    static void copy(String src, String dst) throws IOException{
    	InputStream in = new FileInputStream(src);
        OutputStream out = new FileOutputStream(dst);
        try{
        	byte[] buf = new byte[BUFFER_SIZE];
            int n;
            while((n = in.read(buf)) >= 0)
            	out.write(buf, 0, n);
        }finally{
        	try{
        		out.close();
            }catch(IOException e){
            //TODO  안전한가? runtimeException이 발생하면 안전하지 않다.
            }
            
            try{
           		 in.close();
    		}catch(IOException e){
            //TODO  안전한가?
            }
        }
    }
    
    public static void main(String[] args) throws IOException{
    	String src = args[0];
        String dst = args[1];
        copy(src, dst);
    }
    
}
public class Copy{
	private static final int BUFFER_SIZE = 8 * 1024;
    
    //코드 9-2 자원이 둘 이상이면 try-finally 방식은 너무 지저분하다!(47쪽)
    static void copy(String src, String dst) throws IOException{
    	InputStream in = new FileInputStream(src);
        OutputStream out = new FileOutputStream(dst);
        try{
        	byte[] buf = new byte[BUFFER_SIZE];
            int n;
            while((n = in.read(buf)) >= 0)
            	out.write(buf, 0, n);
       	 }finally{
        	out.close();
        }finally{
        	in.close();
        }
    }
    
    public static void main(String[] args) throws IOException{
    	String src = args[0];
        String dst = args[1];
        copy(src, dst);
    }
    
}

try - finally 코드가 있다면 고쳐라 !!