본문 바로가기

코딩공부/JAVA

JAVA 제어문 [2] - 조건문, 문자의 비교 ( ==과 equals의 차이점 )

조건문(Conditional Statement)

프로그래밍 언어에서 가장 중요한 기본적인 동작 방법은 "시간의 순서에 따라서 동작한다"이다.

조건문을 이용해서 프로그램이 실행되는 순서를 제어할 수 있다.

 

if() 안의 조건이 참이면 if(){} 안의 코드를 실행, 거짓이면 else {} 안의 코드를 실행한다.

public class IfApp {
    public static void main(String[] args) {
 
        System.out.println("a");
        if(false) {
            System.out.println(1);
        } else if(true) {
            System.out.println(2);
        } else{
        	System.out.println(3);
        }
        System.out.println("b");
    }
}

 

※ 노란 줄 쳐진 이유?

Dead code : 영원히 실행되지 않는 죽은 코드이기 때문에

 

조건문 응용

(실습 1)

프로그램 실행 시 입력값으로 "javakong"을 주면, 인증에 성공하고, "Master!"를 출력. 그 외 입력값은 인증에 실패하는 코드 작성

public class AuthApp {
	public static void main(String[] args) {
		String id = "javakong";
        String inputId = args[0];
         
        System.out.println("Hi.");
         
        //if(inputId == id) {  // "javakong" 입력값 == 으로 비교시 false
        if(inputId.equals(id)) { //equals() 메소드 사용시 true
            System.out.println("Master!");
        } else {
            System.out.println("Who are you?");
        }
		
	}
}

 

(실습 2)

프로그램 실행 시 입력값으로 "javakong"과 "1111"을 주면, 인증에 성공하고, "Master!"를 출력. 그 외 입력값은 인증에 실패하는 코드 작성

 

&& 연산자 : "논리 연산자" (and 연산자) 두 개의 조건을 모두 만족할 시 true

public class AuthApp {
	public static void main(String[] args) {
		String id = "javakong";
        String inputId = args[0];
         
        String pass = "1111";
        String inputPass = args[1];
         
        System.out.println("Hi.");
         
        if(inputId.equals(id) && inputPass.equals(pass)) {
            System.out.println("Master!");
        } else {
            System.out.println("Who are you?");
        }       

	}
}

 

문자의 비교 ( ==과 equals의 차이점 )

자바에서 문자나 객체를 비교할 때는 ==가 아닌 equals를 사용해야 한다.

 

자바에는 여러 가지 데이터 타입들이 존재한다. 이 데이터 타입들을 primitive(원시)인지, non primitive 인지로 그룹핑할 수 있다.

  • primitive(원시) : 더 이상 쪼갤 수 없는 데이터
  • non primitive : 문자열, 배열, 클래스 등... 원시 데이터 타입이 아닌 것들로 구분

 

자바가 원시 데이터 타입과 그렇지 않은 것들을 차별한다.

 

 

1. 원시 데이터 타입의 비교

 

(아래 그림은 실제로 자바가 구현된 방식을 설명하는 것이 아니라 머릿속에 이런 이미지가 있으면 많은 현상들이 해석될 수 있다고 할 수 있는 목적으로 만든 이미지이다.)

 

int p1 = 1

p1이라는 변수가 생기고, 그 변수는 데이터 타입이 integer(숫자)이고, 숫자 1은 primitive(원시) 데이터 타입에 속하게 된다.

이 1이라는 데이터를 만들면 컴퓨터 메모리상 어딘가에 저 값이 저장이 된다. "p1이라는 변수가 1 이라는 값이 위치하는 곳을 가리키고 있게 된다." 

 

int p2 = 1

p2라는 변수에 숫자 1을 저장하면, "p2는 이미 1이라는 값이 저장되어있는 위치를 같이 가리키게 된다" (메모리의 새로운 영역에 1 이라는 값을 만들고 가리키지 않음)

 

이 상황에서 p1 == p2 p1과 p2가 같은가?라는 동등 비교 연산을 하게 되면, 동등 비교 연산자"p1과 p2가 같은 곳을 가리키고 있나?"라는 것을 확인하는 연산자이다. 같은 곳을 가리키고 있다는 얘기는 값이 같다는 뜻이므로 결과는 true 가 된다.

 

 

2. non primitive 타입의 비교

 

 

우리가 문자열을 만들 때, String o1 = "java"; 이렇게 만들었지만, String o2 = new String("java"); 이렇게도 만들 수 있다.

둘 다 문자열이지만 자바에서는 이 두 가지를 좀 다르게 취급한다.

 

String o1 = new String("java"); 

o1 이라는 변수에 new 를 이용해서 "java"라는 문자열을 담는 변수를 만들었다면 다음과 같이 메모리 상에 "java" 값이 저장된 위치를 가리키고 있게 된다.

 

String o2 = new String("java"); 

또 o2 는 똑같은 "java" 라는 내용을 가지고 있는 객체를 만들었다면, 이미 문자열 "java"가 존재함에도 불구하고, 새로운 메모리 영역에 "java" 문자열 값을 저장하고 그 위치를 가리키게 된다.

 

이때, o1 == o2 o1과 o2 를 동등비교 연산자로 비교하게 되면, 동등비교 연산자는 왼쪽의 값과 오른쪽의 값이 같은 곳에 위치하는지를 따지기 때문에 false 값을 리턴하는 것이다.

 

원시 데이터 타입이 아닌 객체들은 equals() 라는 메소드를 다들 가지고 있다.

o1.equals(o2) 이렇게 메소드를 호출하게 되면 equals 메소드가 o1과 o2 가 같은지를 내부적으로 계산해서 내용이 같다면 true를 리턴한다. 

 

 

동등 비교 연산자(==) : 변수가 같은 곳을 가리키는지 따져봄

equalse() 메소드 : 내용이 같은지를 따져봄

 

원시 데이터 타입의 비교 => 동등 비교 연산

non 원시 데이터 타입의 비교 => equalse() 메소드 사용

특별히 문자열 타입의 비교 => 동등 비교 연산, equalse() 둘 다 사용 가능

 

 

3. 문자열의 비교

 

문자열(non primitive)은 아주 많이 사용되고 중요한 데이터 타입이기 때문에, 편의성, 성능 때문에 특별히 취급된다.

 

 

String o3 = "java2"

new 키워드를 사용하지 않고 사용한다, "java2" 값이 메모리의 어딘가에 저장되고 o3는 그 위치를 가리키게 된다.

 

String o4 = "java2"

o4 또한 new 를 쓰지 않고 문자열을 정의하게 되면, 문자열은 마치 원시 데이터 타입처럼 동작한다. 새로운 곳에다가 똑같은 값을 만들지 않고, 이미 "java2" 값이 저장되어있는 위치를 같이 가리키게 된다.

 

그렇기 때문에 문자열의 경우 o3 == 04 동등 비교 연산을 하면 true 값을 리턴 받게 된다.

 

※ 이전에 입력값 인자를 받을 때, 동등 비교 연산을 했더니 내용이 같음에도 불구하고 false 가 반환됐다는 것은 그 입력값이 내부적으로 다른 곳에 저장되었단 의미이다. 그렇기 때문에 원시 데이터 타입이 아닌 친구들은 equalse() 메소드를 사용하면 된다.

 

 

두 객체가 같은지 확인하고 싶다면 검색해서 따져봐야한다. 객체라는 것은 복합적인 데이터 타입이기 때문에, 객체들 마다 비교 정책이 다를 수 있다. 그래서 어떻게 내용이 같은지 확인하는지를 파악해서 각 객체들이 갖고 있는 equals() 가 어떻게 동작하는지도 따져봐야 한다.