본문 바로가기
비전공자의 코딩 일지/학원 수업 정리

코딩 학원 14일차 Java (예외 처리, 유용한 클래스)

by Hoder2 2022. 6. 25.

어제 강사님이 말씀 하셨던대로 오늘은 예외처리에 대해 배웠다.

 

-Exception Handling (예외 처리)

 

학원 대면수업을 나오는 사람들과 회식을 하게 되었는데 이 학원을 다니고 나서 현업에서 일하시는 분들 또한 초청? 느낌으로 같이 회식을 하게 되었다. 나는 사정이 있어 못 가지만 아무튼 인당 회비 구하는 프로그램을 만들란다.

총 회비 금액을 정하고 참여 인원수를 넣으면 1인당 회비가 XXXX원 이라는 값이 나오게 만들라 하셨다.

(객체지향은 잠시 접어두고)

그리고 여기서 만약 참여인원수에 0을 입력하게 된다면 0으로는 나누기가 안 되기에 에러가 발생한다.

이런 것 처럼 프로그래머가 만든 프로그램 자체에는 문제가 없지만 이용자가 프로그램을 사용할 때 발생할 수도 있는 에러사항을 처리 하는 것이 예외 처리고 이때 try, catch를 이용한다.

try 안에는 문제가 발생할 수도 있는 소스를 집어넣고
catch에는 try를 실행할 때 문제 발생 시 실행할 소스를 넣는다.

 

그런 다음 회식 장소를 어디 갈지 투표하는 것도 넣어보라 하셨다.

근데 여기서도 3 이상을 입력하면 에러가 발생할 것이다.

catch를 더 추가해서 사용하면 된다.

 

그런데 이런 친절한 방법 말고 아 씨 똑바로 쓰라고 느낌으로 하고 싶다면?

(종류 구별 안 하고 한방에 잡고 싶을 때)

catch 안에 그냥 Exception을 넣으면 모든 에러 상황이 싸그리 잡혀서 쫌이 출력된다.

그런데 이렇게 하면 개발자야 편하겠지만 뭐가 문제인지 모르게 된다.

그래서 이렇게 사용한다. 

"그리고 finally는 예외가 터지든 말든 무조건 실행 되는 영역, 같은 소리하고 있네 이게 뭔 말도 안 되는 소리야 이러니까 책이 개판이라는 겁니다. 그냥 밖에 빼놓으면 되지" 라고 하시면서 객체 지향적으로 새출발을 하잖다.

이렇게 만들었다면 이제 예외 처리를 해보자.

-989는 메소드가 int라서 return 값을 줘야하기에 대충 넣은 것이다.
그리고 계산이 정상이든 비정상이든 계산 끝을 출력하기 위해 catch 밖에 계산 끝 출력을 써준다.

그럼 당연히 return이 위에서 다 끝났기에 에러가 발생한다.
이때 써주는 것이 finally다.

finally의 정확한 의미는 예외가 터지든 말든 무조건 실행되는건 맞는데 return 보다 먼저 실행 되는 것이다. 그러니까 아무 때나 쓰는게 아니고 중간에 return이 있을 때 쓰는 것이란다.

 

예외 처리(Exception Handling)
1. 직접 처리[대응방법 까지] (위의 우리가 한 방법)
2. 미루기 [대응방법은 사용하는 쪽에서]

throws ArithmeticException을 메소드 만들 때 붙혀주면
이 메소드 실행하다가 ArithmeticException이 터지면 호출한 쪽에서 해결하는 방법이다.

 

우리들은 아마 1번을 쓸 것이란다. '어딜 버릇없이 미루려고' 라고 생각하면 아마추어적인 생각이란다. 우린 2번을 쓰게 될 것이라고  하셨다.

위 프로그램을 만들어놓았는데 나중에 다른 사람이 쓰고 싶다 해서 만들어놨던걸 줘서 쓰는 아무튼 이ㄹ럴 때 1번으로 줘버리면 변경을 못하고 모든 이용자에게 같은 오류문구를 보여주게 된다.
그런데 2번으로 줬을 때는 상사 같은 사람들이 직접 그걸 유동적으로 만질 수가 있기 때문에 우린 보통 2번을 이용하게 될 것이다.

 

이제 본격적으로 파트 3 유용한 클래스로 넘어간다.

 

일단 데이터 관련한 것을 알려주셨다.

가장 먼저 우리가 매번 써왔던 String은 사실 문자열 객체이다.

원래 String의 전통 문법은 이렇게 쓴다.

그러면 저 s 문자열의 3번째 글자를 출력해보라 하셨다.

그 외에도 여러 문제들을 내주셨는데

한 3개 정도는 내가 푼 것 같다. 어제 Robot 다룰 때도 대강 영어로 이거일 것 같은데? 싶은 것들 따라 쓰는 마냥 위에도 그렇게 직접 기능을 찾아내서 하는 식으로 실습을 했다. 근데 그냥 영어 잘했으면 쉽게 풀었을 것 같았다.

 

우리가 언제까지고 콘솔창을 쓸건 아니니 형식을 지정해서 문자열 객체를 생성하는 법을 알려주셨다.

우리가 매번 써왔던 printf와 같은 기능이다.

나중에 게임 비슷한걸 만들어 볼 때 이미지를 불러와야 하는 경우가 있으니

hero_kick_01.png ~ hero_kick_12.png 까지 출력[printf 말고]  이거를 해보라 하셨다.

반복문으로 생각보다 쉽게 만들 수 있었다.

이 위에 것도 하라고 하셔서 했는데 내가한 방식이 아닌 s값 자체를 바꾸는 식으로 String을 할 때 =, concat을 쓰게 되면 객체를 하나 더 생성하는 꼴이 되기 때문에 객체 만들고 주소 바꾸고 번지 새로 생성하고 원래 번지 없어지고 이 과정을 거치게 되는데 빅데이터 다룰 때는 컴퓨터 터진단다.

그래서 대량으로 문자열을 결합해야한다면 StringBuffer를 이용해야 한다.

(StringBuffer는 수정이 가능한 문자열 객체이고 append는 문자를 뒤에 붙히는 메소드이다.)

그럼 문자열 분리는 어떻게 할까?

빅데이터 하겠다고 어딘가에서 문자열을 받아오면 대부분 String으로 되어 있는데 말이다.

정형 데이터 같은 경우 몇 번째에 있는 거 빼네서 따로 쓸 수 있지만 비정형은 그게 될까? 3번째 데이터가 뭔데?

정형 데이터는 split을 이용해서 , 기준으로 배열을 생성해서 값을 뽑아올 수 있다.

비정형 데이터 같은 경우 StringTokenizer을 이용해서 스페이스바를 기준으로 문자를 떼어낼 수 있다. 프린트를 많이 해놓은건 하나씩 떼어져서 나오기 때문이다.

반복문을 통해 끝까지 출력하는 방법이 있다.

 

다음 주제로 넘어가자 하셨다.

 

우리가 기본형 변수를 쓰게 되면 stak영역에 값이 생성되는데 이게 heap영역에 생성해야 되는 경우가 생긴다.

기본형의 객체형 : wrapper class 라고 부른다.

이런식으로 모든 기본형 변수에는 이걸 객체형으로 바꿔주는 서포터가 존재한다.

이런식으로 갔다가 다시 올 수도 있다.

보면 노란줄이 쳐지면서 중간선으로 기분 나쁘게 줄을 그어주는데  이것을 deprecated라고 한다.

 

deprecated는 지금 현재 버전에서는 작동이 되나 현시점에 안 맞아서 바꿀 계획이니 다음 버전에서는 없어져도 토 달지 마라.(유예기간) 그러니까 신제품 써라 같은 말이란다. 또 덧붙히신 말이 제발 책 보고 뭐 외우지 말라며 언제 없어질지도 모르는 것들 외워서 뭐하냐고 하셨다.

 

또한 우리가 위에서 했던 wrapper class 방식이 책에 나오는 내용들이고 다 옛날 얘기란다.

이렇게 하면 되며 이걸 autoboxing, autounboxing이라고 하셨다.

 

그리고 아까 말씀하신 것 처럼 어디선가 값을 받아오면 대부분 String인데

이렇게 숫자도 String으로 받아진단다.

그럼 우리가 이 데이터를 가지고 값을 구하려면 String을 int로 바꿔야 하는데 바로는 불가능하다.

그래서 위 처럼 String을 parse를 이용해 Integer로 바꾼 다음 그걸 또 int로 다시 바꾸는 방법을 써야한다. 그래서 마지막 값은 30이 출력 된다.

위 내용을 이렇게 간추릴 수 있다.

그런데 숫자를 글자로 바꾸는 작업은 그냥 + " "를 하면 되고 마지막 값은 55가 출력 된다.

아까 배운 format으로도 가능하다.

 

진도는 이 정도면 됐고 회식비 계산 프로그램 2를 만들어보잖다.

먹은거[xxx/xxx/xxx/...] : 10000/20000/30000
입력하면 60000 나오게

입력 받은 값을 /를 기준으로 split을 통해 뜯어내서 배열로 만든다.
for문을 통해 배열로 만들어진 문자 ss를 int로 바꿔준 값을 0의 값을 가진 변수 a에 더해줌 혹시나 오류가 발생하더라도 catch에 아무것도 안 썼기에 그냥 넘어가고 다음거 반복한다.(글자를 넣어도 에러가 안 나오고 넘기고 다음 숫자를 받는다.)

 

날짜에 관한 것

Date now = new Date();
원래라면 주소를 출력해야 되지만 Java의 센스로 현재 시간 날짜를 출력해준다.

이런식으로 값을 뽑을 수 있는데 저 노란줄에 마우스 갖다대면 아까 나온 deprecation이 뜬다.

값도 이상하게 출력된다.

Date는 Java 초창기(2000년대를 고려하지 않던 시기)에 만들어진 클래스이고

저게 현시점에는 맞지 않는다. -> 현시점에 맞춰야한다.

그 신버전이 이것이다. 우리가 잘 아는 y, d, M, h, s 등의 패턴으로 값을 입력 가능하다.

이런식으로 format을 하고 출력을 해야 주소값이 안 나오고 위의 now처럼 값이 잘 나온다.

그럼 특정 시간이나 날짜를 출력하고 싶다면?

1. String에 년월일 등 값을 넣어주고
2. 심플데이트포멧으로 내가 쓴 값의 의미를 알려주고
3. 다시 String으로 변환 시켜 출력한다.

 

이런식으로 내가 태어난 요일을 구하자면

내가 태어난 날짜를 String으로 넣고 Date 값으로 변환한 다음 거기에 있을 요일 값만 뽑아서 String으로 변환 후 출력.

 

다음은 한국 나이 구하기다.

그리고 조금 어렵게 가보자 하셨다.

 

과자정보[이름/유통기한/가격/중량] :  새우깡/20220501/1000/500
위 입력하면
----------------
이름 : 새우깡
유통기한 : 2022/05/01/수
가격 : 1000원
중량 : 500g
g당 가격 : 2원
먹으면 (죽음 or 괜찮음)

 

이런식으로 나오게 말이다.

마지막 유통기한 판정에서 학생들 다 같이 머리를 싸매다가
/를 다빼고 yyyyMMdd를 다 붙혀서 인트로 바꾸고 날짜를 비교하면
>, < 비교를 할 수 있는걸 발견해서 "와 개 지렸다" 하고 썼는데
막상 강사님이 하시는거 보니 그냥 날짜 비교해주는 서포터가 있어서 "아..? 더 편한게 있었네" 했다.

현재 날짜 데이트를 생성하고 아까 스플릿으로 나눴던 배열 중 유통기한에 해당하는 문자를 데이타로 바꿔준 뒤 before 서포터를 이용해서 삼항연산을 한 문장인데 훨씬 간결해졌다.


해석하면 now - 현재 날짜가 exp - 유통기한 이전이면 먹어도 됨 아니면 먹지마 이다.

 

이제 다시 이걸 럭셔리 하게 객체지향으로 가보자 하셨다.

오늘은 금요일인데도 집중도 잘 되고 뒤처지는 것 없이 잘 따라올 수 있어서 좋았다.