Open zpqmdh opened 1 week ago
Q.
책에 수록된 Period 예제를 자바 8이상으로 개발할 때 Instant 혹은 LocalDateTime, ZonedDateTime을 사용하는 방법을 제시하며 다른 방법으로 위의 인용구를 제시하였습니다. 해당 방법을 적용하면 어떻게 코드를 수정할 수 있는지 보여주실 수 있나요?
A.
import java.util.Date;
public class Period {
// 기존 코드에서의 start, end는 Date 객체였지만 getTime()을 사용할 경우 객체의 밀리세컨드 값을 저장합니다.
private final long start;
private final long end;
public Period(Date start, Date end) {
/*
Date 객체를 그대로 사용하지 않고 내부의 밀리세컨드 long 값을 사용하므로 방어적 복사가 필요하지 않습니다.
이때 생성자로 객체를 만든 뒤에 곧바로 매개변수로 들어온 Date 객체인 start 또는 end 값을 수정하더라도 이미
long 값으로 복사가 완료되었기 때문에 현재 Period 에는 어떠한 영향도 끼칠 수 없습니다.
추가적으로 매개변수로 들어온 start 또는 end 가 null 인 경우에도 getTime()을 수행하면서 NullPointerException 이 throw 되므로
매개변수 검증에서 null 체크가 자동으로 되는 것도 확인할 수 있습니다.
*/
this.start = start.getTime();
this.end = end.getTime();
/*
compareTo 에서 양수가 된다는 것은 start 를 밀리세컨드로 변환했을 때 end 를 밀리세컨드로 반환한 것보다
큰 상태를 의미하므로 다음과 같이 변경할 수 있습니다.
*/
if(this.start > this.end) {
throw new IllegalArgumentException("Start date cannot be greater than end date");
}
}
/*
Getter 함수에서도 방어적 복사를 수행하여 객체 값을 반환할 필요가 없습니다.
이미 생성한 값이 long 이기 때문입니다.
*/
public long getStart() {
return start;
}
public long getEnd() {
return end;
}
public static void main(String[] args) {
Date startDate = new Date(2012, 1, 12);
Date endDate = new Date(2014, 12, 12);
try {
Period period = new Period(startDate, endDate);
System.out.println("수정 전 startDate의 millisecond : " + startDate.getTime());
startDate.setYear(2015);
System.out.println("period 의 start millisecond : " + period.getStart());
System.out.println("수정된 startDate의 millisecond : " + startDate.getTime());
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
}
현재 Date
의 setYear()
, setMonth()
, setDate()
메서드의 경우 deprecated 된 상태임을 유의해주세요 테스트 코드에서는 편의를 위해 사용하였습니다.
만약 Period
객체에서 가지고 온 start
, end
로 새로운 Date
객체를 생성하고 싶을 경우 Date
생성자에서 밀리세컨드를 기반으로 한 Date
객체 생성을 지원하기 때문에 그대로 new Date(period.getStart())
를 해주시면 됩니다.
결과 사진에서도 악의적 공격에 의한 객체 수정이 이루어졌으나 Period 클래스 내부 값은 변경되지 않음을 확인할 수 있습니다.
책에 수록된
Period
예제를 자바 8이상으로 개발할 때Instant
혹은LocalDateTime
,ZonedDateTime
을 사용하는 방법을 제시하며 다른 방법으로 위의 인용구를 제시하였습니다.해당 방법을 적용하면 어떻게 코드를 수정할 수 있는지 보여주실 수 있나요?