본문 바로가기
[ 오류 해결 ]

[JAVA] if 조건문에서 ==가 안될 때, 문자열 비교 시 ==와 equals()의 차이점

by 히앤님 2022. 10. 5.
반응형
SMALL

블로그 만들기 프로젝트 중 회원가입 부분에서 비밀번호 유효성 체크를 하는데 if문이 안먹더라.

String userPwd = req.getParameter("userPwd"); //ajax로 전달한 data 값 userPwd
PrintWriter out = resp.getWriter();
String result = "";//결과값

if (userPwd == "12345678!")) { //안됨
	System.out.println("사용불가");
	result = "1";
}else if (userPwd.equals("1004!!!!")) { //됨
	System.out.println("위험");
	//1004 등의 특정 의미있는 비밀번호
	result = "2";
}
        
out.write(result); //ajax 결과값인 result

한참을 고전하다가 이유를 찾았는데, ==와 equals()의 차이 때문.

1. 사용법의 차이

생긴거부터가 다르다.

==는 비교를 위한 연산자(operator)이다. 메모리 주소를 비교한다.

equals()메소드(method)이다. 두 인스턴스의 주소값을 비교하여 같은 인스턴스인지를 확인하고 같으면 true, 다르면 false의 boolean값을 리턴한다.

2. 리터럴과 객체의 차이

리터럴은 변하지 않는 데이터 그 자체(=상수)이다. 원시타입과 String이 있으며, Heap 메모리 영역 안에 있는 Constant Pool 이라는 메모리 영역에 값을 할당한다.

int a = 10;
int b = 10;

똑같은 값을 또 호출하면 전에 할당한 메모리 주소값을 똑같이 보내준다.

new 연산자는 객체를 Heap이라는 메모리 영역에 메모리 공간을 할당해주고 메모리주소를 반환한 후 생성자를 실행시켜준다. 리터럴과는 달리 new 연산자로 생성된 객체는 똑같은 값을 가진 객체가 있어도 서로 다른 메모리를 할당하기 때문에(=주소값이 다르기 때문에) 서로 다른 객체로 분류된다.

str과 str2는 동일한 내용이여도 주소값이 다르다.

 

객체가 아닌 일반적인 String 리터럴은 원시타입과 마찬가지로 같은 값을 호출할 시에 새로운 메모리를 할당하지 않고 String Constant Pool영역에 이미 할당되어 있는 값을 가르키게 된다.

3. 비교해보기

리터럴 str1,str2와 객체 str3,str4

str1과 str3는 그 내용은 같지만 인스턴스의 주소가 다르다. 하지만 equals메서드를 이용해 비교하면 동일하다는 결과가 나온다.

public class test {

    public static void main(String[] args) {

        String str1 = "apple"; //리터럴을 이용한 방식
        String str3 = new String("apple"); //new 연산자를 이용한 방식

        System.out.println(System.identityHashCode(str1)); //결과값 : 366712642
        System.out.println(System.identityHashCode(str3)); //결과값 : 1829164700
}
String형에서의 equals()는 두 대상의 내용이 같으면 같다고 판단한다.

==는 메모리 주소를 비교하기 때문에 두 대상의 내용이 같아도 메모리 주소가 다르면 false를 리턴한다.

 

4. Call by value vs Call by reference

함수를 호출할 때 메모리 공간 안에서는 함수를 위한 임시공간이 생성된다. (ex.stack frame)

이 때 함수 호출 시 인자로 전달되는 변수가 어떻게 오는지에 따라 호출방식이 달라지게 된다.

call-by-value (값에 의한 호출) - 복사본 전달

  • call-by-value 값에 의한 호출방식은 함수 호출시 전달되는 변수의 값을 복사하여 함수의 인자로 전달한다.
  • 복사된 인자는 함수 안에서 지역적으로 사용되는 local value의 특성을 가진다.
  • 따라서 함수 안에서 인자의 값이 변경되어도, 외부의 변수의 값은 변경되지 않는다. (왜? 복사본을 변경했을 뿐 메모리에 있는 원래 변수값은 변경되지 않음)

 

call-by-reference (참조에 의한 호출) - 본래값 주소 전달

  • call-by-reference 참조에 의한 호출방식은 함수 호출시 인자로 전달되는 변수의 레퍼런스를 전달한다. (해당 변수를 가르킨다.)
  • 따라서 함수 안에서 인자의 값이 변경되면, 아규먼트로 전달된 객체의 값도 함께 변경된다.
반응형
LIST

댓글