Java

[Java] 04. Statement와 Expression

Joo.v7 2024. 8. 22. 21:20

Chapter 1: Statement 개요

  • Statement block (문 블록)
  • Statement(문)의 종류

Chapter 2: Selection Statement (선택문)

  • if Statement (if 문)
  • Cascading if statement (Cascading if 문)
  • switch statement (switch 문)

Chapter 3: Iteration Statement (반복문)

  • while statement (while 문)
  • do statement (do 문)
  • for statement (for 문)
  • foreach statement (foreach 문)

Chapter 4: Jump Statement (분기문)

  • goto statement (goto 문)
  • break / continue statement (break 문 / continue 문)

* Lab 4-1: 연도 일자를 월/일로 계산

Chapter 5: 기본 예외 처리

  • 예외 사용 이유
  • 예외 객체
  • try/catch 블록
  • 다중 catch 블록

Chapter 6: 예외 발생시키기

  • throw stateent (throw 문)
  • throws: 메소드에 예외 선언
  • finally statement (finally 문)
  • try-with-resource clause (try-with-resource 절)

* Lab 4-2: 예외 처리


Chapter 1: Statement 개요

디스크에 있던 프로그램이 메모리에 올라가면서 실행되는데, 프로그램은 블록들의 집합이다. 블록은 statement의 묶음이다. 

(자바에서 블록은 { } 단위로 저장한다)

  • Statement: 명령문. 메모리의 상태를 변경, 프로그램을 구성하는 기본 단위이자 최소 실행 단위. 
    ex) int a = 5;    var x;     function f1() { };
  • Expression: 표현식. 메모리의 상태 변화 주도 하지 않음. 값으로 표현될 수 있는 식. 
    ex) 1 + 5   10   ' java '

 

Statement block (문 블록)

  • Java, C, C++, C#은 { }와 ( )를 사용하여 명령문을 그룹화 한다.
  • { } 중괄호로 묶인 statement의 그룹을 statement block이라 한다.
/* { } 중괄호를 statement block의 기호로 사용한다 */
{
// code
    {
        // code
    }
}

 

Statement(문)의 종류

     (1) 선택문: if / switch문 (식의 값을 선택하고 그 선택에 따라 문을 실행되는 statement)
     (2) 반복문: while / do-while / for / foreach 문 (특정 조건이 true일 동안 반복적으로 실행되는 statement) 
     (3) 분기문: break / continue 문 (제어를 다른 statement으로 옮기는 statement)

 

 


 

Chapter 2: Selection Statement (선택문)

 

expression의 값에 따라 선택하고, 그 선택에 따라 선택적으로 statement를 실행한다.

 

(1) if Statement (if 문)

  • 조건문(boolean-expression)의 결과에 따라 블록의 실행 여부를 결정한다.
  • Java에서는 조건문(boolean-expression)에 정수 값을 사용할 수 없다.
/* if statement */
if (boolean-expression)
	첫 번째 문
else
	두 번째 문
    
/* Java는 boolean-expression(조건문)에 정수값 사용할 수 없다 */
int x;
…
if (x) ...	// Java에서는 (x != 0)으로 써야 함
if (x = 0)	// Java에서는 (x == 0)으로 써야 함

 

 (2) Cascading if statement (Cascading if 문)

  • else if 로 이어진, Cascading(계단식) if 문은 하나의 statement로 동작한다.
  • 하나의 if 문은 각각 statement다.
/* Cascading if 문, 아래의 중 하나의 if 또는 else if 블록만이 실행된다. */
int monthNumber = 2;
int daysInMonth = 0;

if (monthNumber == 2) {
    daysInMonth = 28;
}
else if (monthNumber == 4) {
    daysInMonth = 30;
}
else if (monthNumber == 6) {
    daysInMonth = 30;
}
else {
    daysInMonth = 31;
}

/* 하나의 if 문은 각각이 statement다, 따라서 아래 두 if 문은 monthNumber에 관계없이 모두 실행된다. */
if (monthNumber == 1) {
    daysInMonth = 31;
}

if (monthNumber == 2) {
    daysInMonth = 28
}

 

 

 (3) switch statement (switch 문)

  • 여러 case에 대응해야 하는 경우에 사용한다.
  • break 문을 사용하여 statement의 진행을 제어한다.
  • switch 문은 조건식을 계산 후 결과와 일치하는 case 문으로 이동하여 해당 case 문 아래에 있는 문장들을 수행한다.
switch (monthNumber) {
case 2:
    daysInMonth = 28; break;
case 4:
case 6:
case 9:
case 11:
    daysInMonth = 30; break;
default:
    daysInMonth = 31; break;
}

(좌) break문이 없는 switch문, 실행 결과: monthDays = 31 / (우) break문이 있는 switch문, 실행 결과: monthDays = 30

 

 

Chapter 3: Iteration Statement (반복문)

 특정 조건이 true 인 동안 작업을 수행한다.

 

 (1) while statement (while 문) 

  • boolean 값을 기준으로 내부 문을 수행한다.
  • 반복이 시작될 때 boolean-expression을 평가, 이 값이 true 일 때 { }를 실행한다.
  • 조건에 따라 한 번도 실행되지 않을 수 있다.
/* while statement 형식 */
초기값
while (boolean-expression) {
    embedded-statement
    값 업데이트
}

/* while을 사용하여 구구단(2~9단) 출력 */
int i = 2; j = 1;
while (i <= 9) {
    while (j <= 9) {
        System.out.println(i + “ * ” + j + “ = ” + i * j);
    }
    i++;
    j = 1;
}

 

 (2) do statement (do 문)

  • boolean 값을 기준으로 내부 문을 수행한다.
  • 반복일 끝날 때 boolean-expression을 평가하고, 이 값이 true일 때 내부 문 실행한다.
  • 최소 한 번은 실행된다.
/* 입력받은 숫자의 구구단을 출력하는 do-while 문 */
Scanner scanner = new Scanner(System.in);
int i = scanner.nextInt();
int j = 1;
do {
if (i < 1 || i >= 9) {
         break;
    }
    System.out.println(i + “ * ” + j + “ = ” + i * j);
} while (j <= 9);
scanner.close();

 

(3) for statement (for 문)

/* for statement 구문 */
for (초기자; 종료 조건; 조건 업데이트) {
    embedded-statement
}

/* 구구단(0~10단) */
class test2 {
    public static void main(String[] args) {
        for(int i=0; i<11; i++) {
            for(int j=0; j<11; j++){
                System.out.printf("%d * %d = %d \n", i, j, i*j);
            }
            System.out.println("\n");
        }
    }
}

 

(4) foreach statement (foreach 문)

  • 파이썬의 반복문과 유사하다
/* foreach문, 배열의 모든 요소의 값을 출력 */
// for-each문 -> for (int i : array) 하면 array의 값을 i에 넣는것임. like 파이썬
int[] array = {3, 4, 5, 2, 3, 4, 6};
for(int i: array) {
    System.out.print(i + “ “);
} 
// 실행 결과: 3 4 5 2 3 4 6

/* 구구단(2~9단) */
class Test4 { 
    public static void main(String[] args) {
        int[] array1 = {2,3,4,5,6,7,8,9};
        int[] array2 = {1,2,3,4,5,6,7,8,9};
        
        for(int i : array1) {
            for(int j : array2) {
                System.out.printf("%d * %d = %d \n", i, j, i * j);
            }
            System.out.println("\n");
        }
    }
}

int[] array = {3, 4, 5, 2, 3, 4, 6};
for(int i: array) {
    System.out.print(i + “ “);
}

 

Chapter 4: Jump Statement (분기문)

 

 프로그램의 한 지점에서 다른 지점으로 제어를 전송하는데 사용된다.

 

(1) goto statement (goto 문)

  • Java에서는 goto문을 사용하지 않는다.
  • goto 키워드는 존재하지만 구현되어 있지 않다.

 

 (2) break / continue statement (break 문 / continue 문)

  • break 문: 반복의 밖으로 분기함. 가장 가까운 while, do-while, for, foreach 문을 종료한다. 
  • continue 문: 다음 반복으로 분기함. while, do-while, for, foreach 문에서 현재 반복을 건너뛰고 다음 반복으로 넘어간다.
/* break 문. i가 5가 되면 반복문 종료 */
for (int i = 0; i < 10; i++) {
    if (i == 5) {
        break;  // i가 5가 되면 루프를 종료합니다.
    }
    System.out.print(i + " ");
}
// 실행 결과
0 1 2 3 4

/* continue 문. i가 짝수인 경우 다음 반복으로 넘어감 */
for (int i = 0; i < 10; i++) {
    if (i % 2 == 0) {
        continue;  // 짝수일 경우 나머지 코드를 건너뛰고 다음 반복으로 넘어갑니다.
    }
    System.out.println(i);
}
// 실행 결과
1 3 5 7 9

 

* Lab 4-1: 연도 일자를 월/일로 계산

2024.08.23 - [코딩 문제] - [코딩 문제] 연도 일자를 월/일로 계산하기

 

[코딩 문제] 연도 일자를 월/일로 계산하기

문제 1) 1 ~ 365 사이의 수(일)를 읽어서 월과 일로 변환한 다음 출력하는 프로그램을 작성하시오. (윤년 무시)ex) 입력: 40   ->   출력: February 9import java.util.Scanner;public class Whatday { public static void mai

lightningtech.tistory.com

 

 


 

Chapter 5: 기본 예외 처리

예외 사용 이유

  • 전통적인 절차적 오류 처리는 사용하기 번거로움. ex) goto
  • 오류 처리를 위한 코드에서 오류를 일으킬 수 있다.
  • 오류는 의미를 가지고 있지 않다. ex) error code -1

예외 객체

  • Exception(예외): 프로그램 실행 중에 예측할 수 있는 오류 상황이 발생했을 때.
    • Checked exception: 컴파일 시점에 체크되는 예외. 해당 예외를 처리하지 안으면 컴파일 오류 발생.
    • Unchecked exception: 실행 시점(런타임)에 발생할 수 있는 예외. 컴파일 오류가 발생하지 않으나 프로그래밍 실수, 논리 오류로 인해 발생하는 예외.
  • Error: 시스템에 비정상적인 상황이 발생했을 때. ex) OutofMemoryError, StackOverflowError 등..

Java의 Exception

   

try/catch 블록, 다중 catch 블록

  • 오류 처리에 대한 객체지향적인 방법.
  • try 블록: 예외를 발생시킬 수 있는 코드.
  • catch 블록: 예외 처리 코드.
  • 다중 catch 블록: 각 catch 블록은 하나의 예외 클래스를 잡아낸다.

try 블록에서 예외가 발생하면 runtime은 수행을 중지하고 예외를 잡을 수 있는 catch 블록을 검색한다. catch 블록을 찾으면 실행하고, 찾지 못하면 적절한 catch 블록을 찾을 때까지 검색하다가 main 함수의 끝에 도달하면 프로그램이 종료된다. 

/* 컴파일(javac) 후 실행(터미널에 java Exception 10 입력) */
public class Exceptions {
    public static void main(String[] args) {
        try {
            System.out.println(args[0]);	// 명령줄 인수로 전달된 첫 번째 값을 출력함.
            int j = Integer.parseInt(args[0]);
            }
        catch(ArrayIndexOutOfBoundsException e) {	// args[0]이 존재하지 않는 경우 (입력하지 않은 경우)
            System.out.println("useage: java sample <filename>");
        }
        catch(NumberFormatException e) {	// args[0]을 int로 변환할 수 없는 경우 (1,2가 아닌 문자나 다른 형식을 입력한 경우)
            System.out.println("please use a digit");
        }
        catch (Exception e) {	// 그 외 나머지 예외들
            System.out.println("anyway, an error was occured");
        }
    }
}

 

실행 결과

/* 터미널(zsh) */
joo@JOOui-MacBookAir 20240821 % javac Exceptions.java
joo@JOOui-MacBookAir 20240821 % java Exceptions 10
10
joo@JOOui-MacBookAir 20240821 % java Exceptions 1231241
1231241

 

만약 catch(Exception e) { ... } 로 모든 예외를 처리하도록 작성 후 Exception 자식 클래스에 해당하는 예외는 작성할 수 없다.

catch(java.lang.Exception e) { … }
catch(ArithmeticException e) { … } // 컴파일 오류

 

 


 

Chapter 6: 예외 발생시키기

예외를 임의로 발생시키고 처리할 수 있는 방법.

 

throw statement (throw 문)

  • 예외를 명시적으로 발생시키기 위해 사용된다.
  • 의도적으로 예외를 발생시켜 특정한 조건에서 프로그램의 흐름을 제어한다.
  • 예외에 의미있는 메시지를 제공한다.

throw 문 형식

throw new ExceptionType("Exception Message");
public static void main(String[] args) {
    try {
        int dayNumber = Integer.parseInt(args[0]);
        if (dayNumber < 1 || dayNumber >= 60) {	// dayNumber가 1보다 작거나 60보다 크면 아래의 예외를 발생시킨다.
            throw new IlligalArgumentException("Invalid day number");
	        // 여기부터의 코드는 실행되지 않음
        }
    }
    catch (IlligalArgumentException e) {
        System.out.println(e.getMessage()); // .getMessage(): 예외 객체가 생성될 때 전달된 메시지를 반환한다.
    }
}

 

 

catch 블록에서 throw문 사용

/* catch 블록에서 현재 예외 객체를 다시 발생 */
catch (DateTimeException e) {
    throw e;
}

/* catch 블록에서 다른 예외 발생 */
catch (IOException e) {
   …
   throw new FileNotFoundException(fileName);
}

/* catch 블록에서 잡은 예외 정보를 포함하는 다른 예외를 발생 */
catch (IOException e) {
   …
   throw new FileNotFoundException(fileName, e);
}

 

throws: 메소드에 예외 선언

  • 메소드에서 발생할 수 있는 예외를 메소드 선언부에 명시하여 알린다. 
  • 예외가 선언된 메소드를 호출하는 쪽에서 예외를 처리해야 한다. (예외 떠넘기기)
public int getFileSize(String fileName) throws FileNotFoundException, IOException {
   …
}

 

throws로 선언된 메소드 호출

/* throws로 선언된 메소드 호출시, 호출한 메소드에서 예외를 처리하도록 작성해야한다. */
public static int getFileSize(String fileName) throws IOException {
    return 1;
}

public static void main(String[] args) {
    try {
        TryCatch tryCatch = new TryCatch();
        tryCatch.getFileSize("a.java");
    }
    catch (IOException e) {
        e.printStackTrace();	// .printstackTrace(): 예외가 발생한 클래스명, 파일명, 라인 번호 출력
    }
}

/* 아래와 같이 메소드에서 선언한 예외와 다른 타입의 예외를 호출하면 오류가 발생한다 */
public int getFileSize(String fileName) throws IOException {
    return 1;
}

public static void main(String[] args) {
    try {
        TryCatch tryCatch = new TryCatch();
        tryCatch.getFileSize("a.java");	// 오류 발생: IOException을 처리하지 않음
    }
    catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}

/* 아래와 같이 모든 예외를 처리하도록 할 수 있다. */
public int getFileSize(String fileName) throws IOException {
    return 1;
}

public static void main(String[] args) {
    try {
        TryCatch tryCatch = new TryCatch();
        tryCatch.getFileSize("a.java");
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}

 

finally statement (finally 문)

  • 예외 발생시에도 반드시 실행되어야 하는 구문들을 처리할 때 사용.
  • try-catch 예외 처리 문에서 예외의 발생 여부와 상관없이 무조건 실행.
  • 두 가지 상황에서 사용: 중복 코드 방지 / 예외 발생 후 resource 해제 해야 하는 경우.
/* 중복 코드 방지: try 블록과 catch 블록 모두에서 반드시 사용되어야 하는 경우 */
try {
    …
    statements
}
catch {
    statements
}

// finally 사용
try {
    …
}
catch {
    …
}
finally {
    statements
}

/* finally 블록에서 발생하는 예외 역시 try-catch 문으로 처리할 수 있다. */
// finally 블록에서 발생한 예외가 다른 예외들을 덮어써서 무시된다 
try {
    …
    try {
        …
    }
    catch (IOException e) {	  // FileNotFoundException이 처리되지 않은 경우
    }
    finally {
        throw new FileNotFoundException(fileName);
        }
    }
catch (FileNotFoundException e) {	// FileNotFoundException이 처리됨
}

try-with-resource clause (try-with-resource 절)

  • 예외 발생 여부와 상관없이 try절에 명시된 객체의 close 메소드를 자동으로 호출한다.
  • try-with-resource 문에 사용될 수 있는 객체는 AutoCloseable 의 서브 타입이어야 한다.
  • 다른 객체 또는 프로세스와 연결된 객체(scanner 등)는 사용 종료 후 명시적으로 연결을 닫아야 하는데 finally 절에서 close() 메소드를 명시하지 않아도 자동으로 연결을 닫고 resource를 회수한다. 이는 memory leak 문제를 방지한다.
    * Memory leak (메모리 누수): 프로그램이 필요하지 않은 메모리를 해제 하지 않아 발생하는 문제.
/* finally 절에 명시적으로 연결 객체의 close() 메소드를 호출 */
Scanner scanner = new Scanner(System.in);
try {
   ...
}
catch (ArithmeticException e) {
   ...
}
finally {
   scanner.close();	// 명시적으로 연결을 닫음
}

/* try-with-resource 사용 */
// 주의: try 블록이 끝나면 try()안의 자원이 닫힘!!!
try (Scanner scanner = new Scanner(System.in)) { 
   ...
}
catch (ArithmeticException e) {
    e.printStackTrace();
}

 

* Lab 4-2: 예외 처리

2024.08.23 - [코딩 문제] - [코딩 문제] 연도 일자를 월/일로 계산하기

 

[코딩 문제] 연도 일자를 월/일로 계산하기

문제 1) 1 ~ 365 사이의 수(일)를 읽어서 월과 일로 변환한 다음 출력하는 프로그램을 작성하시오. (윤년 무시)ex) 입력: 40   ->   출력: February 9import java.util.Scanner;public class Whatday { public static void mai

lightningtech.tistory.com

 

 


 

 

출처: https://github.com/gikpreet/class-programming_with_java/tree/master

 

GitHub - gikpreet/class-programming_with_java

Contribute to gikpreet/class-programming_with_java development by creating an account on GitHub.

github.com