Java 예외처리 & 입출력API

mijin·2023년 9월 2일
0

Lesson(SeSAC)

목록 보기
4/4

🤍예외처리
-예외처리를 하는 이유는 프로그램을 정상종료하기 위함이다.

  1. try-catch
    예외 발생이 예상되는 부분에 처리하는 방법.
      ArrayIndexOutOfBoundsException(배열길이오류)를 발생시켜 테스트한 코드이다.
    예외발생이 예상되는 코드는 try 속에, 예외 발생 시 실행될 코드는 catch 속에 넣으면 된다.
     정상 종료되는지 확인하기 위해 마지막에 "END" 메시지를 출력하도록 코드를 추가했다.
     catch는 여러번 사용할 수 있는데 위의 예제처럼 아예 Exception 클래스를 사용할 수도 있고, finally라는 예약어를 사용하면 그 구현부는 예외가 있든 없든 항상 실행한다.

  2. throws
    한 마디로 n개의 메서드를 종료시킨다.
     try-catch로 예외처리를 할 수 있지만, 문제가 있을법한 부분마다 try-catch를 할 순 없으니 아예 throws를 사용해 전체적으로 예외를 던져버린다.


 이 예제에서는 이름을 입력받는 메서드에 매개인자가 null이나 문자열 길이가 2자 미만일 경우, 입력을 거절하기 위해 throw를 사용한 것이다.

이 setName 메서드는 오버로딩한 생성자에서 호출되었기 때문에 이렇게 다른 곳에서 사용하기 위해서는 인터페이스부분에 'throws NameMinLengthException'을 명시해주어야 한다. throw는 메서드를 종료해버리는



🤍사용자 정의 예외 처리하기

 NameMinLengthException, PointScoreException라는 예외를 java API에서 본 적 있는 사람은 없을 것이다. 왜냐하면 내가 지어냈기 때문이다. 이런 것을 사용자 정의 예외라고 한다. 전자는 이름을 입력 받을 때 2자 이상만 입력받기 위해, 후자는 포인트를 입력 받을 때 1점 이상만 입력 받기 위해 임의로 예외를 생성했다. 예외를 적용하는 순서는 아래부터 참고하면 된다.

 우선 임의의 예외 이름으로 클래스를 생성하고 Exception클래스를 상속 받는다. 그 후, 예외 발생 시 메시지도 함께 주기 위해 생성자를 오버로딩하여 메시지를 매개인자로 줬다.

 그 후 예외가 발생하는 부분에서 예외처리와 함께 메시지를 매개인자로 주면,

 이렇게 예외 발생 시 메시지와 함께 확인할 수 있다.
Tip) 컴파일 오류는 위->아래 방향으로 읽지만, 예외는 아래->위 방향으로 읽으면 된다.


🤍IO API
입출력 시에는 꼭 예외처리를 해줘야한다.
아래의 API 정보처럼 항상 예외처리를 하도록 되어있다.

입출력 데이터의 기준은 크게 2가지로 둘 수 있다.
하나는 컴퓨터언어, 다른 하나는 사람언어.
-컴퓨터: 기본 단위가 byte(1byte==8bit)-"Byte Stream"
-사람(character): 2byte(==16bit, 유니코드)-"Character Stream"

즉, Input, Output Steam은 1byte,
Reader, Writer는 2byte이다.⭐


Byte Input API
<<'abstract'>>InputStream
←FileinputStream
←ObjextinputSteam
←FilterInputStream←BufferedInputStream
                        ←DataInputStream

Character output API
<<'abstract'>>Writer
←BufferedWriter
←OutputStreamWriter←FileWriter
←FilterWriter

cf. OutputStreamWriter 같은 경우는 "OutputStream"과 "Writer"이 합쳐진 단어이다. 즉, 1byte 정보를 2byte로 변환해주는 역할을 한다.

예제1)
  sisout은 시스템(터미털창)에 출력된다. 혹시 출력결과를 파일로 저장하고 싶으면 System의 설정을 바꿔주면 된다. setOut메서드를 사용하여 PrintStream을 불러와 매개인자로 주고, 또 매개인자로 FileOutputStream을 불러와 파일명을 매개인자로 준다. API 정보를 확인해보면 알겠지만 항상 throws를 통해 예외처리를 해줘야 한다!

예제2) Input
 위의 코드를 실행시켜서 "한글"이라고 입력하면 저 프린트문을 통해서는 어떤 결과가 나올까?

1byte인 것을 2byte char타입으로 캐스팅 해줬으니 재대로 나올까?
 애석하게도 그렇지 않다 ㅎ(이유가 뭐지?)

 짜잔! InputStreamReader를 이용해 2byte로 변환시켜주면?

 (왜 한 글자만 나오지?ㅠ) 글자가 깨지지않고 정상적으로 나온다.
 근데 이러면 input+1의 결과가 궁금할 수 있다. 결과는 아래와 같다.
 (왜?ㅠ)

예제3)
 코드를 이렇게 구성한 이유를 설명하자면, 문자를 입력받는 프로그램은 계속 실행이 되고, exit를 입력했을 때 입력이 종료되며 파일로 문자가 저장되는 프로그램을 구성했고, main메서드에서 최대한 짧은 코드로 구현할 수 있도록 생성자를 오버로딩해줬다. 물론 입출력 시 일어나는 예외처리도 해줬다.

  1. 일단 BufferedReader는 문자열처리 API이다. 이것은 2byte이니까 1byte로 변환하는 API인 InputStreamReader를 사용했고, 시스템에서 입력을 받았다.

  2. 후에 파일로 저장하기 위해 FileWriter를 사용했다.

  3. 입력받은 것을 줄 단위로 인식하는 readLine()을 이용해 출력한다.

  4. 버퍼로 입력이 끝났으면 마지막에 꼭 flush()를 호출해야함. 이것은 내부 버퍼의 내용을 파일에 출력(writer)한다. 만약 호출하지 않으면 내용이 버퍼에만 남고 파일에는 출력되지 않게 됨.

  5. 그리고 중간에 생성자에 예외처리, 그리고 마지막에 main메서드에서 try-catch로 예외처리를 해주면 된다.

profile
가보자고~!

0개의 댓글