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 해보기?