250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 자료구조
- DDD
- 이팩티브 자바
- 클린코드
- 이펙티브자바
- 자바예외
- 자바스터디
- SQL쿡북
- 스프링부트와AWS로혼자구현하는웹서비스
- 인덱스
- 인프런백기선
- aop
- AWS RDS
- vue.js
- 혼공SQL
- 알고리즘분석
- 인프런김영한
- react
- mysql
- CleanCode
- 네트워크
- jpa
- 도메인 주도 개발 시작하기
- AWS
- MariaDB
- 알고리즘
- 자바
- java
- 기술면접
- 이펙티브 자바
Archives
- Today
- Total
기록이 힘이다.
[이팩티브 자바]아이템 8. 완벽 공략 Finalizer/ AutoCloseable 본문
728x90
Finalizer 공격
import java.math. BigDecimal;
public class Account {
private String accountId;
public Account(String accountId){
this.accountId = accountId;
if(accountId.equals("푸틴")){
throw new IllegalArgumentException("푸틴은 계정을 막습니다.");
//finalizer를 통해 보낼 수 있다
}
}
public void transfer(BigDecimal amount, String to){
System.out.printf("transfer %f from %s to %s\n", amount, accountId, to);
}
}
public class BrokenAccount extends Account{
public BrokenAccount(String accountId){
super(accountId);
}
@Override
protected void finalize() throws Throwable{
this.transfer(BigDecimal.valueOf(100), "keesun");
}
}
- 테스트 코드
- 방어하는 방법
- final 클래스로 만들거나
- finalizer() 메소드를 오버라이딩 한 다음 final을 붙여서 하위 클래스에서 오버라이딩 할 수 없도록 막는다.
class AccountTest{
@Test
void 일반_계정(){
Account account = new Account("keesun");
account.transfer(BigDecimal.valueOf(10,4), "hello");
}
@Test
void 푸틴_계정() throws InterruptedException{
Account account = null;
try{
account = new BrokenAccount("푸틴");
}catch(Exception exception){
System.out.println("이러면??");
}
System.gc();
Thread.sleep(3000L);
}
}
import java.math. BigDecimal;
public final class Account { //상속을 할 필요가 없으면 final로 막을 수 있다.
private String accountId;
public Account(String accountId){
this.accountId = accountId;
if(accountId.equals("푸틴")){
throw new IllegalArgumentException("푸틴은 계정을 막습니다.");
//finalizer를 통해 보낼 수 있다
}
}
public void transfer(BigDecimal amount, String to){
System.out.printf("transfer %f from %s to %s\n", amount, accountId, to);
}
}
import java.math. BigDecimal;
public class Account { //상속을 해야 한다면 메소드에 final을 붙인다.
private String accountId;
public Account(String accountId){
this.accountId = accountId;
if(accountId.equals("푸틴")){
throw new IllegalArgumentException("푸틴은 계정을 막습니다.");
//finalizer를 통해 보낼 수 있다
}
}
public void transfer(BigDecimal amount, String to){
System.out.printf("transfer %f from %s to %s\n", amount, accountId, to);
}
@Override
protected final void finalize() throws Throwable{}
}
AutoClosable
@author josh Bloch // 교재의 지은이이다.
@since1.7
public interface AutoCloseable{
void close() throws Exception;
}
인터페이스를 쓰면 main에서 finaly 블럭을 안써도 된다.
import java.io.*;
public class AutoClosableIsGood implements AutoCloseable{
private BufferedReader reader;
public AutoClosableIsGood(String path){
try{
this.reader = new BufferedReader(new FileReader(path));
}catch(FileNotFoundException e){
throw new IllegalArgumentException(path);
}
}
@Override
public void close() throws IOException {
reader.close();
}
}
import java.io.IOException;
public class App{
public static void main(String[] args){
try(AutoCloseableIsGood good = new AutoCloseableIsGood("")){
//TODO 자원 반납 처리가 됨.
}catch(IOException e){
e.printStackTrace();
}
}
}
import java.io.*;
public class AutoClosableIsGood implements AutoCloseable{
private BufferedReader reader;
public AutoClosableIsGood(String path){
try{
this.reader = new BufferedReader(new FileReader(path));
}catch(FileNotFoundException e){
throw new IllegalArgumentException(path);
}
}
@Override
public void close() { //던지지 않고 잡으면 굳이 클라이언트 코드에서 잡을 필요가 없다.
try{
reader.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
import java.io.*;
public class AutoClosableIsGood implements AutoCloseable{
private BufferedReader reader;
public AutoClosableIsGood(String path){
try{
this.reader = new BufferedReader(new FileReader(path));
}catch(FileNotFoundException e){
throw new IllegalArgumentException(path);
}
}
@Override
public void close() { //던지지 않고 잡으면 굳이 클라이언트 코드에서 잡을 필요가 없다.
try{
reader.close();
}catch(IOException e){
throw new RuntimeException(e);
}
}
}
읽고 쓰거나 하면 Closeable을 쓰는 게 좋은 선택이 될 수도 있다. -->더 많은 규약이 있다.
'JAVA' 카테고리의 다른 글
[이펙티브 자바] 10. equals는 일반 규약을 지켜 재정의하라 (2) | 2023.03.14 |
---|---|
[이팩티브 자바] 아이템 9 try-finally 보다 try-with-resouces를 사용하라. (0) | 2023.03.07 |
아이템6 불필요한 객체 생성을 피하라 (0) | 2023.01.27 |
아이템5 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) | 2023.01.26 |
아이템3. 생성자나 열거 타입으로 싱글턴임을 보증하라. (0) | 2023.01.25 |