
※ 이 글은 쉽게 배우는 자바 프로그래밍(2017) 내용을 기반으로 작성했습니다. 일부 내용은 생략되었습니다.
제어문
일반적으로 프로그램의 실행문은 순차적으로 수행한다. 하지만 항상 순차적으로만 실행하면 문제가 발생한다.
예를 들어, 어떤 변수에 10을 1000번을 더해야 한다면, 실행문을 1000번 적어야 한다.
또 순차적 실행은 선택 개념이 없어서 특정 상황엔 다른 선택을 할 수가 없다.
그래서 프로그래밍 언어는 제어문을 사용해 실행문을 비순차적으로 수행할 수 있게 한다.
- 제어문 : 실행문의 수행 순서를 변경하는 문장
- 조건문 : 조건식의 결과에 따라 여러 실행 경로 중 하나를 선택하는 문장 (if, switch)
- 반복문 : 조건에 따라 같은 처리를 반복하는 문장 (for, while, do~while)
- 분기문 : 실행 흐름을 무조건 변경시키는 문장 (break, continue)
조건문
조건문은 크게 단순 if문, if~else문, 다중 if문, 중첩 if문, switch문이 있다.
- 단순 if문 : 조건식이 true일 때만 실행문을 수행한다.
- 조건식에는 연산식, 논리 값, 변수가 올 수 있다.
- 수행할 실행문이 하나라면 {}를 생략 가능하다.
if (조건식) {
실행문(들);
}
- if~else문 : if문 조건식이 true이면 if문 실행 블록을 실행하고, false이면 else문 실행 블록을 실행한다.
if (조건식) {
실행문(들);
}
else {
실행문(들);
}
- 다중 if문 : 각 조건식을 차례대로 검사한 뒤 만족하는 조건식의 실행문을 실행한다.
- 즉, 아래로 내려가면서 조건을 검사하고, 모든 조건에 만족하지 않으면 else문을 실행하는 방식
if (조건식) {
실행문(들);
}
else if (조건식) {
실행문(들);
}
...
else {
실행문(들);
}
- 중첩 if문 : if문 안에 다른 if문이 포함되는 형태를 말한다.
- 적절하게 사용하면 괜찮지만, 너무 중첩을 많이 시키면 가독성이 떨어질 수 있다.
if (조건식) {
실행문(들);
}
else {
if (조건식) {
실행문(들);
}
...
}
- switch문 : 다중 if문을 쉽게 구현한 방법
- 구성 : 0개 이상의 case 레이블과 0~1개의 default 레이블을 포함
- case 레이블 : 수행할 실행문의 시작점
- default 레이블 : 어느 case 값과도 일치하지 않을 경우 수행
- case 레이블 마지막에 break 문을 넣어줘야 중간에 벗어날 수 있다.
switch(연산식) {
case 값1 :
실행문(들);
case 값2 :
실행문(들);
...
...
default :
실행문(들);
}
반복문
반복문도 크게 while문, do~while문, for문이 있다.
- while문 : 반복할 횟수는 알 수 없지만, 조건은 알고 있을 때 주로 사용하는 반복문
- 조건식이 true일 동안 실행문을 반복적으로 수행한다.
- 무한 반복으로 이어질 수 있기 때문에 본체를 탈출할 실행문이나, break문 사용이 필요하다.
- 중첩해서 사용 가능하다.

- do~while문 : while문과 기능은 같지만, 반복문 본체를 먼저 실행한 후, 조건식을 검사하는 반복문
- 그래서 do~while문은 최소 1번은 반복문 본체를 실행한다.

- for문 : 반복할 횟수를 미리 알 수 있을 때 주로 사용하는 반복문이다.
- 초기식, 조건식, 증감식으로 이루어져 있고, 상황에 따라 생략이 가능하다.
- 초기식 : for문이 시작될 때 최초 한 번만 실행됨.
- 조건식 : 조건식이 true이면 반복문 본체를 실행함.
- 증감식 : 반복 제어 변수의 값을 증가시키거나 감소시키는 식
- for문의 실행 흐름은 다음과 같다.
- ① 초기식 실행
- ② 조건식 검사 (False면 종료)
- ③ 반복문 본체 실행
- ④ 증감식 실행
- ⑤ 조건식이 True가 아닐 때까지 ②~④ 반복 실행

분기문
분기문은 break문, continue문이 있다.
- break문 : 반복문 또는 switch문에서 실행을 중단하고 다음 실행문으로 제어를 이동시키는 문장
- 레이블이 없다면 가장 안쪽 반복문을 종료하고, 레이블이 있다면 레이블을 붙인 반복문을 종료한다.

- continue문 : 반복문에서만 사용하며, 현재 반복을 중단하고 다음 반복으로 넘어가는 문장
- while문, do~while문은 조건식 검사로 넘어가지만, for문은 증감식으로 넘어간다.

메서드
메서드가 왜 필요할까?
만약 우리가 0~10, 10~100, 100~1000 구간의 합을 구하는 프로그램을 만든다 가정해보자. 우리가 배운 내용으로 코드를 짠다면 이렇게 짤 것이다.
int sum = 0;
for (int i = 0; i <= 10; i++)
sum += i;
System.out.println("합(1~10) : " + sum); // 합(1~10) : 55
sum = 0;
for (int i = 10; i <= 100; i++)
sum += i;
System.out.println("합(10~100) : " + sum); // 합(10~100) : 5005
sum = 0;
for (int i = 100; i <= 1000; i++)
sum += i;
System.out.println("합(100~1000) : " + sum); // 합(100~1000) : 495550
그런데 코드를 보면 반복되는 코드가 많다. 즉, 기본 틀을 만들어 재사용하는 편이 좋지 않을까?
이 반복되는 기본 틀을 만들어 둔것을 메서드라고 한다.
- 메서드 : 특정 연산을 수행하기 위해 실행문을 모아 둔 블록
- 중복 코드를 줄이고 재사용 가능
- 코드를 모듈화해 가독성을 높임 → 프로그램 품질 향상
그럼 메서드를 이용해 프로그램을 짠다면 어떻게 될까? 아래와 같이 코드도 훨씬 줄었고, 보기 편하다.
public static int sum(int i1, int i2) {
int sum = 0;
for (int i = i1; i <= i2 ; i++) {
sum += i;
}
return sum;
}
public static void main(String[] args) {
System.out.println("합(1~10) : " + sum(1,10)); // 합(1~10) : 55
System.out.println("합(10~100) : " + sum(10,100)); // 합(10~100) : 5005
System.out.println("합(100~1000) : " + sum(100,1000)); // 합(100~1000) : 495550
}
메서드의 구조

- 접근 지정자 : 컴파일러에 메서드의 접근 범위를 알려줌. (필수는 아님)
- 반환 타입 : 메서드가 본체를 실행한 후 반환할 데이터 타입으로, 반환할 데이터가 없다면 void를 사용함.
- 매개변수 : 메서드 외부에서 전달받는 값을 저장하기 위한 변수, 여러 개라면 데이터 타입을 따로 선언해야 함.
- 지역 변수 : 매개변수 또는 메서드 내부에 선언된 변수를 지역변수라고 함.
메서드의 호출과 반환
메서드는 호출해야 사용이 가능하고, 여러 번 호출이 가능하다.
메서드를 호출하면 제어가 호출된 메서드로 넘어가서 마지막까지 실행을 마친 뒤, 호출한 메서드로 복귀한다.
만약 return 문을 사용하면 메서드 실행 도중에도 호출한 메서드로 제어를 넘길 수 있다.
이때 반환할 데이터가 있다면 return문에 데이터를 포함해야 하며, 메서드 헤더에 있는 반환 타입과 같아야 한다.
public static void main(String[] args) {
printScore(99); // 점수 : 99
printScore(120); // 잘못된 점수 : 120
}
public static void printScore(int score) {
if (score <= 0 || score >= 100) {
System.out.println("잘못된 점수 : " + score);
return;
}
System.out.println("점수 : " + score);
}
메서드의 매개변수와 값 전달
매개변수를 가진 메서드를 호출할 때는 매개변수에 넘겨줄 값이나 변수를 제공하는데, 이 매개변수에 넘겨줄 값이나 변수를 인수(Argument)라고 부른다. 여기서 주의할 점은 매개변수 ≠ 인수라는 점이다.
- 매개변수 : 메서드 외부에서 전달받는 값을 저장하기 위한 변수
- 인수 : 매개변수에 넘겨줄 값이나 변수
가장 중요한 점은 메서드를 호출하면 인수 값의 복사본을 매개변수로 전달한다는 것이다.
이를 값 전달(Call by Value)이라 부르는데, 이 방식은 메서드를 실행하는 도중 매개변수 값이 변해도 인수에는 영향을 미치지 않는다. 복사본을 받은것이지 원본 그 자체를 받은게 아니여서이다.
public static void main(String[] args) {
int x = 0;
System.out.println("add() 메서드를 호출하기 전의 x는 " + x);
add(x);
System.out.println("add() 메서드를 호출한 후의 x는 " + x);
}
public static void add(int n) {
n++;
System.out.println("add() 메서드가 끝날 때의 n은 " + n);
}
// 출력결과
// add() 메서드를 호출하기 전의 x는 0
// add() 메서드가 끝날 때의 n은 1
// add() 메서드를 호출한 후의 x는 0
메서드 오버로딩
- 메서드 오버로딩 : 메서드 이름은 같지만, 메서드 시그니처가 다른 메서드를 정의하는 것
- 메서드 시그니처 : 메서드 이름, 매개변수 개수, 데이터 타입, 순서 등
아래처럼 메서드 오버로딩으로 매개변수가 달라도 같은 기능을 하는 여러 메서드를 만들 수 있다.
// 메서드 오버로딩 예시
public static void main(String[] args) {
int i1 = 3, i2 = 7, i3 = 10;
double d1 = 7.0, d2 = 3.0;
System.out.printf("max(%d, %d) = %d\n", i1, i2 ,max(i1, i2));
System.out.printf("max(%.1f, %.1f) = %.1f\n", d1, d2 , max(d1, d2));
System.out.printf("max(%d, %d, %d) = %d\n", i1, i2, i3 ,max(i1, i2, i3));
}
public static int max(int n1, int n2) {
int result = n1 > n2 ? n1 : n2;
return result;
}
public static double max(double n1, double n2) {
double result = n1 > n2 ? n1 : n2;
return result;
}
public static int max(int n1, int n2, int n3) {
return max(max(n1, n2), n3);
}
'공부 > Java' 카테고리의 다른 글
| [Java] 2. 자바 프로그램 구조와 기초 문법 익히기 (0) | 2026.06.17 |
|---|---|
| [Java] 1. 자바 시작하기 (0) | 2026.06.16 |