본문 바로가기
☁︎KOSTA/☂︎KOSTA-JAVA

[KOSTA] Spring 기반 Cloud 서비스 구현 개발자 양성 (Day 15) - Mini Project exception handling 적용, IO

by 하_센세 2022. 8. 18.

2022.08.18 [THU]

- Day 15- 

 

수업 주요 목차

  • Exception Handling(예외처리) review
  • schoolproject exception handling 적용
  • java.io.File class를 이용한 파일 제어

🤖Review

 

-Exception Handling(예외처리) review

: 프로그램 실행시 예외(exception)가 발생할 때 대처방안/예외흐름을 실행하고 프로그램을 정상 수행

: 예외처리(Exception Handling)를 하지 않으면 즉시 종료

 

 

 Throwable의 자식 클래스 Error & Exception :

  •  Error : 심각한 문제 환경 또는 구조를 개선
  •  Exception : 예외, 프로그램 내부에서 처리

 

try : 예외 발생예상 영역 지정

catch : 예외처리(Exception Handling)

finally : 예외 발생 및 처리여부와 관계없이 항상 실행 (try가 반드시 있어야 함)

throws : 호출한 측으로 예외를 던질 수 있다.(전파할 수 있다.)

throw : 필요시 예외를 고의로 발생시킨다.

 

직접 Exeption을 정의하려면  java.lang.Exception을 상속받으면 된다.

 

Checked Exception: Runtime계열 제외한 모든 Exception으로 compile시 Exception 처리를 체크할 수 있다. (try/catch || throw)

UnChecked Exception: RuntimeException 계열의 Exception으로 따로 throws 명시할 필요가 없다.(자동으로 호출한 측으로 던져짐)

 

🔎 Eclipse 실습 내용

  • System.out.println("A"); -> 코드의 흐름을 확인하기 위해 넣어 놓은 것
  • 입금시 발생가능한 예외처리를 위한 NoMoneyException
package step1;

public class NoMoneyException extends Exception {
	private static final long serialVersionUID = 7448528606571933648L; // IO에서 공부할 예정

	public NoMoneyException(String message) {
		super(message);
		System.out.println("A");
	}

}

 

 

  • AccountService Class
package step1;

public class AccountService {
	public void deposit(int money) throws NoMoneyException {
		try {
			if (money <= 0)
				throw new NoMoneyException(money + "는 잘못된 입금액입니다.");
			System.out.println(money + "입금완료");
			System.out.println("B");
		} finally {
			System.out.println("카드를 돌려줍니다.");
			System.out.println("C");
		}
	}
}
  • 입금액이 0이하일 경우 고의적으로 예외를 발생시키고 User에게 예외를 던진다.(전파한다.)
  • 입금액이 정상 범위일 경우 입력한 금액과 "입금완료" 메세지를 출력한다.
  • try문 실행여부와 관계없이 "카드를 돌려줍니다." 메세지는 언제나 출력된다.

 

  • Test(User) Class
package step1;

public class TestReviewException {
	public static void main(String[] args) {
		AccountService service = new AccountService();
		int money = 100; // 정상흐름
		money = 0; // 예외흐름
		try {
			service.deposit(money);
			System.out.println("D"); // 입금후 후속작업
		} catch (NoMoneyException nme) { // 예외 처리 내용
			System.out.println(nme.getMessage()); // 메시지 반환받아 출력
			System.out.println("E"); 
		} 
		System.out.println("F");
	}
}
  • money가 100일 경우(정상흐름) NoMoneyException이 실행되지 않기 때문에 코드는 B → C → D → F 의 흐름으로 코드가 진행된다.
  • money가 0일 경우(예외흐름) NoMoneyException이 실행되며 A 가 먼저 출력되고 그 이후로 C → E → F 의 흐름으로 코드가 진행된다.

SchoolProject Exception Handling 적용 (List 사용)

 

1) Member(abstract), Student, Teacher, Employee class 생성 (Day7 참고)

2) SchoolService class 생성

package model.service;

// Service : business logic 담당 객체
import java.util.ArrayList;

import model.exception.DuplicateTelException;
import model.exception.MemberNotFoundException;
import model.vo.Member;

public class SchoolService {
	private ArrayList<Member> list = new ArrayList<>();





}

이렇게 만들어준 뒤 SchoolService 블록 안에다가 method들 만들어주면 된다.

  •  findIndexByTel (강사님이랑 같이 한 것)
public int findIndexByTel(String tel) {
	int position = -1;
	for (int i = 0; i < list.size(); i++) {
		if (tel.equals(list.get(i).getTel())) {
			position = i;
			break; // jvm을 도와주는 것
		}
	}
	return position;
}
  • addMember
public void addMember(Member member) throws DuplicateTelException {
	boolean flag=false;
	for(int i=0;i<list.size();i++) {
		if (member.getTel().equals(list.get(i).getTel())) { 
			flag=true;
			throw new DuplicateTelException(member.getTel() + " tell은 중복되는 번호로 등록 불가합니다.");
		}		
	}
	if(flag==false)
	list.add(member);		
}

가장 처음에는 위에 코드처럼 for문을 사용해서 i를 사용하려고 하다가 점심시간이 다 되어서 중간에 멈추고(저렇게 완성되기 전!/ boolean을 안썼었음!) 밥을 먹으러 가던 중 조원에게 if조건 안에 뭐라고 이렇게 쓰면 되냐고 물어봤더니 findIndexTel에 대해 얘기해주셨다. 밥 다 먹고 돌아와보니 간단하게 findIndexTel을 통해 얻게 된 i의 값과 -1을 비교하면 굳이 for, if 구구절절 쓰지 않아도 해결이 가능했다.

public void addMember(Member member) throws DuplicateTelException {
	if (findIndexByTel(member.getTel()) != -1) { // for if 쓰다가 조원의 힌트로 바꿈
		throw new DuplicateTelException(member.getTel() + " tell은 중복되는 번호로 등록 불가합니다.");
	}
	list.add(member);
}

나는 위에 코드로 짰는데 조원들이 else얘기를 하길래 else가 없어도 돌아가지 않냐고 물어보니 다들 안된다고 그래서 혼란에 빠질뻔하다가 비교해본 결과

public void addMember(Member member) throws DuplicateTelException {
	if (findIndexByTel(member.getTel())==-1) { //for if 쓰다가 조원의 힌트로 바꿈
		list.add(member);
	}  else {
		throw new DuplicateTelException(member.getTel() + " tell은 중복되는 번호로 등록 불가합니다.");	
		}
}

나는 !=를 썼었고 조원들은 ==을 썼었다. ==을 쓰게 되면 throw ~코드를 else로 묶어줘야 정상작동된다. (왜지....) 그리고 아래 나머지는 혼자서 어떻게 어떻게 해보니 결과가 맞게 나왔다.

  • printAll
public void printAll() {
	for (int i = 0; i < list.size(); i++) {
		System.out.println(list.get(i));
	}
}
  • findMemberByTel
public Member findMemberByTel(String tel) throws MemberNotFoundException {  // 중복되면 찾아줘야 하는데 중복되면 없습니다! 라고 해서 에러났었음 순서 바꿔주니 ok
		Member member = null;
		if (findIndexByTel(tel) != -1) {  // != -> not equal to
			member = list.get(findIndexByTel(tel));
			return member;
		}
		throw new MemberNotFoundException(tel + "에 해당하는 구성원 정보가 없어 찾을 수 없습니다.");
}
  • deleteMemberByTel(중복이 있으면 후속작업이 진행되는 것이라서 맨 처음에 !=로 썼더니 오류가 났었음)
public void deleteMemberByTel(String tel) throws MemberNotFoundException {
	if (findIndexByTel(tel) == -1) {
		throw new MemberNotFoundException(tel + "tel에 해당하는 구성원 정보가 없어서 삭제 불가합니다.");
	}
	list.remove(findIndexByTel(tel));
}
  • updateMemberByTel
public void updateMemberByTel(Member member) throws MemberNotFoundException {
	if (findIndexByTel(member.getTel()) == -1) {
		throw new MemberNotFoundException(member.getTel() + "tel에 해당하는 구성원 정보가 없어서 수정 불가합니다.");
	}
	list.set(findIndexByTel(member.getTel()), member);
}

 

 


 

🔎 Eclipse 실습 내용

 

1. Error

package step2;

class ErrorDemo{
	public void a(int i) {
		System.out.println(i);
		b(i);
	}
	public void b(int j) {
		System.out.println(j);
		a(j);
	}
}
public class TestError {
	public static void main(String[] args) {
		ErrorDemo demo=new ErrorDemo();
		demo.a(7);
	}
}

7 계속 반복하다가 Error(StackOverFlow)

 

 

2. ConsoleIO 1

 

원하는 출력결과

**불금메뉴**
 메뉴를 입력하세요: 고구마
 고구마주문성공!
 메뉴를 입력하세요: 요거트
 요거트주문성공!
 메뉴를 입력하세요: 사과
 사과주문성공!
 메뉴를 입력하세요: 주문끝
 ***메뉴 주문이 완료되었습니다.***
더보기

 힌트:

while(true){
   if(비교)
   break;

package step3;

import java.util.Scanner;

public class TestConsoleIO1 {

	public void view() {
		Scanner scanner=new Scanner(System.in);
		System.out.println("**불금메뉴**");
		while(true) {
			System.out.print("메뉴를 입력하세요: " );
			String data=scanner.nextLine();
			if(data.equals("주문끝")){
				break;
			}
			System.out.println(data+"주문성공!");	
		}
		scanner.close();
		System.out.println("***메뉴 주문이 완료되었습니다.***");
	}
	
	public static void main(String[] args) {
		new TestConsoleIO1().view();
	}
}

System.out.println(data+"주문성공!"); ->  위치는 while에 들어갈 수는 없는 것인가...? 나는 while문 안에 같이 넣어줬어서(결과는 같았음!) 궁금했으나 질문하지 못했다.. 월요일에 여쭤봐야지!

 

3. ConsoleIO 2

package step4;

import java.util.Scanner;

	public class TestConsoleIO2 {
		public void show() {
			Scanner scanner=new Scanner(System.in);
			while(true) {
				System.out.println("***주종을 선택하세요 1.맥주 2.소주 3.막걸리 4.종료***");
				String data=scanner.nextLine();	
				if(data.equals("1")) {
					System.out.println("맥주를 선택하셨습니다");
				} else if(data.equals("2")) {
					System.out.println("소주를 선택하셨습니다");
				} else if(data.equals("3")) {
					System.out.println("막걸리를 선택하셨습니다 ");
				} else if(data.equals("4")) {
					System.out.println("***주문 프로그램을 종료합니다***");
					break;
				} else {
					System.out.println("잘못된 입력값입니다. (1~4까지만 가능)");
				}
			}
			scanner.close();
		}
	public static void main(String[] args) {
		new TestConsoleIO2().show();
	}
}

 

 

 

// 오늘의 단축키

cmd+shift+f => 코드정렬

 

//오늘의 질문

 try문 안에 여러 코드를 넣어주고 예외가 발생하고난 뒤 이어지는 코드들을 진행시킬 수 있는 방법은 없나요?

  ㄴ 이 후 진도

 

!=(not equals to), ==(equals to) 쓸 때 else를 써야하고 안써야하고 왜 그런건지?

 ㄴ else로 exeption 코드를 묶어준 이유는 if가 실행이 되고 else가 없으면 무조건 이어져서 실행이 되기 때문에 모 아니면 도 느낌으로 묶어줘야 한다.

 

//오늘의 숙제

복습+ConsoleIO 2 switch문으로 해보기+int data로 해보기

extra) Map version으로 Exception 처리해보기+refactoring 해보기?