효습
Java에서 equals() 와 == 의 차이 본문
1. '==' 연산자
- '==' 연산자는 두 객체의 주소(참조)값이 동일한지 비교함
- Java의 기본 자료형(int , long , boolean...)에서는 값 자체를 비교하지만, 객체 타입(Long , String , Integer..)의 경우 주소(참조)값을 비교함
2. 'equals()`메서드
- 두 객체의 주소값이 아니라 내용이 똑같은지 비교함 , 두 객체가 실제로 같은 값을 가지고 있는지 비교
- 대부분의 Java 클래스(Long , String , Integer..)는 equals() 메서드를 오버라이드하여 객체의 값 비교
String을 예로 들면 쉽게 이해할 수 있다.
String str1 = "string";
String str2 = "string";
String str3 = new String("string");
System.out.println(str1 == str2); // true
System.out.println(str1 == str3); // false
System.out.println(str1.equals(str2)); // true
System.out.println(str1.equals(str3)); // true
사실 혼용해서 쓰다가 결제 내역을 검증하고 저장하는 서비스 코드를 짜다가 차이점을 발견함
결제 내역을 검증할 때 , 다음과 같은 과정을 거친다.
- 프론트에서 포트원을 통해 결제를 하면 결제 내역을 서버로 보냄(결제 고유 번호 .. 등등)
- 서버는 결제 고유 번호를 가지고 포트원에서 결제 내역을 조회해옴
- 조회해온 금액과 프론트에서 보낸 금액이 같은지 검증함
펀딩 서비스였기 때문에 참여 내역의 기여 금액과 비교하는 코드도 넣긴 하였으나 결제를 테스트로 연동한 거여서 그 부분은 주석처리 하였다.
Payservice.java에서 결제 내역을 검증하고 DB에 결제 내역을 저장하는 코드는 다음과 같다.
/* 결제 내역을 검증하고 DB에 결제 내역을 저장 */
public PayResponseDto createPayment(User user , String paymentNumber , PayRequestDto paymentRequestDto) {
// Long userId = user.getUserId();
//Long fundingId = paymentRequestDto.getFundingId();
IamportResponse<Payment> iamportResponse = iamportClient.paymentByImpUid(paymentNumber); // 결제 번호 가져오기
log.info("결제 요청 응답. 결제 번호 :{}" ,iamportResponse.getResponse().getMerchantUid());
Long resAmount = iamportResponse.getResponse().getAmount().longValue();
// 펀딩 참여 테이블의 기여금액과 일치하는지 확인 _ 참여 테이블의 기여 금액과 같은지 확인하는 과정 생략
// Participation participation = participationRepository.findByUserIdAndFundingId(userId , fundingId)
// .orElseThrow(() -> new CustomException(ErrorCode.PARTICIPATION_NOT_FOUND));
//if(participation.getContributionAmount().eqauls(resAmount) || participation.getContributionAmount().equals(paymentRequestDto.getAmount())){ // 결제 조회값이나 참여 테이블 기여금액과 다르면
if(!resAmount.equals(paymentRequestDto.getAmount())){ // 포트원에서 조회해온 금액이랑 프론트에서 받은 금액이 같은지 확인,
//금액이 다르다면 결제 취소
throw new CustomException(ErrorCode.INVALID_AMOUNT);
}
//기본키 값이 일치하는 게 있는지
if(paymentRepository.countByPayIdContainingIgnoreCase(paymentNumber) !=0){ // 결제 번호가 겹치는 값이 있다면
throw new CustomException(ErrorCode.DUPLICATED_IMP);
}
Funding funding = fundingRepository.findByFundingId(paymentRequestDto.getFundingId());
Pay pay = Pay.toEntity(paymentNumber ,user , funding , paymentRequestDto.getAmount());
paymentRepository.save(pay);
log.info("결제 성공 : 결제 번호 {}" , pay.getPayId());
PayResponseDto payRes = PayResponseDto.from(pay.getPayId() , pay.getUser().getUserId() ,
pay.getFunding().getFundingId() , pay.getAmount()
);
return payRes;
}
포트원에서 조회해온 금액과 프론트에서 보내온 결제 내역의 결제 금액을 비교하는 코드에서 처음에는 '==' 연산자를 썼었다.
포트원에서 조회해온 금액은 BigDecimal 자료형이었고 이를 Long형으로 바꾸고 비교했는데 이 금액과 프론트에서 보낸 금액은 객체 타입 이고 다른 객체니까 '==' 연산자로 비교를 하면 false를 반환하는 것이었다.
내가 원한 건 값(내용) 자체에 대한 비교였기 때문에 '==' 연산자를 equals 메서드로 바꾸니 잘 실행되었다.
'프로젝트' 카테고리의 다른 글
SSE(Server-Sent- Events)로 알림 기능 구현하기 (0) | 2025.01.10 |
---|---|
redis 배포하기 (0) | 2025.01.02 |
QueryDSL 사용하기 (1) | 2024.10.05 |
서버 배포 과정 이해하기 (1) | 2024.06.19 |