본문 바로가기

카테고리 없음

[2024-2 Java 스터디] 정채은 #7주차

반응형

[7-4] 예외 처리

 

<예외는 언제 발생하는가>

FileNotFoundException : 존재 하지 않는 파일 열 때

ArithmeticException : 산술 문제

ArrayIndexOutOfBoundsException : 배열에 아무것도 없는 곳을 가리킬 때 

 

<예외 처리하기>

try {
    <수행할 문장 1>;
    <수행할 문장 2>;
    ...
} catch(예외1) {
    <수행할 문장 A>;
    ...
} catch(예외2) {
    <수행할 문장 a>;
    ...
}

 

예외 X : catch 문장 수행 X

예외 O : catch 문장 수행 O

 

<finally>

예외 발생 → 프로그램 중지 or  예외 처리 : catch 구문 실행

 

but 예외 발생 → 반드시 실행 how ? 

public class Sample {
    public void shouldBeRun() {
        System.out.println("ok thanks.");
    }

    public static void main(String[] args) {
        Sample sample = new Sample();
        int c;
        try {
            c = 4 / 0;
            sample.shouldBeRun();  // 이 코드는 실행되지 않는다.
        } catch (ArithmeticException e) {
            c = -1;
        }
    }
}

 

sample.shouldBeRun()   메서드 반드시 실행 → finally 문 사용

 

public class Sample {
    public void shouldBeRun() {
        System.out.println("ok thanks");
    }

    public static void main(String[] args) {
        Sample sample = new Sample();
        int c;
        try {
            c = 4 / 0;
        } catch (ArithmeticException e) {
            c = -1;
        } finally {
            sample.shouldBeRun();  // 예외에 상관없이 무조건 수행된다.
        }
    }
}

 

예외 발생 여부에 상관없이 무조건 실행 ! 

 

<예외 활용하기 >

 

public class Sample {
    public void sayNick(String nick) {
        if("바보".equals(nick)) {
            return;
        }
        System.out.println("당신의 별명은 "+nick+" 입니다.");
    }

    public static void main(String[] args) {
        Sample sample = new Sample();
        sample.sayNick("바보");
        sample.sayNick("야호");
    }
}

 

sayNick 메서드 :  return으로 메서드 종료 → 별명 출력 X

 

<RuntimeException>

class FoolException extends RuntimeException {
}

public class Sample {
    public void sayNick(String nick) {
        if("바보".equals(nick)) {
            throw new FoolException();
        }
        System.out.println("당신의 별명은 "+nick+" 입니다.");
    }

    public static void main(String[] args) {
        Sample sample = new Sample();
        sample.sayNick("바보");
        sample.sayNick("야호");
    }
}

 

return했던 부분 → throw new FoolException()

 

Exception in thread "main" FoolException
    at Sample.sayNick(Sample.java:7)
    at Sample.main(Sample.java:14)

 

RuntimeException : 실행 시 발생하는 예외

Exception : 컴파일 시 발생하는 예외 (예측 가능한 경우)

 

<Exception>

RuntimeException 상속 → Exception 상속 : 컴파일 오류

FoolExceptionChecked Exception : 예외 처리 강제 

 

class FoolException extends Exception {
}

public class Sample {
    public void sayNick(String nick) {
        try {
            if("바보".equals(nick)) {
                throw new FoolException();
            }
            System.out.println("당신의 별명은 "+nick+" 입니다.");
        }catch(FoolException e) {
            System.err.println("FoolException이 발생했습니다.");
        }
    }

    public static void main(String[] args) {
        Sample sample = new Sample();
        sample.sayNick("바보");
        sample.sayNick("야호");
    }
}

 

sayNick 메서드에서 try ~ catch 문으로 FoolException을 처리

 

<예외 던지기>

 

예외 위로 던지기 ♥

public class Sample {
    public void sayNick(String nick) throws FoolException {
        try {   // try .. catch 문을 삭제할수 있다.
            if("바보".equals(nick)) {
                throw new FoolException();
            }
            System.out.println("당신의 별명은 "+nick+" 입니다.");
        }catch(FoolException e) {
            System.err.println("FoolException이 발생했습니다.");
        }
    }

    public static void main(String[] args) {
        Sample sample = new Sample();
        sample.sayNick("바보");
        sample.sayNick("야호");
    }
}

 

sayNick 메서드 뒷부분에 throws 구문 이용 !

 

throw와 throws의 차이

throw: 메서드 에서 예외를 발생시키는 데 사용

thorws: 메서드 선언부에서 사용, 해당 메서드가 처리하지 않은 예외를 호출자에게 전달

 

by throws 구문 , FoolException의 예외를 처리해야 하는 대상 : sayNick 메서드 → main 메서드

 

class FoolException extends Exception {
}

public class Sample {
    public void sayNick(String nick) throws FoolException {
        if("바보".equals(nick)) {
            throw new FoolException();
        }
        System.out.println("당신의 별명은 "+nick+" 입니다.");
    }

    public static void main(String[] args) {
        Sample sample = new Sample();
        try {
            sample.sayNick("바보");
            sample.sayNick("야호");
        } catch (FoolException e) {
            System.err.println("FoolException이 발생했습니다.");
        }
    }
}

 

sayNick 메서드에서 처리 vs  main 메서드에서 처리 ☜

  얜 다 실행 됨                              얜 두번째 문장이 실행 X 

                                                     왜냐면 첫번째 문장 예외 발생 : catch 문으로 빠져버리기 때문

 

<트랜잭션>

트랜잭션 : 하나의 작업 단위

 

 

모두 취소하는 행위 : 롤백 

데이터 정합성 : 데이터들의 값이 서로 일관성 있게 일치하는 것

 

상품발송() {
    포장();
    영수증발행();
    발송();
}

포장() {
   ...
}

영수증발행() {
   ...
}

발송() {
   ...
}

 

쇼핑몰 운영자는 ‘포장’, ‘영수증발행’, ‘발송’이라는 3가지 작업 중 1가지라도 실패하면 모든 작업을 취소하고 싶어함

 

 

트랜잭션 처리 방법 : 포장, 영수증발행, 발송 메서드에서는 각각 예외를 던지고 상품발송 메서드에서 던져진 예외를 처리한 뒤 모두 취소 !  

 

상품발송() {
    try {
        포장();
        영수증발행();
        발송();
    }catch(예외) {
        모두취소();  // 하나라도 실패하면 모두 취소한다.
    }
}

포장() throws 예외 {
   ...
}

영수증발행() throws 예외 {
   ...
}

발송() throws 예외 {
   ...
}

 

[7-5 스레드]

 

프로세스 : 한개 일

ㅅㅡ레드 : 두 가지 또는 그 이상의 일을 동시에

 

 

코테 2 번 문제 

<문제>

어떤 단어를 뒤에서부터 읽어도 똑같다면 그 단어를 팰린드롬이라고 한다. 'radar', 'sees'는 팰린드롬이다.

수도 팰린드롬으로 취급할 수 있다. 수의 숫자들을 뒤에서부터 읽어도 같다면 그 수는 팰린드롬수다. 121, 12421 등은 팰린드롬수다. 123, 1231은 뒤에서부터 읽으면 다르므로 팰린드롬수가 아니다. 또한 10도 팰린드롬수가 아닌데, 앞에 무의미한 0이 올 수 있다면 010이 되어 팰린드롬수로 취급할 수도 있지만, 특별히 이번 문제에서는 무의미한 0이 앞에 올 수 없다고 하자.

 

<입력>

입력은 여러 개의 테스트 케이스로 이루어져 있으며, 각 줄마다 1 이상 99999 이하의 정수가 주어진다. 입력의 마지막 줄에는 0이 주어지며, 이 줄은 문제에 포함되지 않는다.

 

<출력>

각 줄마다 주어진 수가 팰린드롬수면 'yes', 아니면 'no'를 출력한다.

<풀이>

import java.util.Scanner;

public class Main {
    // 팰린드롬 수 판별 함수
    public static boolean isPalindrome(String number) {
        int len = number.length();
        for (int i = 0; i < len / 2; i++) {
            if (number.charAt(i) != number.charAt(len - i - 1)) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        while (true) {
            String num = sc.nextLine().trim();
            
            // 입력이 '0'이면 종료
            if (num.equals("0")) {
                break;
            }
            
            // 팰린드롬 수 판별 및 출력
            if (isPalindrome(num)) {
                System.out.println("yes");
            } else {
                System.out.println("no");
            }
        }

        sc.close();
    }
}

 

 
  • public static boolean isPalindrome(String number) {:
    팰린드롬인지 확인하는 메서드
    • public: 다른 클래스에서도 이 메서드를 호출할 수 있게 설정
    • static: 객체를 생성하지 않고도 메서드를 호출할 수 있게 설정
    • boolean: 이 메서드는 true 또는 false를 반환
    • String number: 숫자를 문자열 형태로 받아 팰린드롬 여부를 확인
  • int len = number.length();:
    입력된 문자열 number의 길이 구하기. 길이는 비교 반복문의 범위를 결정하는 데 사용
 
  • for (int i = 0; i < len / 2; i++) {:
    문자열의 앞쪽 절반과 뒤쪽 절반을 비교하기 위해 반복문 사용
    • i는 문자열의 앞부분 인덱스 나타냄
    • 반복은 문자열의 길이의 절반(len / 2)까지만 수행.
  • if (number.charAt(i) != number.charAt(len - i - 1)) {:
    문자열의 앞쪽 문자(number.charAt(i))와 뒤쪽 문자(number.charAt(len - i - 1))를 비교
    • charAt(i): i번째 문자 반환
    • charAt(len - i - 1): 문자열 뒤쪽에서 i번째 문자 반환
    • 두 문자가 다르면 팰린드롬이 아니므로 false 반환
 
  • return false;:
    문자열이 팰린드롬이 아니면 즉시 false를 반환하여 메서드 종료
 
  • return true;:
    반복문이 끝날 때까지 서로 다른 문자가 없으면 팰린드롬이므로 true 반환

 

 
  • public static void main(String[] args) {:
    실행 시작
 
  • Scanner sc = new Scanner(System.in);:
    Scanner 객체를 생성하여 사용자로부터 입력받기
    • System.in: 표준 입력 스트림(키보드 입력) 
 
 
  • String num = sc.nextLine().trim();:
    사용자로부터 한 줄의 입력을 받아 공백을 제거한 문자열로 반환
 
  • if (num.equals("0")) {:
    입력된 문자열이 "0"인지 확인합니다.
    • "0"이면 입력이 종료 조건을 만족하므로 프로그램 종료
 
  • if (isPalindrome(num)) {:
    입력된 문자열 num이 팰린드롬인지 확인
    • isPalindrome(num)이 true를 반환하면 "yes" 출력
 
  • System.out.println("yes");:
    문자열 num이 팰린드롬이면 "yes"를 출력

 

 
  • else {:
    isPalindrome(num)이 false를 반환한 경우 실행

 

 
 
  • System.out.println("no");:
    문자열 num이 팰린드롬이 아니면 "no"를 출력
 
 
  • sc.close();:
    Scanner 객체를 닫아 입력 스트림 해제

 

 
 
 
 

 

반응형