Chapter 05

Java 조건문 if와 switch

플레이어의 체력과 행동 명령에 따라 다른 메시지를 출력하며 if, else if, else와 switch expression을 배웁니다.

난이도
입문
예상 학습
55분
Java 기준
Java 25 LTS
최종 검토

전체 22개 Chapter 확장 구조 중 Chapter 05입니다.

기능 구분

정식 Java 25에서도 쓸 수 있는 이전 버전 기능

Java SE 정식 기능

if와 switch expression은 Java 25에서도 사용할 수 있는 정식 문법입니다.

이 Chapter의 예제는 Preview 또는 Incubator API 실행 옵션 없이 Java 25 LTS 정식 기능 기준으로 읽을 수 있습니다.

Learning goals

오늘 배울 내용

  • 조건문이 필요한 상황 찾기
  • if, else if, else로 범위 나누기
  • 여러 조건을 안전한 순서로 배치하기
  • switch expression으로 정해진 선택 처리하기
  1. 현재 체력 읽기
  2. 위험 범위인지 비교
  3. 조건에 맞는 한 경로 선택
  4. 상태 메시지 출력
코드가 판단하고 실행되는 순서

조건문은 실행 경로를 나눕니다

프로그램이 늘 같은 순서로만 실행된다면 현재 상태에 맞는 반응을 할 수 없습니다. 체력이 20일 때와 1일 때 같은 메시지를 보여 주고, 권한이 있는 사용자와 없는 사용자를 같은 화면으로 보내고, 입력값이 잘못되었는데도 계산을 계속할 것입니다. 조건문은 boolean 결과를 보고 여러 실행 경로 중 하나를 고르게 해 줍니다.

조건문을 잘 쓰는 핵심은 “조건을 어떻게 쓰느냐”보다 “조건을 어떤 순서로 검사하느냐”에 있습니다. 조건이 겹칠 수 있다면 더 좁고 중요한 조건을 먼저 둡니다. 경계값을 포함할지 제외할지 명확히 정합니다. 모든 경우가 처리되는지 elsedefault로 확인합니다.

if와 else의 기본 형태

가장 단순한 조건문은 참일 때만 실행합니다.

if (health <= 0) {
    System.out.println("행동할 수 없습니다.");
}

거짓일 때의 경로도 필요하면 else를 붙입니다.

if (health > 0) {
    System.out.println("탐험을 계속합니다.");
} else {
    System.out.println("캠프로 돌아갑니다.");
}

조건식 자리에는 boolean 결과가 와야 합니다. health > 0, hasKey, level >= 5 && health > 0처럼 비교와 논리 연산 결과를 사용할 수 있습니다. Java에서는 숫자 0을 거짓으로 자동 취급하지 않습니다. if (health) 같은 코드는 사용할 수 없습니다.

체력 상태를 단계별로 나누기

다음 예제는 체력 값에 따라 하나의 메시지만 선택합니다.

public class Main {
    public static void main(String[] args) {
        int health = 6;

        if (health <= 0) {
            System.out.println("행동 불가: 구조 요청이 필요합니다.");
        } else if (health <= 5) {
            System.out.println("위험: 즉시 회복 아이템을 사용하세요.");
        } else if (health <= 12) {
            System.out.println("주의: 다음 전투 전에 휴식하세요.");
        } else {
            System.out.println("양호: 탐험을 계속할 수 있습니다.");
        }
    }
}

예상 출력은 다음과 같습니다.

주의: 다음 전투 전에 휴식하세요.

else if 연결에서는 위에서부터 검사하다가 처음 참인 블록 하나만 실행합니다. 체력 6은 0 이하도 아니고 5 이하도 아니지만 12 이하이므로 세 번째 블록이 실행됩니다. 이미 앞 조건들이 거짓이라는 사실을 알고 있기 때문에 세 번째 조건에 health >= 6을 반복하지 않아도 됩니다.

조건 순서가 만드는 차이

다음처럼 넓은 조건을 먼저 두면 의도와 다른 결과가 나옵니다.

int health = 3;

if (health <= 12) {
    System.out.println("주의");
} else if (health <= 5) {
    System.out.println("위험");
}

체력 3은 12 이하이므로 첫 번째 블록에서 멈춥니다. 더 위험한 메시지는 실행되지 않습니다. 그래서 범위를 나눌 때는 특별하고 좁은 조건을 먼저, 일반적인 조건을 나중에 둡니다.

경계값도 중요합니다. health < 5는 5를 포함하지 않고, health <= 5는 5를 포함합니다. 조건문을 작성한 뒤에는 0, 1, 5, 6, 12, 13처럼 경계 바로 앞뒤 값을 넣어 확인하세요. 테스트를 자동화하기 전에도 손으로 경계값을 점검하는 습관은 큰 도움이 됩니다.

독립 if와 else if 연결

조건을 여러 개 쓰는 방식에는 차이가 있습니다.

int score = 85;

if (score >= 60) {
    System.out.println("통과");
}
if (score >= 80) {
    System.out.println("우수");
}

위 코드는 두 조건이 모두 참이면 두 줄이 모두 출력됩니다. 반면 else if는 하나만 선택합니다.

int score = 85;

if (score >= 90) {
    System.out.println("최우수");
} else if (score >= 80) {
    System.out.println("우수");
} else if (score >= 60) {
    System.out.println("통과");
} else {
    System.out.println("재도전");
}

점수 등급처럼 하나의 분류만 필요하면 else if가 자연스럽습니다. 여러 개의 독립 알림이 동시에 필요하면 각각의 if를 사용합니다. 예를 들어 “체력이 낮다”, “가방이 가득 찼다”, “밤이 되었다”는 동시에 표시될 수 있는 경고라서 독립 if가 맞을 수 있습니다.

중첩 조건문은 줄이고 읽기 쉽게 만들기

조건문 안에 조건문을 넣을 수 있습니다.

if (hasTicket) {
    if (level >= 5) {
        System.out.println("입장");
    }
}

하지만 중첩이 깊어지면 읽기 어렵습니다. 두 조건이 모두 필요하다면 논리 연산자로 합칠 수 있습니다.

if (hasTicket && level >= 5) {
    System.out.println("입장");
}

복잡한 조건은 boolean 변수에 이름을 붙이는 방법도 좋습니다.

boolean hasEntryRight = hasTicket && level >= 5;
boolean canMove = health > 0 && !isFrozen;

if (hasEntryRight && canMove) {
    System.out.println("던전 입장");
}

조건식이 길어질수록 이름을 붙여 의도를 드러내세요. if (a && b && !c)보다 if (canStartQuest)가 훨씬 읽기 쉽습니다.

switch expression으로 선택지 처리하기

하나의 값이 정해진 후보 중 무엇인지에 따라 결과를 고를 때는 switch가 잘 맞습니다. Java 25에서는 switch expression을 사용해 선택 결과를 바로 값으로 만들 수 있습니다.

public class Main {
    public static void main(String[] args) {
        String command = "craft";

        String message = switch (command) {
            case "mine" -> "곡괭이를 들고 광맥을 찾습니다.";
            case "craft" -> "작업대에서 도구를 제작합니다.";
            case "rest" -> "캠프에서 체력을 회복합니다.";
            case "map" -> "현재 위치와 목표 지점을 확인합니다.";
            default -> "알 수 없는 명령입니다.";
        };

        System.out.println(message);
    }
}

예상 출력은 다음과 같습니다.

작업대에서 도구를 제작합니다.

화살표 ->를 사용하는 switch expression은 각 case가 어떤 값을 내는지 선명합니다. default는 예상하지 못한 입력을 처리합니다. 사용자 입력, 외부 데이터, 파일 값처럼 완전히 통제할 수 없는 값에는 항상 기본 경로를 마련하는 편이 안전합니다.

switch와 if의 선택 기준

switch는 하나의 값이 정확히 어떤 후보와 일치하는지 볼 때 좋습니다. 명령어, 메뉴 번호, 등급 코드, 상태 코드가 대표적입니다. 반대로 범위 비교나 복합 조건은 if가 자연스럽습니다.

if (temperature <= 0) {
    System.out.println("동결 위험");
} else if (temperature >= 35) {
    System.out.println("고온 주의");
}

온도처럼 연속된 범위를 나누는 작업은 switch보다 if가 읽기 쉽습니다. 도구를 고를 때는 “코드를 가장 빨리 이해할 다음 사람”을 기준으로 삼으세요.

흔한 실수와 방어 습관

조건 뒤에 세미콜론을 붙이면 의도와 다르게 동작합니다.

if (health <= 0);
{
    System.out.println("항상 실행될 수 있는 블록");
}

세미콜론 때문에 if의 본문이 빈 문장이 되고, 아래 중괄호 블록은 조건과 상관없이 실행됩니다. 한 줄 조건이라도 중괄호를 유지하고, 조건 뒤에는 바로 {를 두는 스타일을 지키면 이런 실수를 줄일 수 있습니다.

또 다른 실수는 대입과 비교를 헷갈리는 것입니다. Java에서는 if (health = 0)처럼 int 대입 결과를 조건으로 사용할 수 없어서 컴파일 오류가 나지만, boolean 변수에서는 if (ready = true) 같은 코드가 컴파일될 수 있습니다. boolean 비교는 if (ready)처럼 쓰고, 굳이 == true를 붙이지 않는 편이 실수를 줄입니다.

조건문을 표로 먼저 설계하기

조건이 조금만 복잡해져도 바로 코드부터 쓰면 빠뜨리는 경우가 생깁니다. 이럴 때는 작은 표로 먼저 정리해 보세요. 예를 들어 체력 상태를 나눈다면 “0 이하, 1부터 5, 6부터 12, 13 이상”처럼 범위를 적고 각 범위의 메시지를 적습니다. 표에서 겹치는 범위가 없고 빈 범위가 없으면 코드로 옮기기 쉽습니다.

권한 조건도 표로 정리할 수 있습니다. “열쇠 있음, 레벨 충분, 체력 양수” 세 조건이 모두 필요하다면 각 조건의 의미를 boolean 변수로 만들고 마지막에 연결합니다. 만약 열쇠가 없더라도 관리자라면 입장 가능하다는 예외가 있다면, 예외 조건을 별도 이름으로 분리합니다.

boolean hasNormalAccess = hasKey && level >= 5 && health > 0;
boolean hasOverrideAccess = isAdmin && health > 0;
boolean canEnter = hasNormalAccess || hasOverrideAccess;

이렇게 나누면 “관리자도 체력이 0이면 입장할 수 없는가?” 같은 질문이 자연스럽게 떠오릅니다. 좋은 조건문은 문법적으로 맞는 것을 넘어, 정책을 읽는 사람이 납득할 수 있어야 합니다.

실패 경로를 먼저 생각하기

입문 예제는 성공 경로를 중심으로 쓰기 쉽습니다. 하지만 실제 프로그램에서는 실패 경로가 더 중요할 때가 많습니다. 입력이 비어 있거나, 범위를 벗어나거나, 권한이 부족하거나, 알 수 없는 명령이 들어올 수 있습니다. 조건문을 작성할 때는 “정상 값이면 무엇을 할까?”와 함께 “정상 값이 아니면 어디서 멈출까?”를 생각해야 합니다.

예를 들어 배열 인덱스를 선택하기 전에 범위 검사를 하지 않으면 실행 중 예외가 발생할 수 있습니다. 파일 이름이나 명령 문자열을 처리할 때 default가 없으면 새 값이 들어왔을 때 침묵하거나 잘못된 기본값을 사용할 수 있습니다. 조건문의 else와 switch의 default는 귀찮은 나머지 처리가 아니라 프로그램의 안전망입니다.

조건문이 길어지면 우선순위를 다시 점검하세요. 긴급한 실패 조건을 먼저 검사하고, 정상 처리 코드는 아래쪽에 두면 읽기 쉬운 경우가 많습니다. 나중에 메서드를 배우면 이런 방식을 더 깔끔하게 만들 수 있습니다. 지금은 중괄호 안에서라도 실패 조건과 성공 조건을 분리해 읽는 연습을 하면 충분합니다.

직접 해보기

  1. 체력 값을 0, 5, 6, 12, 13으로 바꾸어 출력 경로를 기록합니다.
  2. 점수 등급 예제를 90 이상 A, 80 이상 B, 70 이상 C, 나머지 D로 바꿉니다.
  3. hasKey, hasMap, health를 조합해 퀘스트 시작 가능 조건을 boolean 변수로 만듭니다.
  4. switch에 "trade" 명령을 추가하고 거래 메시지를 반환합니다.
  5. 일부러 넓은 조건을 먼저 두고 결과가 어떻게 달라지는지 확인한 뒤 올바른 순서로 고칩니다.
경계값 힌트

조건문은 평균적인 값보다 경계값에서 더 자주 틀립니다. “포함인가, 제외인가”를 말로 설명할 수 있어야 코드도 안정적입니다.

조건문 복습 체크리스트

조건문을 배운 뒤에는 한 경로만 실행되는 상황과 여러 경고가 동시에 실행되는 상황을 구분해야 합니다. 등급 분류, 상태 메시지, 메뉴 선택처럼 하나만 골라야 한다면 else if 연결이나 switch가 잘 맞습니다. 반대로 “체력 낮음”, “가방 가득 참”, “밤이 됨”처럼 여러 알림이 동시에 필요하면 독립된 if 여러 개가 더 자연스럽습니다.

다음 질문에 답해 보세요. health <= 5health < 5는 어떤 값에서 결과가 달라지나요? else if에서 넓은 조건을 먼저 두면 어떤 문제가 생기나요? switch의 default는 왜 필요할까요? 조건식이 길어질 때 boolean 변수로 이름을 붙이면 어떤 장점이 있나요?

조건문은 요구사항의 언어와 가깝습니다. 그래서 코드를 쓰기 전에 말로 먼저 설명하는 습관이 좋습니다. “체력이 0 이하이면 행동 불가, 1부터 5까지는 위험, 6부터 12까지는 주의, 그 이상은 양호”처럼 설명할 수 있으면 코드도 안정적으로 나옵니다. 말로 설명할 수 없는 조건은 코드로 써도 흔들립니다.

테스트 값을 고르는 법

조건문을 확인할 때는 아무 값이나 넣지 말고 대표값과 경계값을 함께 고르세요. 대표값은 각 구간의 가운데쯤 있는 값입니다. 경계값은 조건이 바뀌는 바로 그 지점입니다. 체력 조건이라면 0, 1, 5, 6, 12, 13이 좋은 테스트 값입니다.

switch는 알려진 명령과 모르는 명령을 모두 확인해야 합니다. "mine", "craft"처럼 정상 명령을 넣고, "dance"처럼 처리하지 않은 명령도 넣어 default가 실행되는지 봅니다. 이런 작은 확인 습관이 나중에 자동 테스트를 작성할 때도 그대로 이어집니다.

이번 장의 정리

조건문은 현재 값에 따라 실행 경로를 선택합니다. if, else if, else는 범위와 복합 조건에 좋고, switch expression은 정해진 선택지 중 하나를 고를 때 좋습니다. 조건 순서와 경계값은 결과를 바꾸므로 반드시 확인해야 합니다. 다음 장에서는 선택한 동작을 여러 번 반복하는 forwhile을 배웁니다.

FAQ

자주 묻는 질문

if를 여러 개 쓰는 것과 else if는 무엇이 다른가요?

독립된 if는 각 조건을 모두 검사해 여러 블록이 실행될 수 있습니다. else if 연결은 처음 참인 한 경로만 실행합니다.

switch는 언제 쓰는 것이 좋나요?

명령 이름이나 메뉴 번호처럼 하나의 값이 몇 가지 정확한 후보 중 무엇인지 나눌 때 읽기 좋습니다. 연속 범위 비교는 if가 자연스럽습니다.

조건 순서가 결과에 영향을 주나요?

else if에서는 첫 번째로 참인 블록만 실행되므로 영향을 줍니다. 좁고 긴급한 범위를 먼저 검사하는 식으로 겹침을 의도적으로 정리하세요.

작성·편집 ToolPado

콘텐츠 유형 Java 학습 가이드

Java 기준 Java 25 LTS

마지막 검토