변수에 값을 저장할 수 있게 되면 다음 단계는 그 값을 계산하고, 비교하고, 조건에 따라 다른 코드를 실행하고, 필요한 만큼 반복하는 것이다.
이 글에서는 Java의 연산자와 String, 조건문, 반복문을 하나의 흐름으로 정리한다.
int a = 10;
int b = 3;
System.out.println(a + b); // 13
System.out.println(a - b); // 7
System.out.println(a * b); // 30
System.out.println(a / b); // 3
System.out.println(a % b); // 1
정수끼리 나누면 결과도 정수이므로 소수 부분이 버려진다.
System.out.println(5 / 2); // 2
System.out.println(5 / 2.0); // 2.5
%는 나머지를 구한다. 짝수 여부나 주기적인 동작을 만들 때 유용하다.
int index = 7;
boolean isEven = index % 2 == 0;
int count = 0;
count++;
count--;
전위와 후위는 표현식 안에서 사용하는 시점이 다르다.
int value = 10;
System.out.println(++value); // 11
value = 10;
System.out.println(value++); // 10
System.out.println(value); // 11
단순히 값을 1 증가시키는 목적이라면 count++ 정도로만 사용하면 헷갈릴 일이 줄어든다.
int stock = 10;
stock = stock + 3;
같은 코드는 복합 대입 연산자로 줄일 수 있다.
stock += 3;
stock -= 2;
stock *= 2;
stock /= 2;
stock %= 3;
비교 연산의 결과는 boolean이다.
int age = 25;
System.out.println(age > 19); // true
System.out.println(age <= 30); // true
System.out.println(age == 25); // true
System.out.println(age != 20); // true
여러 조건을 합칠 때는 논리 연산자를 사용한다.
boolean loggedIn = true;
boolean hasPermission = false;
boolean canAccess = loggedIn && hasPermission;
boolean canPreview = loggedIn || hasPermission;
boolean guest = !loggedIn;
&&: 양쪽이 모두 참일 때 true||: 하나라도 참이면 true!: 참과 거짓을 뒤집음&&와 ||는 단락 평가(short-circuit evaluation) 를 한다. 결과가 이미 결정되면 오른쪽 식을 실행하지 않는다.
String token = null;
if (token != null && token.length() > 10) {
System.out.println("유효한 형식");
}
첫 번째 조건이 false면 token.length()는 실행되지 않아 NullPointerException을 피할 수 있다.
int score = 82;
String result = score >= 60 ? "PASS" : "FAIL";
간단한 값 선택에는 읽기 좋지만, 조건이 여러 단계로 중첩되면 if문이 더 명확하다.
String은 자주 쓰는 메소드부터 익히자String path = " /api/orders ";
System.out.println(path.length());
System.out.println(path.trim());
System.out.println(path.contains("orders"));
System.out.println(path.startsWith("/api"));
System.out.println(path.endsWith("orders"));
System.out.println(path.indexOf("api"));
System.out.println(path.replace("orders", "users"));
문자열은 불변 객체이므로 replace(), trim() 같은 메소드는 원본 문자열 자체를 수정하지 않고 새 문자열을 반환한다.
String original = "hello";
String upper = original.toUpperCase();
System.out.println(original); // hello
System.out.println(upper); // HELLO
equals()Java 입문에서 가장 중요한 실수 중 하나다.
String a = new String("Java");
String b = new String("Java");
System.out.println(a == b); // false
System.out.println(a.equals(b)); // true
==는 참조가 같은지 비교하고, equals()는 문자열의 내용을 비교한다.
리터럴에서는 문자열 풀 때문에 우연히 ==가 true가 나올 수 있다.
String a = "Java";
String b = "Java";
System.out.println(a == b); // true일 수 있음
그래도 문자열 내용 비교는 항상 equals()를 사용하는 습관을 들이는 것이 안전하다.
null 가능성이 있는 값을 비교할 때는 상수를 앞에 두는 방법도 있다.
if ("ACTIVE".equals(status)) {
// ...
}
문자열 안에서 줄바꿈, 탭, 따옴표 같은 특수 문자를 표현할 때 사용한다.
System.out.println("first\nsecond");
System.out.println("name\tvalue");
System.out.println("C:\\logs\\app.log");
System.out.println("\"Java\"");
if, else if, else조건에 따라 실행할 코드를 나눌 때 사용한다.
int statusCode = 404;
if (statusCode >= 500) {
System.out.println("서버 오류");
} else if (statusCode >= 400) {
System.out.println("클라이언트 오류");
} else {
System.out.println("정상 또는 리다이렉션");
}
여러 문장을 실행한다면 중괄호를 항상 사용하는 편이 실수를 줄인다.
switch: 값에 따라 분기하기전통적인 형태는 다음과 같다.
String role = "ADMIN";
switch (role) {
case "ADMIN":
System.out.println("관리자 권한");
break;
case "USER":
System.out.println("일반 사용자 권한");
break;
default:
System.out.println("알 수 없는 권한");
}
break를 생략하면 다음 case까지 이어서 실행되는 fall-through가 발생할 수 있다.
현대 Java에서는 화살표 형태의 switch 표현식도 사용할 수 있다.
String label = switch (role) {
case "ADMIN" -> "관리자";
case "USER" -> "사용자";
default -> "알 수 없음";
};
단순한 값 매핑에서는 이 형태가 더 읽기 쉽다.
for: 반복 횟수를 알 때for (int i = 0; i < 5; i++) {
System.out.println("request-" + i);
}
실행 흐름은 다음 순서다.
초기화 → 조건 확인 → 본문 실행 → 증감 → 조건 확인 → ...
중첩 반복문도 만들 수 있다.
for (int page = 1; page <= 3; page++) {
for (int item = 1; item <= 2; item++) {
System.out.println("page=" + page + ", item=" + item);
}
}
바깥쪽 3회 × 안쪽 2회이므로 본문은 총 6회 실행된다.
while: 조건이 유지되는 동안반복 횟수보다 조건이 중요할 때 사용한다.
int retry = 0;
while (retry < 3) {
System.out.println("API 재시도: " + retry);
retry++;
}
조건이 계속 true라면 무한 반복이 발생하므로 반복문 안에서 조건을 바꿀 수 있는지 확인해야 한다.
do-while: 최소 한 번은 실행int retry = 0;
do {
System.out.println("요청 실행");
retry++;
} while (retry < 3);
while과 달리 조건을 나중에 검사하므로 본문이 최소 한 번 실행된다.
break와 continuebreak는 반복문을 즉시 끝낸다.
for (int i = 0; i < 10; i++) {
if (i == 3) {
break;
}
System.out.println(i);
}
continue는 현재 회차의 남은 코드를 건너뛰고 다음 반복으로 이동한다.
for (int i = 0; i < 5; i++) {
if (i == 2) {
continue;
}
System.out.println(i);
}
+, -, *, /, %가 있다.boolean을 만들고, &&, ||, !로 조건을 조합할 수 있다.==가 아니라 equals()를 사용한다.if는 범위 조건, switch는 명확한 값 분기에 잘 맞는다.for는 반복 횟수가 명확할 때, while은 조건 중심 반복에 적합하다.do-while은 본문을 최소 한 번 실행한다.break는 반복 종료, continue는 현재 회차만 건너뛴다.