728x90

 

 

🚨 이슈 발생

로그인 API를 구축 중에 정지된 유저를 걸러주는 의미적 Validation을 Provider에서 처리하는 중에 분명 Validation처리를 해주었지만 정상 작동하지 않는 이슈를 겪었다.

 

다음 코드가 Validation이 정상 작동하지 않은 코드이다.

// 정지된 유저 validation 처리
if(checkStatus(postLoginReq.getId()) == "Ban"){
    throw new BaseException(POST_USERS_DISABLED_USER);
}

 

아래 코드는 해당 BaseException(POST_USERS_DISABLED_USER)이다.

POST_USERS_DISABLED_USER(false,2011,"정지된 유저입니다."),

 

 

 

 

 

 

👌 이슈 해결

뭐가 문제인지 몰라 헤매다가 혹시나 하는 마음에 다음과 같이 코드를 변경하였더니 정상적으로 Validation이 작동하였다.

// 정지된 유저 validation 처리
if(checkStatus(postLoginReq.getId()).equals("Ban")){
    throw new BaseException(POST_USERS_DISABLED_USER);
}

 


이 기회에 JAVA에서의 == 과 equals의 차이를 확실히 짚고 넘어가려고 한다.

 

 

 

 

📌  == 과 equals의 차이점

 

1. 형태의 차이

 

우선 간단한 차이점은 형태의 차이다.

  • equals는 메소드이다. 객체끼리 내용의 비교를 할 수 있도록 한다.
  • ==은 비교를 위한 비교 연산자이다.

 

 

2) 주소 값 비교(==)와 값 비교(equals)

 

== 연산자와 String클래스의 equals() 메서드의 가장 큰 차이점은

== 연산자는 비교하고자 하는 두 개의 대상의 주소값을 비교하는데 반해 String클래스의 equals 메소드는 비교하고자 하는 두개의 대상의 값 자체를 비교한다는 것이다. 일반적인 타입들 int형, char형 등은 Call by Value 형태로 기본적으로 대상에 주소 값을 가지지 않는 형태로 사용된다.

하지만 String은 일반적인 타입이 아니라 클래스이다. 클래스는 기본적으로 Call by Reference형태로 생성 시 주소 값이 부여된다. 그렇기에 String타입을 선언했을 때는 같은 값을 부여하더라도 서로 간의 주소 값이 다를 수가 있다.

 

이를 위의 경우에 대입시키면 우선 Provider의 checkStatus 메서드와 Dao의 checkStatus 메서드를 확인해야 한다.

 

 

 

Provider의 checkStatus 메서드

public String checkStatus(String status) throws BaseException{
    try{
        return userDao.checkStatus(status);
}  catch (Exception exception){
        throw new BaseException(DATABASE_ERROR);
  }
}

 

 

 

Dao의 checkStatus 메서드

public String checkStatus(String Id){
    String checkStatusQuery = "select status from User where ID = ?";
    String checkStatusParams = Id;
    return this.jdbcTemplate.queryForObject(checkStatusQuery,
        String.class,
        checkStatusParams);
}

 

 

Provider의 checkStatus 메서드는 Dao에서 쿼리문을 통해 나온 status를 String 타입으로 가져온다.

이를 데이터베이스 에러(DATABASE_ERROR)가 없다면 그대로 return 해준다.

즉 Validation으로 "Active" 혹은 "Ban"이라는 상태가 String타입으로 반환되어 오게 된다. 

 

 

따라서 위에서 말한 "그렇기에 String타입을 선언했을 때는 같은 값을 부여하더라도 서로 간의 주소 값이 다를 수가 있다."가 그대로 여기에 적용되는 것이다. 주소값이 다르기 때문에 == 으로는 실질적으로 비교가 되지 않고 equals를 통해 비교를 해주어야 정상 작동하게 된다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Reference:

https://ojava.tistory.com/15

https://coding-factory.tistory.com/536

 

복사했습니다!