본문 바로가기
BackEnd/JAVA

[용어정리] JCP, JSR, JSR-310 정리

by sorryisme 2024. 10. 16.

JCP

  • 자바 커뮤니티 프로세스의 약자로 향후 버전에 기능에 대해 논의하는 과정 및 프로그램
  • 선 마이크로즈에서 기술사양과 개발 및 개정을 위해 프로그램 도입
  • 전 세계 개발자와 조직들이 누구든지 참여할 수 있음

JSR

  • JCP을 통해 Java 플랫폼에 대한 기술 제안 및 최종 사양
  • 여러 벤더사에서 JDK를 JSR기준으로 구현
  • TCK을 통해 테스트를 진행하며 인증, 인증 주관은 Oracle에서 진행한다

JSR-310

  • Date와 Calendar를 대체하여 새롭게 제안된 날짜를 제공
    • 둘 다 월을 나타내는 0-인덱스를 사용, 이로 인해 버그 이슈를 야기함
    • Date와 Calendar 클래스 모두 불변 클래스가 아니라 복제와 스레딩에 대한 부분을 고려해야함
    • 두 날짜 사이의 일수를 계산하는 것이 어려운 문제
  • 위와 같은 문제를 해결하기 위해 Joda-Time 프로젝트에서 진행된 것을 적용
    • 날짜, 시간, 기간, 간격, 서식 , 구문 분석을 위한 모델과 구현 클래스에서 아이디어를 이식함

Java 날짜와 시간 API

 

이전에 작성한 블로그 글을 다시 인용

왜 Date, Calendar 대신 LocalDateTime을 사용할까

자바 개발 초기부터 자주 사용해왔던 것이 Date와 Calendar인데 사실 이 클래스는 굉장히 위험한 문제를 가지고 있다고 한다. (실무에서 많이 경험하는 사이드 이펙트)너무 당연하게 Date와 SimpleDate Format을 사용해왔던 터라 이런 문제를 가지고 있는지 인지하지 못했다.많은 개발자들이 Date,Calendar 대신 LocalDateTime, LocalDate를 사용하고 있어서 알아보았다.


Date와 Calendar는 불변객체가 아니다

 

네이버 기술블로그 Java의 날짜와 시간 API에서 다음과 같이 기술한다.

불행히도 Java의 기본 날짜, 시간 클래스는 불변 객체가 아니다. 앞의 코드에서 Calendar 클래스에 set 메서드를 호출해서 날짜를 지정하고, 다시 같은 객체에 set(int,int) 메서드를 호출해서 수행한 날짜 연산 결과는 같은 인스턴스에 저장되었다. Date 클래스에도 값을 바꿀 수 있는 set 메서드가 존재한다. 이 때문에 Calendar 객체나 Date 객체가 여러 객체에서 공유되면 한 곳에서 바꾼 값이 다른 곳에 영향을 미치는 부작용이 생길 수 있다. 『Effective Java 2nd Edition』(2008)의 저자 Joshua Bloch도 Date 클래스는 불변 객체여야 했다고 지적했다.[18]

 

Date의 setter은 deprecated 되었지만 (API 문서에서는 not immutable 문제때문에 deprecated 된 것이 아니라 calendar.set으로 replaced되었다고 나와있다.) 실제로 다음과 같은 코드에서 처럼 setter를 사용 시 실제 객체 값이 변동되는 것을 확인할 수 있었다.

 

 

Date date = new Date();
Member member = new Member();
member.setName("1번째 회원");
member.setJoinDate(date);

printMember(member);
Date date2 = new Date();
Member member2 = new Member();
member2.setName("2번째 회원");
member2.setJoinDate(date2);

printMember(member2);
date.setDate(1);
System.out.println("----------------------------------------");
printMember(member);
printMember(member2);
~~~
<<결과값>>
가입이름 : 1번째 회원가입 일자 : Sat Jan 18 04:08:47 KST 2020
가입이름 : 2번째 회원가입 일자 : Sat Jan 18 04:08:47 KST 2020
---------------------------------------------
가입이름 : 1번째 회원가입 일자 : Wed Jan 01 04:08:47 KST 2020
가입이름 : 2번째 회원가입 일자 : Sat Jan 18 04:08:47 KST 2020
~~~

date에서 set을 사용할 경우 member 객체에 저장된 가입일자가 변했다는 사실을 확인할 수 있다. 이런 문제 외에도 헷갈리는 월지정, int 상수필드에 대한 내용들을 문제점으로 지적하는데 이를 해결하기 위한 라이브러리가 JodaTime이다.

 

Joda-Time

LocalDateTime localDateTime = new LocalDateTime();
Member member = new Member();
member.setName("1번째 회원");
member.setJoinDate(localDateTime.now());

printMember(member);
localDateTime.plusDays(1);

System.out.println("-----------------------------------------");
printMember(member);
가입이름 : 1번째 회원가입 일자 : 2020-01-18T04:21:55.072
---------------------------------------------
가입이름 : 1번째 회원가입 일자 : 2020-01-18T04:21:55.072
  • 기존 Date와 비슷한 코드이지만 메소드를 호출해도 실제 member 객체 내 가입일자는 변동되지 않는다.

실제 내부 plusDays 메소드

public LocalDateTime plusDays(int days) {
	if (days == 0) {
    	return this;
	}
	long instant = getChronology().days().add(getLocalMillis(), days);
    return withLocalMillis(instant);
}

LocalDateTime withLocalMillis(long newMillis) {
	return (newMillis == getLocalMillis() ? this :
            			new LocalDateTime(newMillis, getChronology()));
}

 

 

실제 값을 비교해서 현재 값과 동일하거나 인자값이 0일 경우 현재 객체를 리턴하고 그 외 모든 경우 새로운 객체를 생성해서 전달하는 것을 알 수 있다. 라이브러리를 받아서 사용하면 되지만 java8 부터는 joda-Time이 아닌 java.time 에서 제공해주는 LocalDateTime을 사용하면 된다.

 

 

 

참고

https://jcp.org/en/jsr/detail?id=310

네이버 기술 블로그 : https://d2.naver.com/helloworld/645609

자바 8 API Documentation : https://docs.oracle.com/javase/8/docs/api/

jodaTime : https://www.joda.org/joda-time/