Hi

비메모리 자원이 있는 객체와 Try with Resources 본문

Programming/Java

비메모리 자원이 있는 객체와 Try with Resources

SharingWorld 2018. 3. 29. 12:05

 비메모리 자원에 대한 누수가 명시적인 종료 메소드를 호출하지 않을 경우,
 발생할 수도 있고 아닐 수도 있다.


 => 자바 클래스 라이브러리는 비 메모리 자원에 대한 파괴를
 finalize를 통해서 제공하고 있다.


 1) 호출 시점이 명확하지 않다.
 : GC 의 발생시점이 언제인지 알 수 없다.
 2) finalize의 호출이 보장되지 않는다.
 : 누수가 발생할 가능성이 있다.



스택을 만들어보자
class User implements AutoCloseable {
	private String name;
	private int age;

	// File: 비메모리 자원
	// => User라는 객체를 사용할 때 반드시 명시적인 종료 메소드를 제공해야 한다.
	// => Try with Resources 문법을 사용할 수 있도록 AutoClosable에 대한 인터페이스 구현도
	// 제공해야 한다.
	private FileOutputStream fos;

	public User(String name, int age, String filename) throws FileNotFoundException {
		this.name = name;
		this.age = age;
		this.fos = new FileOutputStream(filename);
	}

	@Override
	protected void finalize() throws Throwable {
		super.finalize();

	// 사용자가 close()를 호출하지 않았다.
		if (fos != null) {
			fos.close();
			System.err.println("User에 대해서는 반드시 close를 호출해야 합니다.");
	// Android Framework - CloseGuard
		}

	}

	@Override
	public void close() throws IOException {
		System.out.println("close()");
		if (fos != null) {
			fos.close();
			fos = null;
		}
	}
}


public class Program_0322 {
	public static void main(String[] args) {
	// User 객체에 대해서 Try with Resources 문법을 사용하기 위해서는
	// 약속된 인터페이스를 제공하면 된다.
	// => AutoClosable
		try (User user = new User("Tom", 42, "tom.txt")) {
	// ...
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
/*
public static void main(String[] args) {
	User user = null;
	try {
		user = new User("Tom", 42, "tom.txt");

	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} finally {
		try {
			if (user != null)
			user.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
*/
}