📕 기본 자료형 (Primitive Type)
📗 기본 자료형이 무엇인가?
기본 자료형은 프로그래밍 언어에서 제공하는 가장 기본적인 데이터 타입으로, 변수에 저장되는 데이터의 값을 직접 담는다.
📗 기본 자료형의 특징
- null 값을 허용하지 않는다.
- 정해진 메모리를 할당한다.
- 스택(stack) 영역에 저장된다.
📗 기본 자료형의 종류
- int
- 정수 값을 저장하는 기본 자료형.
- 예를 들면, 1, -42, 100 등의 정수.
- boolean:
- 참 또는 거짓을 나타내는 논리 자료형.
- true 또는 false.
- byte:
- 작은 정수 값을 저장하는 기본 자료형으로, -128부터 127까지의 값을 표현.
- 주로 메모리 절약이 필요한 경우에 사용한다.
- char
- 유니코드(Unicode) 문자 하나를 저장하는 기본 자료형으로, 홑따옴표('')로 감싸서 사용한다.
- 예를 들면 'A', 'b', '1' 등의 문자를 표현한다.
- short
- 작은 정수 값을 저장하는 기본 자료형으로, -32,768부터 32,767까지의 값을 표현.
- int보다 작은 범위의 정수를 표현할 때 사용한다.
- long
- 큰 정수 값을 저장하는 기본 자료형으로,
매우 큰 범위인 -9,223,372,036,854,775,808부터 9,223,372,036,854,775,807까지의 값을 표현. - int보다 큰 범위의 정수를 다룰 때 사용한다.
- 큰 정수 값을 저장하는 기본 자료형으로,
- float
- 실수 값을 저장하는 기본 자료형으로, 부동 소수점 형식을 사용하여 대략적인 소수값을 표현.
- 예를 들면 3.14, -0.123 등의 실수를 표현할 수 있다.
- double
- 더 큰 범위의 실수 값을 저장하는 기본 자료형으로, float보다 더 정밀한 소수 값을 표현.
- 높은 정밀도가 필요한 실수 계산에 사용된다.
📕 참조 자료형 (Reference Type)
- 참조 자료형은 기본 자료형을 객체로 다룰 수 있게 해주는 클래스.
- 자바에서는 int를 Integer로, boolean을 Boolean으로 변환하여 래퍼클래스로 다룰 수 있다.
- 래퍼클래스는 대문자로 시작하며 기본 자료형과 동일한 값을 갖지만, 메서드를 통해 더 많은 기능을 제공한다.
- 래퍼 클래스 안에 있는 값을 변경할 수 없다.
📗 Wrapper class
래퍼 클래스는 기본자료형을 참조자료형처럼 사용할 수 있게 감싸주는 클래스들이다.
모든 기본자료형에 대한 래퍼클래스가 있다.
Primitive Type | Wrapper class |
byte | Byte |
short | Short |
int | Integer |
long | Long |
double | Double |
char | Character |
float | Float |
boolean | Boolean |
📕 래퍼 클래스는 언제 쓸까?
여러가지 상황이 있지만 특정 한 예시로
Spring boot 개발환경에서 RequestBody로 받은 Dto 형식의 데이터를 @Valid를 이용하여 예외 처리를 하는 경우를 생각해보자.
다음과 같은 Dto 데이터를
[CharacterUpdateDto]
public class CharacterUpdateDto {
@NotBlank(message = "캐릭터 이름이 없습니다")
@ApiModelProperty(notes = "캐릭터 이름")
private String characterName;
@NotNull(message = "chaosSelected: null일 수 없습니다.")
@ApiModelProperty(notes = "카오스던전 숙제 할 캐릭인지 선택, true / false")
private boolean chaosSelected;
@Min(value = 0, message = "chaosCheck: 0~2 사이여야 합니다.")
@Max(value = 2, message = "chaosCheck: 0~2 사이여야 합니다.")
@NotNull(message = "chaosCheck: null일 수 없습니다.")
@ApiModelProperty(notes = "카오스던전 돌았는지 체크, 최소 0, 최대 2")
private int chaosCheck;
@NotNull(message = "guardianSelected: null일 수 없습니다.")
@ApiModelProperty(notes = "가디언토벌 숙제 할 캐릭인지 선택, true / false")
private boolean guardianSelected;
@Min(value = 0, message = "guardianCheck : 0~2 사이여야 합니다.")
@Max(value = 2, message = "guardianCheck : 0~2 사이여야 합니다.")
@NotNull(message = "guardianCheck: null일 수 없습니다.")
@ApiModelProperty(notes = "가디언토벌 돌았는지 체크, 최소 0, 최대 2, 1씩 증감")
private int guardianCheck;
}
아래의 Api의 Body로 받는데
@ApiOperation(value = "회원과 등록된 캐릭터 리스트 업데이트", response = CharacterUpdateDto.class)
@PatchMapping("/{username}")
public ResponseEntity updateCharacters(@RequestBody @Valid CharacterUpdateDto characterUpdateDto,
@PathVariable String username) {
return new ResponseEntity<>(memberService.updateCharacter(username, characterUpdateDtoV2), HttpStatus.OK);
}
chaosSelected와 같은 boolean 타입, chaosCheck와 같은 int타입에 값을 넣지 않을 경우
{
"characterName": "캐릭터이름",
"guardianCheck": 0,
"guardianSelected": true
}
boolean과 int 타입의 @NotNull 어노테이션이 정상적으로 작동하는가?
-> 위에 기본 자료형의 특징에서 보는 거와 같이 기본 자료형은 null값을 애초에 허용하지 않기 때문에
int의 기본값이 0과 boolean의 기본값이 false가 자동적으로 들어간다.
-> 따라서 @NotNull 은 정상적으로 작동이 되지 않는다.
📗 참조 자료형 사용
단순히 기본값으로 생성하는 것이 아닌 null을 받았을 때 Exception을 처리를 하려면
기본 자료형이 아닌 참조 자료형으로 받으면 된다.
[CharacterUpdateDtoV2]
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CharacterUpdateDtoV2 {
@NotBlank(message = "캐릭터 이름이 없습니다")
@ApiModelProperty(notes = "캐릭터 이름")
private String characterName;
@NotNull(message = "chaosSelected: null일 수 없습니다.")
@ApiModelProperty(notes = "카오스던전 숙제 할 캐릭인지 선택, true / false")
private Boolean chaosSelected;
@Min(value = 0, message = "chaosCheck: 0~2 사이여야 합니다.")
@Max(value = 2, message = "chaosCheck: 0~2 사이여야 합니다.")
@NotNull(message = "chaosCheck: null일 수 없습니다.")
@ApiModelProperty(notes = "카오스던전 돌았는지 체크, 최소 0, 최대 2")
private Integer chaosCheck;
@NotNull(message = "guardianSelected: null일 수 없습니다.")
@ApiModelProperty(notes = "가디언토벌 숙제 할 캐릭인지 선택, true / false")
private Boolean guardianSelected;
@Min(value = 0, message = "guardianCheck : 0~2 사이여야 합니다.")
@Max(value = 2, message = "guardianCheck : 0~2 사이여야 합니다.")
@NotNull(message = "guardianCheck: null일 수 없습니다.")
@ApiModelProperty(notes = "가디언토벌 돌았는지 체크, 최소 0, 최대 2, 1씩 증감")
private Integer guardianCheck;
}
이렇게 하고 에러를 발생시키면
MethodArgumentNotValidException 으로 잡힌다.
{
"chaosCheck": 0,
"chaosSelected": true,
"characterName": "마볼링"
}
{
"errorCode": 400,
"exceptionName": "MethodArgumentNotValidException",
"errorMessage": "guardianCheck: null일 수 없습니다., guardianSelected: null일 수 없습니다."
}