본문 바로가기

증감·비교·논리·대입

상태를 바꾸는 연산과 값을 만드는 연산을 분리하고 단축 평가를 이용해 안전한 회원가입 조건을 구성합니다.

count++는 값을 읽는 동시에 변수를 바꾸고, age >= 30은 변수를 바꾸지 않은 채 boolean 값을 만듭니다.

=는 대입이고 ==는 비교입니다.

기호가 짧다고 한 식에 섞으면 “어떤 값이 계산됐는가”와 “어떤 상태가 바뀌었는가”를 동시에 추적해야 합니다.

연산식의 결과와 저장 상태를 따로 추적한다

후위증가·대입·비교의 이전 상태/식 결과/이후 상태를 명시합니다. 세 독립 연산을 같은 단계에서 비교하면 값 생성과 상태 변경 차이가 선명합니다.

Java 연산식의 결과와 저장 상태 전이 비교

STATE MACHINE · EXPRESSION CONTRACT

연산식의 결과와 저장 상태를 따로 추적한다

같은 식 안에서도 계산된 값과 변수에 남은 상태는 다를 수 있다. 이전 상태, 식 결과, 이후 상태, 저장 상태의 변경 여부를 나눠 읽는다.

연산식의 결과와 저장 상태를 따로 추적한다 memberCount 후위 증가, boolean 대입, boolean 비교를 이전 상태와 식 결과와 이후 상태로 나누어 저장 상태의 변경 여부를 비교한다. 후위 증가 memberCount++ 이전 값을 결과로 사용 memberCount = 0 이전 상태 식 결과 = 0 memberCount = 1 이후 · 값 변경 대입 active = true 값 저장과 결과 생성 active = false 이전 상태 식 결과 = true active = true 이후 · 값 변경 비교 active == true 상태를 읽어 비교 active = false 이전 상태 비교 결과 = false active = false 이후 · 그대로 이전 상태 → 식의 결과 → 이후 상태 · 비교는 저장 상태를 바꾸지 않습니다
연산식의 결과와 저장 상태를 따로 추적한다 후위증가0→1/결과0,대입false→true/결과true,비교false유지/결과false. 본문과 바로 아래 설명이 원래 코드·수치를 보완합니다. memberCount++ 식 결과 0 이전 저장 상태 0 이후 저장 상태 1 변경 active = true 식 결과 true 이전 저장 상태 false 이후 저장 상태 true 변경 active == true 식 결과 false 이전 저장 상태 false 이후 저장 상태 false 유지
memberCount++
이전 상태 0 · 식 결과 0 · 이후 상태 1 · 상태 변경
active = true
이전 상태 false · 식 결과 true · 이후 상태 true · 상태 변경
active == true
이전 상태 false · 비교 결과 false · 이후 상태 false · 상태 유지

후위 증가의 식 결과가 이전 값이라는 사실과, 식 평가 뒤 저장 상태가 증가했다는 사실을 한 문장으로 섞지 않는다.

이 예의 조건

  • 세 연산은 각각 제시된 초기 상태에서 실행합니다.
관계도의 보충 설명
원 도표의 설명과 주석
구분내용
전체 읽기 정보연산식의 결과와 저장 상태를 따로 추적한다 Java 연산식의 결과와 저장 상태 전이 비교 STATE MACHINE · EXPRESSION CONTRACT 연산식의 결과와 저장 상태를 따로 추적한다 같은 식 안에서도 계산된 값과 변수에 남은 상태는 다를 수 있다. 이전 상태, 식 결과, 이후 상태, 저장 상태의 변경 여부를 나눠 읽는다. memberCount++ 이전 상태 0 · 식 결과 0 · 이후 상태 1 · 상태 변경 active = true 이전 상태 false · 식 결과 true · 이후 상태 true · 상태 변경 active == true 이전 상태 false · 비교 결과 false · 이후 상태 false · 상태 유지 후위 증가의 식 결과가 이전 값이라는 사실과, 식 평가 뒤 저장 상태가 증가했다는 사실을 한 문장으로 섞지 않는다.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
이전 상태

증가·대입·비교의 저장 상태를 먼저 둡니다.

  • 증가: memberCount=0
  • 대입·비교: active=false
  • 초기 상태를 식의 결과와 구별해 읽습니다.
식 결과

후위 증가는 이전 값, 대입은 새 값, 비교는 boolean을 만듭니다.

  • memberCount++: 결과 0
  • 대입 / 비교: true / false
  • 같은 형태의 식도 결과 생성 규칙이 다릅니다.
이후 상태

저장된 상태의 변경 여부를 확인합니다.

  • 증가: memberCount=1
  • 대입 / 비교: active=true / false 유지
  • 비교는 값을 읽기만 하므로 상태를 바꾸지 않습니다.

연산식의 결과와 저장 상태를 따로 추적한다

후위증가·대입·비교의 이전 상태/식 결과/이후 상태를 명시합니다. 세 독립 연산을 같은 단계에서 비교하면 값 생성과 상태 변경 차이가 선명합니다.

Java 연산식의 결과와 저장 상태 전이 비교

STATE MACHINE · EXPRESSION CONTRACT

연산식의 결과와 저장 상태를 따로 추적한다

같은 식 안에서도 계산된 값과 변수에 남은 상태는 다를 수 있다. 이전 상태, 식 결과, 이후 상태, 저장 상태의 변경 여부를 나눠 읽는다.

연산식의 결과와 저장 상태를 따로 추적한다 memberCount 후위 증가, boolean 대입, boolean 비교를 이전 상태와 식 결과와 이후 상태로 나누어 저장 상태의 변경 여부를 비교한다. 후위 증가 memberCount++ 이전 값을 결과로 사용 memberCount = 0 이전 상태 식 결과 = 0 memberCount = 1 이후 · 값 변경 대입 active = true 값 저장과 결과 생성 active = false 이전 상태 식 결과 = true active = true 이후 · 값 변경 비교 active == true 상태를 읽어 비교 active = false 이전 상태 비교 결과 = false active = false 이후 · 그대로 이전 상태 → 식의 결과 → 이후 상태 · 비교는 저장 상태를 바꾸지 않습니다
연산식의 결과와 저장 상태를 따로 추적한다 후위증가0→1/결과0,대입false→true/결과true,비교false유지/결과false. 본문과 바로 아래 설명이 원래 코드·수치를 보완합니다. memberCount++ 식 결과 0 이전 저장 상태 0 이후 저장 상태 1 변경 active = true 식 결과 true 이전 저장 상태 false 이후 저장 상태 true 변경 active == true 식 결과 false 이전 저장 상태 false 이후 저장 상태 false 유지
memberCount++
이전 상태 0 · 식 결과 0 · 이후 상태 1 · 상태 변경
active = true
이전 상태 false · 식 결과 true · 이후 상태 true · 상태 변경
active == true
이전 상태 false · 비교 결과 false · 이후 상태 false · 상태 유지

후위 증가의 식 결과가 이전 값이라는 사실과, 식 평가 뒤 저장 상태가 증가했다는 사실을 한 문장으로 섞지 않는다.

이 예의 조건

  • 세 연산은 각각 제시된 초기 상태에서 실행합니다.

관계도의 보충 설명

원 도표의 설명과 주석
구분내용
전체 읽기 정보연산식의 결과와 저장 상태를 따로 추적한다 Java 연산식의 결과와 저장 상태 전이 비교 STATE MACHINE · EXPRESSION CONTRACT 연산식의 결과와 저장 상태를 따로 추적한다 같은 식 안에서도 계산된 값과 변수에 남은 상태는 다를 수 있다. 이전 상태, 식 결과, 이후 상태, 저장 상태의 변경 여부를 나눠 읽는다. memberCount++ 이전 상태 0 · 식 결과 0 · 이후 상태 1 · 상태 변경 active = true 이전 상태 false · 식 결과 true · 이후 상태 true · 상태 변경 active == true 이전 상태 false · 비교 결과 false · 이후 상태 false · 상태 유지 후위 증가의 식 결과가 이전 값이라는 사실과, 식 평가 뒤 저장 상태가 증가했다는 사실을 한 문장으로 섞지 않는다.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
이전 상태

증가·대입·비교의 저장 상태를 먼저 둡니다.

  • 증가: memberCount=0
  • 대입·비교: active=false
  • 초기 상태를 식의 결과와 구별해 읽습니다.
식 결과

후위 증가는 이전 값, 대입은 새 값, 비교는 boolean을 만듭니다.

  • memberCount++: 결과 0
  • 대입 / 비교: true / false
  • 같은 형태의 식도 결과 생성 규칙이 다릅니다.
이후 상태

저장된 상태의 변경 여부를 확인합니다.

  • 증가: memberCount=1
  • 대입 / 비교: active=true / false 유지
  • 비교는 값을 읽기만 하므로 상태를 바꾸지 않습니다.

후위 증가 연산

lab/PostIncrementTrap.java
public final class PostIncrementTrap {
    public static void main(String[] args) {
        int memberCount = 0;
        int printedCount = memberCount++;

        System.out.println("printed=" + printedCount);
        System.out.println("stored=" + memberCount);
    }
}
printed=0
stored=1

후위 memberCount++는 식의 결과로 변경 전 값 0을 내놓고, 그 뒤 변수에 1을 저장합니다.

전위 ++memberCount는 먼저 1을 저장한 뒤 식의 결과도 1로 만듭니다.

단독 문장으로 사용할 때는 둘 다 1을 증가시킵니다.

memberCount++;
System.out.println(memberCount);

카운터를 증가시키면서 동시에 다른 변수에 대입하거나 메서드 인자로 넘기면 전위·후위 차이를 매번 해석해야 합니다.

회원가입에서는 상태 변경을 한 문장으로 분리해 증가 뒤의 값을 명확히 사용합니다.

--도 같은 규칙으로 1을 감소시킵니다.

회원 나이처럼 0 아래로 내려가면 안 되는 값은 연산자 자체가 막지 않으므로 별도 조건이 필요합니다.


대입과 비교

다음 코드는 active가 참인지 확인하는 대신 참을 대입합니다.

대입식의 결과도 대입한 값 true이므로 출력만 보면 비교가 성공한 것처럼 보입니다.

lab/AssignmentInsteadOfComparison.java
public final class AssignmentInsteadOfComparison {
    public static void main(String[] args) {
        boolean active = false;

        System.out.println("expression=" + (active = true));
        System.out.println("stored=" + active);
    }
}
expression=true
stored=true

같은지 비교하는 연산자는 ==입니다.

boolean은 if (active)처럼 값 자체를 조건으로 읽을 수 있어 active == true보다 간단합니다.

문자열의 내용 비교에는 ==가 아니라 equals를 사용한다는 차이는 참조를 배운 뒤 자세히 다룹니다.


boolean 결괏값

src/MemberConditions.java
public final class MemberConditions {
    public static void main(String[] args) {
        int age = 45;
        int minimumAge = 18;
        boolean emailPresent = true;

        boolean positive = age > 0;
        boolean withinLimit = age <= 120;
        boolean valid = emailPresent && positive && withinLimit;
        boolean active = age >= minimumAge;
        boolean needsAttention = !valid || !active;

        System.out.println("positive=" + positive);
        System.out.println("withinLimit=" + withinLimit);
        System.out.println("valid=" + valid);
        System.out.println("active=" + active);
        System.out.println("needsAttention=" + needsAttention);
    }
}
positive=true
withinLimit=true
valid=true
active=true
needsAttention=false

<, <=, >, >=, ==, !=는 두 값을 비교해 boolean을 만듭니다.

&&는 두 조건이 모두 참일 때, ||는 하나 이상 참일 때 참입니다.

!는 참과 거짓을 뒤집습니다.

valid처럼 복합 조건에 이름을 붙이면 출력과 분기에서 같은 규칙을 재사용할 수 있습니다.

age > 0 && age <= 120은 1부터 120까지의 닫힌 범위를 표현합니다.

경계값 1과 120을 포함하려면 두 번째 비교에 <=가 필요합니다.

0 < age <= 120처럼 수학식의 연쇄 비교는 Java 문법이 아닙니다.

비교 두 개를 논리 연산자로 연결합니다.


단축 평가

&&는 왼쪽이 거짓이면 전체 결과가 이미 거짓이므로 오른쪽을 평가하지 않습니다.

||는 왼쪽이 참이면 오른쪽을 평가하지 않습니다.

src/ShortCircuitGuard.java
public final class ShortCircuitGuard {
    public static void main(String[] args) {
        int totalAge = 120;
        int memberCount = 0;

        boolean averageAtLeastThirty = memberCount != 0
            && (totalAge / memberCount) >= 30;

        System.out.println("averageAtLeastThirty=" + averageAtLeastThirty);
    }
}
averageAtLeastThirty=false

왼쪽 memberCount != 0이 거짓이므로 0으로 나누는 오른쪽 식은 실행되지 않습니다.

순서를 뒤집으면 예외가 먼저 납니다.

boolean broken = (totalAge / memberCount) >= 30
    && memberCount != 0;

단축 평가를 단지 성능 최적화로 보지 않습니다.

오른쪽 식을 평가해도 안전한지 왼쪽 조건이 보장하는 가드로 사용합니다.

다만 오른쪽에서 변수 증가나 파일 쓰기 같은 부수 효과를 일으키면 조건에 따라 실행 여부가 달라지므로 논리식 안에는 상태 변경을 넣지 않는 편이 안전합니다.

단축 평가 가드가 위험한 나눗셈을 막는다

왼쪽 nonzero 가드가 오른쪽 나눗셈의 도달을 막습니다. 검사→평가 또는 건너뜀→결과/예외의 순서를 따라가기 좋습니다.

Java AND 단축 평가와 0 나눗셈 가드 흐름

FLOWCHART · SHORT-CIRCUIT GUARD

단축 평가 가드가 위험한 나눗셈을 막는다

AND의 왼쪽 조건은 전체 결과뿐 아니라 오른쪽 식을 실행할지도 결정한다. 0이 아닌지 먼저 확인해야 정수 나눗셈이 안전하게 열린다.

단축 평가 가드가 위험한 나눗셈을 막는다 memberCount가 0이면 AND 오른쪽 나눗셈을 평가하지 않고 false가 되며, 0이 아닐 때만 평균을 계산하는 안전 흐름과 나눗셈을 먼저 둔 예외 흐름을 비교한다. totalAge = 120 평균 조건 평가 시작 memberCount != 0 ? 왼쪽 조건 · 0 확인 오른쪽 식 실행 안 함 전체 false · 예외 없음 false totalAge / memberCount 오른쪽 평균식 평가 true 비교 결과 반환 평균 ≥ 30의 true / false 위험한 순서 · 나눗셈 먼저 totalAge / memberCount memberCount가 0인 경우 count = 0 ArithmeticException 가드 전에 예외 발생 왼쪽 조건이 false이면 오른쪽 식을 실행하지 않습니다 이 예제는 정수 나눗셈을 안전하게 실행하도록 순서를 정합니다.
단축 평가 가드가 위험한 나눗셈을 막는다 왼쪽count!=0 참일때만오른쪽평균비교;거짓이면미실행false;역순count0예외. 본문과 바로 아래 설명이 원래 코드·수치를 보완합니다. 안전한 순서 위험한 순서 · count=0 참 거짓 totalAge = 120 AND 평가 시작 memberCount != 0 ? 오른쪽 평균 평가 totalAge / memberCount >= 30 비교 결과 true 또는 false 오른쪽 미실행 전체 false · 예외 없음 가드 전에 정수 나눗셈 Arithmetic Exception 발생 가드까지 도달 못함
  1. 왼쪽 가드부터 평가

    memberCount != 0이 오른쪽 나눗셈을 실행해도 되는지 결정합니다.

  2. false이면 중단

    memberCount == 0이면 오른쪽은 실행되지 않음이고 전체 결과는 false입니다.

  3. true일 때만 평균 계산

    totalAge / memberCount >= 30을 평가해 최종 boolean을 만듭니다.

  4. 역순은 안전하지 않음

    나눗셈을 먼저 두고 count가 0이면 가드에 도달하기 전에 ArithmeticException이 발생합니다.

&&의 조건 순서는 결과뿐 아니라 오른쪽 식의 실행 여부를 결정한다.

이 예의 조건

  • totalAge=120인 정수 나눗셈의 안전한 && 식을 추적합니다. 원 main은 memberCount=0이고, count≠0은 같은 식의 조건부 비교입니다.
  • 나눗셈을 앞에 둔 broken 식은 독립 반례이며 위 관계도와 표의 원문 표에 보존합니다. 안전한 식의 뒤 동작으로 연결하지 않습니다.
관계도의 보충 설명
원 도표의 전체 관계·라벨·조건
구분내용
10totalAge
15평균 ≥ 30의 true
18totalAge
원 도표의 설명과 주석
구분내용
전체 읽기 정보단축 평가 가드가 위험한 나눗셈을 막는다 Java AND 단축 평가와 0 나눗셈 가드 흐름 FLOWCHART · SHORT-CIRCUIT GUARD 단축 평가 가드가 위험한 나눗셈을 막는다 AND의 왼쪽 조건은 전체 결과뿐 아니라 오른쪽 식을 실행할지도 결정한다. 0이 아닌지 먼저 확인해야 정수 나눗셈이 안전하게 열린다. 왼쪽 가드부터 평가 memberCount != 0 이 오른쪽 나눗셈을 실행해도 되는지 결정합니다. false이면 중단 memberCount == 0 이면 오른쪽은 실행되지 않으며 전체 결과는 false 입니다. true일 때만 평균 계산 totalAge / memberCount >= 30 을 평가해 최종 boolean을 만듭니다. 역순은 안전하지 않음 나눗셈을 먼저 두고 count가 0이면 가드에 도달하기 전에 ArithmeticException 이 발생합니다. && 의 조건 순서는 결과뿐 아니라 오른쪽 식의 실행 여부를 결정한다.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
안전한 식의 입력

totalAge=120과 memberCount를 안전한 식에 전달합니다.

  • 원 main: count=0
  • 조건부 비교: count≠0
  • 평가 순서: count 가드 → 평균식
  • 같은 안전한 식의 왼쪽 가드가 나눗셈 실행 여부를 먼저 결정합니다.
왼쪽 가드 판정

memberCount!=0을 먼저 평가하고 오른쪽 도달 여부를 정합니다.

  • count=0: 왼쪽 false · 오른쪽 미평가
  • count≠0: 왼쪽 true · 오른쪽 평가 가능
  • 변수 상태: 읽기만 수행 · 변경 없음
  • count=0의 실행은 나눗셈 전에 false로 끝나고, 0이 아닌 조건만 오른쪽으로 갑니다.
조건별 결과 반환

원 main은 예외 없이 false이고, 0이 아닌 조건은 평균 비교 결과를 반환합니다.

  • 원 main count=0: 전체 false · ArithmeticException 없음
  • 조건부 count≠0: 120/count 정수 나눗셈 후 평균≥30의 true/false
  • 출력 원 main: averageAtLeastThirty=false
  • 가드 통과 조건에서만 평균식을 평가하므로 0으로 나누지 않고 각 조건의 boolean 결과를 반환합니다.

단축 평가 가드가 위험한 나눗셈을 막는다

왼쪽 nonzero 가드가 오른쪽 나눗셈의 도달을 막습니다. 검사→평가 또는 건너뜀→결과/예외의 순서를 따라가기 좋습니다.

Java AND 단축 평가와 0 나눗셈 가드 흐름

FLOWCHART · SHORT-CIRCUIT GUARD

단축 평가 가드가 위험한 나눗셈을 막는다

AND의 왼쪽 조건은 전체 결과뿐 아니라 오른쪽 식을 실행할지도 결정한다. 0이 아닌지 먼저 확인해야 정수 나눗셈이 안전하게 열린다.

단축 평가 가드가 위험한 나눗셈을 막는다 memberCount가 0이면 AND 오른쪽 나눗셈을 평가하지 않고 false가 되며, 0이 아닐 때만 평균을 계산하는 안전 흐름과 나눗셈을 먼저 둔 예외 흐름을 비교한다. totalAge = 120 평균 조건 평가 시작 memberCount != 0 ? 왼쪽 조건 · 0 확인 오른쪽 식 실행 안 함 전체 false · 예외 없음 false totalAge / memberCount 오른쪽 평균식 평가 true 비교 결과 반환 평균 ≥ 30의 true / false 위험한 순서 · 나눗셈 먼저 totalAge / memberCount memberCount가 0인 경우 count = 0 ArithmeticException 가드 전에 예외 발생 왼쪽 조건이 false이면 오른쪽 식을 실행하지 않습니다 이 예제는 정수 나눗셈을 안전하게 실행하도록 순서를 정합니다.
단축 평가 가드가 위험한 나눗셈을 막는다 왼쪽count!=0 참일때만오른쪽평균비교;거짓이면미실행false;역순count0예외. 본문과 바로 아래 설명이 원래 코드·수치를 보완합니다. 안전한 순서 위험한 순서 · count=0 참 거짓 totalAge = 120 AND 평가 시작 memberCount != 0 ? 오른쪽 평균 평가 totalAge / memberCount >= 30 비교 결과 true 또는 false 오른쪽 미실행 전체 false · 예외 없음 가드 전에 정수 나눗셈 Arithmetic Exception 발생 가드까지 도달 못함
  1. 왼쪽 가드부터 평가

    memberCount != 0이 오른쪽 나눗셈을 실행해도 되는지 결정합니다.

  2. false이면 중단

    memberCount == 0이면 오른쪽은 실행되지 않음이고 전체 결과는 false입니다.

  3. true일 때만 평균 계산

    totalAge / memberCount >= 30을 평가해 최종 boolean을 만듭니다.

  4. 역순은 안전하지 않음

    나눗셈을 먼저 두고 count가 0이면 가드에 도달하기 전에 ArithmeticException이 발생합니다.

&&의 조건 순서는 결과뿐 아니라 오른쪽 식의 실행 여부를 결정한다.

이 예의 조건

  • totalAge=120인 정수 나눗셈의 안전한 && 식을 추적합니다. 원 main은 memberCount=0이고, count≠0은 같은 식의 조건부 비교입니다.
  • 나눗셈을 앞에 둔 broken 식은 독립 반례이며 위 관계도와 표의 원문 표에 보존합니다. 안전한 식의 뒤 동작으로 연결하지 않습니다.

관계도의 보충 설명

원 도표의 전체 관계·라벨·조건
구분내용
10totalAge
15평균 ≥ 30의 true
18totalAge
원 도표의 설명과 주석
구분내용
전체 읽기 정보단축 평가 가드가 위험한 나눗셈을 막는다 Java AND 단축 평가와 0 나눗셈 가드 흐름 FLOWCHART · SHORT-CIRCUIT GUARD 단축 평가 가드가 위험한 나눗셈을 막는다 AND의 왼쪽 조건은 전체 결과뿐 아니라 오른쪽 식을 실행할지도 결정한다. 0이 아닌지 먼저 확인해야 정수 나눗셈이 안전하게 열린다. 왼쪽 가드부터 평가 memberCount != 0 이 오른쪽 나눗셈을 실행해도 되는지 결정합니다. false이면 중단 memberCount == 0 이면 오른쪽은 실행되지 않으며 전체 결과는 false 입니다. true일 때만 평균 계산 totalAge / memberCount >= 30 을 평가해 최종 boolean을 만듭니다. 역순은 안전하지 않음 나눗셈을 먼저 두고 count가 0이면 가드에 도달하기 전에 ArithmeticException 이 발생합니다. && 의 조건 순서는 결과뿐 아니라 오른쪽 식의 실행 여부를 결정한다.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
안전한 식의 입력

totalAge=120과 memberCount를 안전한 식에 전달합니다.

  • 원 main: count=0
  • 조건부 비교: count≠0
  • 평가 순서: count 가드 → 평균식
  • 같은 안전한 식의 왼쪽 가드가 나눗셈 실행 여부를 먼저 결정합니다.
왼쪽 가드 판정

memberCount!=0을 먼저 평가하고 오른쪽 도달 여부를 정합니다.

  • count=0: 왼쪽 false · 오른쪽 미평가
  • count≠0: 왼쪽 true · 오른쪽 평가 가능
  • 변수 상태: 읽기만 수행 · 변경 없음
  • count=0의 실행은 나눗셈 전에 false로 끝나고, 0이 아닌 조건만 오른쪽으로 갑니다.
조건별 결과 반환

원 main은 예외 없이 false이고, 0이 아닌 조건은 평균 비교 결과를 반환합니다.

  • 원 main count=0: 전체 false · ArithmeticException 없음
  • 조건부 count≠0: 120/count 정수 나눗셈 후 평균≥30의 true/false
  • 출력 원 main: averageAtLeastThirty=false
  • 가드 통과 조건에서만 평균식을 평가하므로 0으로 나누지 않고 각 조건의 boolean 결과를 반환합니다.

복합 대입

src/CompoundAssignment.java
public final class CompoundAssignment {
    public static void main(String[] args) {
        int totalAge = 40;

        totalAge += 30;
        totalAge -= 10;
        totalAge *= 2;
        totalAge /= 4;

        System.out.println("total=" + totalAge);
    }
}
total=30

totalAge += 30은 현재 값을 읽어 30을 더한 뒤 같은 변수에 저장한다는 뜻입니다.

대체로 totalAge = totalAge + 30과 같은 의도지만, 복합 대입에는 암시적 타입 변환 규칙도 있어 작은 숫자 타입에서는 완전히 같은 식으로 치환되지 않을 수 있습니다.

지금은 int 안에서만 사용하고 형변환 절에서 차이를 다시 확인합니다.

연산 우선순위상 산술·비교·논리·대입 순서로 묶이지만, 다음처럼 의미를 변수로 나누는 것이 읽기 쉽습니다.

boolean withinRange = age >= 1 && age <= 120;
boolean acceptable = emailPresent && withinRange;
active = acceptable && age >= minimumAge;

입력 상태 계산

회원가입 입력에서 아직 분기를 하지 않고 판정값만 출력해 봅니다.

이번 실행은 이메일·나이·최소 가입 나이 세 인자를 전달하고, 뒤의 두 값은 int 범위 안의 정수 문자열이라고 가정합니다. 인자가 빠지거나 숫자로 변환되지 않을 때의 처리는 다음 장에서 다룹니다.

email.isBlank()는 빈 문자열이거나 공백 문자만 있으면 true입니다. 앞의 !가 결과를 뒤집으므로 !email.isBlank()는 공백뿐인 입력을 제외합니다. 이 검사는 이메일 주소 형식까지 확인하지는 않습니다. String API의 isBlank 정의에서 검사 범위를 확인할 수 있습니다.

src/MemberFlags.java
public final class MemberFlags {
    public static void main(String[] args) {
        String email = args[0];
        int age = Integer.parseInt(args[1]);
        int minimumAge = Integer.parseInt(args[2]);

        boolean emailPresent = !email.isBlank();
        boolean ageValid = age >= 1 && age <= 120;
        boolean minimumAgeValid = minimumAge >= 1 && minimumAge <= 120;
        boolean valid = emailPresent && ageValid && minimumAgeValid;
        boolean active = valid && age >= minimumAge;

        System.out.println("valid=" + valid);
        System.out.println("active=" + active);
    }
}

java -cp out MemberFlags [email protected] 45 60은 valid=true, active=false를 출력합니다.

java -cp out MemberFlags [email protected] 700 60은 valid=false이고 단축 평가 때문에 활성으로 판정되지 않습니다.

다음 절에서는 이 두 boolean에 따라 저장·오류 출력 경로를 실제로 나눕니다.


연습 문제

이메일이 비어 있지 않고, 나이가 18세 이상 120세 이하이며, 로그인 실패 횟수가 2 이하일 때만 eligible=true가 되는 SignupFlags를 작성하세요.

age=50, failedLoginCount=3을 사용해 각 부분 조건과 최종 조건을 모두 출력합니다.

해설 보기
src/SignupFlags.java
public final class SignupFlags {
    public static void main(String[] args) {
        String email = "[email protected]";
        int age = 50;
        int failedLoginCount = 3;

        boolean emailPresent = !email.isBlank();
        boolean ageAllowed = age >= 18 && age <= 120;
        boolean loginAttemptsAllowed = failedLoginCount <= 2;
        boolean eligible = emailPresent
            && ageAllowed
            && loginAttemptsAllowed;

        System.out.println("emailPresent=" + emailPresent);
        System.out.println("ageAllowed=" + ageAllowed);
        System.out.println("loginAttemptsAllowed=" + loginAttemptsAllowed);
        System.out.println("eligible=" + eligible);
    }
}
emailPresent=true
ageAllowed=true
loginAttemptsAllowed=false
eligible=false

최종 결과만 출력하면 어떤 조건이 실패했는지 알 수 없습니다.

연습 단계에서는 부분 조건에 이름을 붙여 함께 출력하고, 실제 CLI에서는 사용자에게 필요한 실패 이유를 분기해 안내합니다.