If-Then 명령문
If-Then 문은 모든 제어 흐름 명령문 중 가장 기본적인 명령문입니다. 특정 테스트가 true로 평가될 경우에만 코드의 특정 부분을 실행하도록 프로그램에 지시합니다. 예를 들어, Bicycle 클래스는 자전거가 이미 움직이고 있는 경우에만 브레이크를 통해 자전거의 속도를 줄이도록 할 수 있습니다. applyBrakes() 메서드의 한 가지 가능한 구현은 다음과 같습니다:
void applyBrakes() {
// the "if" clause: bicycle must be moving
if (isMoving){
// the "then" clause: decrease current speed
currentSpeed--;
}
}이 테스트가 false로 평가되면(자전거가 움직이지 않는다는 의미), 제어는 if-then 문 끝으로 넘어갑니다.
또한 “then” 절에 명령문이 하나만 포함되어 있는 경우 여는 중괄호와 닫는 중괄호는 선택 사항입니다:
void applyBrakes() {
// same as above, but without braces
if (isMoving)
currentSpeed--;
}중괄호를 생략할 시기를 결정하는 것은 개인적인 취향의 문제입니다. 중괄호를 생략하면 코드가 더 취약해질 수 있습니다. 나중에 “then” 절에 두 번째 명령문을 추가하는 경우 흔히 발생하는 실수는 새로 필요한 중괄호를 추가하는 것을 잊어버리는 것입니다. 컴파일러는 이런 종류의 오류를 잡아낼 수 없으므로 잘못된 결과를 얻을 수 있습니다.
If-Then-Else 명령문
if-then-else 문은 if 절이 false로 평가될 때 보조 실행 경로를 제공합니다. 자전거가 움직이지 않을 때 브레이크를 밟으면 어떤 동작을 수행하기 위해 applyBrakes() 메서드에 if-then-else 문을 사용할 수 있습니다. 이 경우 동작은 단순히 자전거가 이미 멈췄다는 오류 메시지를 인쇄하는 것입니다.
void applyBrakes() {
if (isMoving) {
currentSpeed--;
} else {
System.err.println("The bicycle has already stopped!");
}
}다음 프로그램인 IfElseDemo는 시험 점수의 값에 따라 등급을 부여합니다(90% 이상이면 A, 80% 이상이면 B 등).
class IfElseDemo {
public static void main(String[] args) {
int testscore = 76;
char grade;
if (testscore >= 90) {
grade = 'A';
} else if (testscore >= 80) {
grade = 'B';
} else if (testscore >= 70) {
grade = 'C';
} else if (testscore >= 60) {
grade = 'D';
} else {
grade = 'F';
}
System.out.println("Grade = " + grade);
}
}프로그램의 출력은 다음과 같습니다:
Grade = C복합 명령문에서 testscore의 값이 76 >= 70과 76 >= 60 등 두 개 이상의 표현식을 만족할 수 있다는 것을 눈치챘을 것입니다. 그러나 한 조건이 만족되면 해당 명령문(grade = 'C';)이 실행되고 나머지 조건은 평가되지 않습니다.
While 및 Do-while 명령문
While 문은 특정 조건이 true인 동안 명령문 블록을 계속 실행합니다. 구문은 다음과 같이 표현할 수 있습니다:
while (expression) {
statement(s)
}while 문은 boolean 값을 반환해야 하는 표현식을 평가합니다. 표현식이 true로 평가되면 while 문은 동안 블록에 있는 명령문(들)을 실행합니다. while 문은 표현식이 false로 평가될 때까지 표현식을 계속 테스트하고 해당 블록을 실행합니다. while 문을 사용하여 1부터 10까지의 값을 출력하는 것은 다음 WhileDemo 프로그램에서와 같이 수행할 수 있습니다:
class WhileDemo {
public static void main(String[] args){
int count = 1;
while (count < 11) {
System.out.println("Count is: " + count);
count++;
}
}
}다음과 같이 while 명령문을 사용하여 무한 루프를 구현할 수 있습니다:
while (true){
// your code goes here
}Java 프로그래밍 언어에서는 다음과 같이 표현할 수 있는 do-while 명령문도 제공합니다:
do {
statement(s)
} while (expression);do-while과 while의 차이점은 do-while은 루프의 위쪽이 아닌 아래쪽에서 해당 표현식을 평가한다는 것입니다. 따라서 다음 DoWhileDemo 프로그램에서 볼 수 있듯이 do 블록 내의 명령문은 항상 한 번 이상 실행됩니다:
class DoWhileDemo {
public static void main(String[] args){
int count = 1;
do {
System.out.println("Count is: " + count);
count++;
} while (count < 11);
}
}
For 명령문
for 명령문은 다양한 값을 반복하는 간결한 방법을 제공합니다. 프로그래머들은 특정 조건이 충족될 때까지 반복적으로 반복하는 방식 때문에 이를 “for loop”라고 부르기도 합니다. for 명령문의 일반적인 형태는 다음과 같이 표현할 수 있습니다:
for (initialization; termination; increment) {
statement(s)
}이 버전의 for 명령문을 사용할 때는 다음 사항에 유의하세요:
- 초기화(initialization) 표현식은 루프를 초기화하며, 루프가 시작될 때 한 번 실행됩니다.
- 종료(termination) 표현식이
false로 평가되면 루프가 종료됩니다. - 증분(increment) 표현식은 루프를 반복할 때마다 호출되며, 이 표현식은 값을 증가시키거나 감소시키는 데 완벽하게 사용할 수 있습니다.
다음 프로그램인 ForDemo는 일반적인 형태의 for 명령문을 사용하여 숫자 1부터 10까지를 표준 출력으로 출력합니다:
class ForDemo {
public static void main(String[] args){
for(int i = 1; i < 11; i++){
System.out.println("Count is: " + i);
}
}
}이 프로그램의 출력은 다음과 같습니다:
Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9
Count is: 10코드가 초기화 표현식 내에서 변수를 선언하는 방식을 주목하세요. 이 변수의 범위는 선언에서 for 문이 제어하는 블록의 끝까지 확장되므로 종료 및 증분 표현식에서도 사용할 수 있습니다. for 문을 제어하는 변수가 루프 외부에서 필요하지 않은 경우 초기화 표현식에서 변수를 선언하는 것이 가장 좋습니다. i, j, k라는 이름은 종종 for 루프를 제어하는 데 사용되며, 초기화 표현식 내에서 선언하면 수명을 제한하고 오류를 줄일 수 있습니다.
for 루프의 세 가지 표현식은 선택 사항이며, 다음과 같이 무한 루프를 만들 수 있습니다:
// infinite loop
for ( ; ; ) {
// your code goes here
}for 명령문에는 컬렉션과 배열을 통한 반복을 위해 설계된 또 다른 형식도 있습니다. 이 형식을 향상된 for(enhanced for) 명령문이라고도 하며, 루프를 더 간결하고 읽기 쉽게 만드는 데 사용할 수 있습니다. 예를 들어 숫자 1부터 10까지가 들어 있는 다음 배열을 살펴보겠습니다:
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};다음 프로그램인 EnhancedForDemo는 배열을 반복하기 위해 향상된 for(enhanced for) 를 사용합니다:
class EnhancedForDemo {
public static void main(String[] args){
int[] numbers =
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int item : numbers) {
System.out.println("Count is: " + item);
}
}
}이 예제에서 item 변수는 숫자 배열의 현재 값을 보유합니다. 이 프로그램의 출력은 이전과 동일합니다:
Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9
Count is: 10가능하면 일반적인 형식 대신 이 형식의 for 명령문을 사용하는 것이 좋습니다.
Break 명령문
break 명령문에는 레이블이 있는 형태와 레이블이 없는 형태의 두 가지가 있습니다. 이전 switch 문에 대한 설명에서 레이블이 없는 형태를 보았습니다. 레이블이 없는 break를 사용하여 다음 BreakDemo 프로그램에서와 같이 for, while 또는 do-while 루프를 종료할 수도 있습니다:
class BreakDemo {
public static void main(String[] args) {
int[] arrayOfInts =
{ 32, 87, 3, 589,
12, 1076, 2000,
8, 622, 127 };
int searchfor = 12;
int i;
boolean foundIt = false;
for (i = 0; i < arrayOfInts.length; i++) {
if (arrayOfInts[i] == searchfor) {
foundIt = true;
break;
}
}
if (foundIt) {
System.out.println("Found " + searchfor + " at index " + i);
} else {
System.out.println(searchfor + " not in the array");
}
}
}이 프로그램은 배열에서 숫자 12를 검색합니다. break문은 해당 값이 발견되면for루프를 종료합니다. 그러면 제어 흐름이for` 루프 뒤의 명령문으로 전달됩니다. 이 프로그램의 출력은 다음과 같습니다:
Found 12 at index 4레이블이 없는 break 문은 가장 안쪽의 switch, for, while 또는 do-while 문을 종료하지만 레이블이 있는 break는 바깥쪽 문을 종료합니다. 다음 프로그램인 BreakWithLabelDemo는 이전 프로그램과 유사하지만 중첩된 for 루프를 사용하여 2차원 배열에서 값을 검색합니다. 값이 발견되면 레이블이 지정된 break가 외부 for 루프(“search” 레이블)를 종료합니다:
class BreakWithLabelDemo {
public static void main(String[] args) {
int[][] arrayOfInts = {
{ 32, 87, 3, 589 },
{ 12, 1076, 2000, 8 },
{ 622, 127, 77, 955 }
};
int searchfor = 12;
int i;
int j = 0;
boolean foundIt = false;
search:
for (i = 0; i < arrayOfInts.length; i++) {
for (j = 0; j < arrayOfInts[i].length;
j++) {
if (arrayOfInts[i][j] == searchfor) {
foundIt = true;
break search;
}
}
}
if (foundIt) {
System.out.println("Found " + searchfor + " at " + i + ", " + j);
} else {
System.out.println(searchfor + " not in the array");
}
}
}이것이 프로그램의 출력입니다.
Found 12 at 1, 0break 문은 레이블이 지정된 문을 종료하지만 제어 흐름을 레이블로 이전하지는 않습니다. 제어 흐름은 레이블이 지정된(종료된) 문 바로 뒤에 있는 문으로 전달됩니다.
Continue 명령문
continue 명령문은 for, while 또는 do-while 루프의 현재 반복을 건너뜁니다. 레이블이 지정되지 않은 양식은 가장 안쪽 루프 본문의 끝으로 건너뛰고 루프를 제어하는 부울 표현식을 평가합니다. 다음 프로그램인 ContinueDemo는 문자 p의 발생 횟수를 세면서 String을 단계적으로 처리합니다. 현재 문자가 p가 아닌 경우 continue 문은 나머지 루프를 건너뛰고 다음 문자로 진행합니다. p인 경우 프로그램은 문자 수를 증가시킵니다.
class ContinueDemo {
public static void main(String[] args) {
String searchMe = "peter piper picked a " + "peck of pickled peppers";
int max = searchMe.length();
int numPs = 0;
for (int i = 0; i < max; i++) {
// interested only in p's
if (searchMe.charAt(i) != 'p')
continue;
// process p's
numPs++;
}
System.out.println("Found " + numPs + " p's in the string.");
}
}이 프로그램의 출력은 다음과 같습니다:
Found 9 p's in the string.이 효과를 더 명확하게 확인하려면 continue 명령문을 제거하고 다시 컴파일해 보세요. 프로그램을 다시 실행하면 9개가 아닌 35개의 p를 발견했다고 카운트가 잘못 표시됩니다.
레이블이 지정된 continue 문은 지정된 레이블이 표시된 외부 루프의 현재 반복을 건너뜁니다. 다음 예제 프로그램인 ContinueWithLabelDemo는 중첩 루프를 사용하여 다른 문자열 내에서 하위 문자열을 검색합니다. 하나는 하위 문자열을 반복하고 다른 하나는 검색 중인 문자열을 반복하는 두 개의 중첩 루프가 필요합니다. 다음 프로그램인 ContinueWithLabelDemo는 continue의 test 레이블을 사용하여 외부 루프에서 반복을 건너뜁니다.
class ContinueWithLabelDemo {
public static void main(String[] args) {
String searchMe = "Look for a substring in me";
String substring = "sub";
boolean foundIt = false;
int max = searchMe.length() -
substring.length();
test:
for (int i = 0; i <= max; i++) {
int n = substring.length();
int j = i;
int k = 0;
while (n-- != 0) {
if (searchMe.charAt(j++) != substring.charAt(k++)) {
continue test;
}
}
foundIt = true;
break test;
}
System.out.println(foundIt ? "Found it" : "Didn't find it");
}
}이 프로그램의 출력은 다음과 같습니다.
Found it
Return 명령문
다음 분기 명령문은 return 문입니다. return 명령문은 현재 메서드를 종료하고 제어 흐름은 메서드가 호출된 위치로 돌아갑니다. return 명령문에는 값을 반환하는 명령문과 값을 반환하지 않는 명령문의 두 가지 형태가 있습니다. 값을 반환하려면 return 키워드 뒤에 값(또는 값을 계산하는 표현식)을 넣으면 됩니다.
return ++count;반환되는 값의 데이터 타입은 메서드에서 선언된 return 값의 타입과 일치해야 합니다. 메서드가 void로 선언된 경우 값을 반환하지 않는 return 형식을 사용하세요.
return;클래스와 객체 섹션에서는 메서드 작성에 대해 알아야 할 모든 것을 다룹니다.
Yield 명령문
마지막 분기 명령문은 yield 문입니다. yield문은 현재 있는switch 표현식에서 종료됩니다. yield 문 뒤에는 항상 값을 생성해야 하는 표현식이 뒤따릅니다. 이 표현식은 void가 아니어야 합니다. 이 표현식의 값은 둘러싸고 있는 switch 표현식에서 생성되는 값입니다.
다음은 yield 명령문의 예입니다.
class Test {
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public String calculate(Day d) {
return switch (d) {
case SATURDAY, SUNDAY -> "week-end";
default -> {
int remainingWorkDays = 5 - d.ordinal();
yield remainingWorkDays;
}
};
}
}