본문 바로가기

Programming/Java & Spring 관련 내용 정리

[코드리뷰 받은 내용 정리] 코드를 작성할 때 '이것'을 생각해보자!

🎨 참조타입 vs 원시타입

 

 

@Schema(description = "정기알림 신청여부", example = "false")
private Boolean monthlyRequestYn;

 

 

 

[ 위 코드에 대한 코드리뷰 내용 ]

 

" 개인적으론 Boolean type은 boolean을 쓰는 걸 추천합니다.

Reference type과 성능 차이도 있을 수 있지만 null point exception 과 같은 것도 고민안해도 되니깐요.

 

특히 boolean type은 만약 입력을 하지 않으면

false나 true 둘 중에 하나의 default 값이 존재하는 경우가 많아서

reference type을 쓸일이 더 없었던거 같아요. 물론 100%라고 말씀드릴 순 없어요.

 

그러나 여기는 false가 default 일거 같긴하네요. "

 

* Boolean과 boolean은 다르다!

 

어떻게 다를까?

 

 

 

Boolean type은 boolean(primitive type)을 쓰도록 해보자.

참조타입과 성능 차이가 있고, null point exception 상황을 고민하지 않아도 된다.

boolean type은 만약 입력을 하지 않으면 false나 true 둘 중에 하나의 default 값이 존재하는 경우가 많다.

 

 

 

* 참조타입과 원시타입의 성능은 어떻게 다를까?

 

[ 성능 관점 ]

 

 

 

 

원시 타입은 스택 영역에 존재한다.

반면 참조 타입은 스택 영역에는 참조 값만 있고, 실제 값은 힙 영역에 존재한다.

 

참조 타입은 최소 2번 메모리 접근을 해야 하고,

일부 타입의 경우 값을 필요로 할 때 언박싱 과정(ex. Double → double, Integer → int)을 거쳐야 하므로

원시 타입과 비교해서 접근 속도가 느린 편이다.

 

 

 

 

[ 메모리 관점 ]

 

 

원시 타입보다 참조 타입이 사용하는 메모리 양이 압도적으로 높다.

 

 

 

[ Null 관점 ]

 

원시 타입은 null을 담을 수 없지만, 참조 타입은 null을 담을 수 있다.

원시 타입의 경우, 값이 없으면 디폴트 값을 반환하기 때문이다. (ex. int은 0, boolean은 false)

 

 

 


🎨 long 타입 데이터의 유효성 검사에서

@NotNull과 @NotEmpty는 의미가 없다.

 

 

‘custSeq(사용자 순번)’은 요청 데이터에서 필수값이기에

@NotNull과 @NotEmpty 어노테이션을 붙여 유효성 체크를 하려고 했다.

 

@NotNull @NotEmpty
@Schema(description = "사용자 순번", example = "598")
private long custSeq;

 

하지만 long 타입 데이터에 @NotEmpty 유효성 체크 어노테이션을 붙이는 것은 의미가 없다.

 

 

왜 의미가 없을까?

 

1. long은 원시타입 (primitive type) 이기 때문에 null이 없고, default value 는 0L.

→ 따라서 @NotNull을 붙이는 것은 의미 없음

 

2. @NotEmpty 가 지원되는 유형은 다음과 같다.

  • CharSequence (length of character sequence is evaluated)
  • Collection (collection size is evaluated)
  • Map (map size is evaluated)
  • Array (array length is evaluated)

long 타입은 해당되지 않아서 @NotEmpty를 붙이는 것은 의미 없음

 

 

 

그럼 어떻게 유효성 검사를 하면 좋을까?

 

@Min(1)
@Schema(description = "사용자 순번", example = "598")
private long custSeq;

 

위와 같이 @Min(1)을 사용해서 유효성 검사를 해볼 수 있다.

 

 

 


🎨 Arrays.asList()와 List.of()의 차이점은 무엇일까?

 

// 노출 및 노출 예정인 금융사 정보 조회
List<CompDto.ResultItem> compList = compMapper.selectCompListByStatus(Arrays.asList(
                                                                        MAIN_COMP_STATUS_ACTIVE, 
                                                                        MAIN_COMP_STATUS_TO_BE_EXPOSED));

 

자바에서 Array를 List으로 변환하기 위해서 위와 같이 Arrays.asList() 사용했는데,

"java 9 version 이상에서는 이런 용도의 List를 만들 때 Arrays.asList보다 List.of 를 더 추천합니다."

라는 코드리뷰를 받았다.

 

 

Java 9 버전 부터는  List.of(array)라는 새로운 팩토리 메소드가 도입되었는데

`List.of(array)`와 `Arrays.asList()`의 차이점은 무엇일까?

 

그리고 왜 List.of(array) 를 더 추천하셨을까?

 

 

결론 먼저 정리하자면!

  • Arrays.asList()는 크고 동적인 데이터에 사용하고, List.of()는 작고 변경되지 않는 데이터에 사용한다.
  • Arrays.asList()는 List.of()보다 힙에 더 많은 개체를 생성하기 때문에 더 많은 오버헤드 공간을 차지한다.
    • 따라서, 단지 값 요소가 필요한 경우라면 List.of()가 적합하다.
  • Arrays.asList()는 변경이 가능하며 thread safety 하지 않고, List.of()는 불변하고 thread safety 하다.
  • Arrays.asList()는 null 요소를 허용하고 List.of()는 null 요소를 허용하지 않는다.

 

 


🎨 log.info(“{ }”, log)   VS    log.info(log.toString())

 

 

[ 기존코드 ]

log.info(reqJson.toString());        

 

 

기존 코드에서 수정하면 좋은 부분은 어디일까?

바로 toString()을 사용한 부분이다.

 

 

[ 수정 코드 ]

log.info("{}", reqJson);

 

 

 

 

 

Only after evaluating whether to log or not, and only if the decision is positive,

will the logger implementation format the message and replace the '{}' pair with the string value of entry.

In other words, this form does not incur the cost of parameter construction

when the log statement is disabled.

 

→ toString()을 호출하지 않고 객체만 전달하면 toString() 오버헤드가 절약된다.