날아라쩡글이의 블로그입니다.

사용자 정의 예외 처리 , 앞으로 코딩 작성 방법(맨 밑) 본문

중앙 HTA (2106기) story/java API story

사용자 정의 예외 처리 , 앞으로 코딩 작성 방법(맨 밑)

날아라쩡글이 2021. 10. 13. 20:51
반응형
  • 필요에 따라서 try~catch문의 예외처리를 할 수 있다. 
  • 강제 예외 발생시키기 
    • 새로운 예외를 발생시키는 것
  • 예외 변환하기 
    • 발생한 예외를 try ~ catch하고 다른 예외를 발생시키는 것.
  • User의 class를 정의 한다. 
  • UserManager class을 작성한다. 
  • private로 List<User> userList =  new ArrayList<>(); 입력받을 User ArrayList를 작성하고, 
  • public method를 입력한다. 반환타입은 없는 void로 입력했다. 
  • for문으로 User userList에 입력된 값을 출력하고, 
  • if문으로 getId()가 동일한 경우
    • throw new RuntimeException(아이디 중복 (원인작성));
  • if문으로 getName()이 동일한 경우를 입력한다. 
    • throw new RuntimeException(이름 중복(원인 작성)); 
  • 아이디와 이름이 중복된 상황을 확인했고, 예외가 발생하면 해당 메소드는 즉시 실행이 중단되게 만들었다. 
  • throw new RuntimeException()으로 빠른 종료와 같은 효과를 냈다. 
  • 여기서 throw가 되지 않는다면, userList.add(user);로 
  • userList객체에 User객체를 저장하는 수행문을 입력을 하였고, 이 수행문이 실행되기 위해서는 for문의 예외 강제로 발생시키는 수행문이 절대로 수행되지 않아야 가능하다. 
  • 그리고 main class로 가서 User user1 = new User("입력id" , "입력name");으로 객체를 생성해주고, 
  • UserManager usermanager = new UserManager();로 메소드를 수행할 객체를 new연산자로 생성하였다. 
  • try{
    • 실행할 문장을 입력하였다. 
    • 오류가 발생시켜 RuntimeException으로 아이디 중복으로 인한 오류임을 확인할 수 있었다.
    • 오류가 발생되지 않으면 수행될 문장이다. 오류가 발생되는 수행문 바로 즉시 중단하고 catch문으로 들어간다.
    • }
  • catch(RuntimeException ex) {
    • System.out.println(ex.getMessager()); // 오류메세지를 반환한다.
    • ex.printStackTrace(); // 예외가 발생한 수행문 정보를 출력한다. 
    • }
      • catch블록이 실행됨으로 
      • -addNewUser(user) 실행이 실패한 것을 확인 할 수 있다. 
      • -오류 메세지가 포함된 예외객체를 확인했다. 
      • +getMessage()메소드로 오류에 대한 상세한 정보를 획득할 수 있다. 
      • +void printStackTrace();메소드로 오류가 발생한 수행문을 확인 할 수 있다. 
      • 오류의 원인도 알아차릴 수 있고, 어디에서 난건지 확인 할 수 있다. 
  • 예외 강제 발생시키기 
    • 어플리케이션을 개발할 때 예외를 강제로 발생시킬 수 있다. 
    • 예외 강제 발생 상황
      1. 업무 로직에 위배되는 경우 
        • 동일한 아이디를 가진 사용자가 등록되는 것
        • 로그인처리시 비밀번호가 맞지 않는 것
        • 출금 금액보다 잔액이 부족한 경우 
      2. 유효한 입력값이 아닌 경우 
        • 아이디가 빈 문자열인 것 
        • 이메일 형식이 아닌 이메일 주소
        • 값의 범위를 넘어가는 값
        • 제시된 항목이 아닌 항목의 값(ex)성별인데 동물을 작성했다)
    • 예외 강제 발생시키기 
      • throw new 예외클래스 ();
      • throw new 예외클래스 (오류메세지);
      • throw new 예외클래스 (오류메세지, 예외원인); //예외원인은 다른 예외 객체다.
  • 등록/성공/실패 여부를 반환값으로 확인할 경우 , 실패에 대한 자세한 이유를 알 수 없다. 
  • 사용자 중복 저장되는 경우를 오류로 확인할 수 있다. nullPointException등 프로그래밍적인 오류가 아닌 업무로직 오류도 오류로 확인 할 수 있다. 
  • 코드에는 오류가 없고, 내가 의도한대로 프로그램이 동작하지 않는 경우 : 업무 로직 오류
  • 업무로직에 맞지 않는 경우 예외 강제 발생으로 오류에 대한 상세한 정보를 호출한 측에게 전달하는 것이 중요하다.

throws = 예외 위임하기 

throw = 예외 던지기 ---> 구별하는 것이 중요하다. 

  1. true, false보다 다양한 결과를 보낼 때
  2.  예외객체를 이용하여, error 메세지를 전달하고, 어떤 원인인지 알려줄 수 있다. 

프로그램 구현에서 오류사항에 예외 발생시키는 것을 가장 많이 사용한다. 

빠른 종료 

  1.  return  : 수행문이 실행되고 마는 것
  2.  throw new 예외클래스 : 빠른 종료처럼 사용함 
    • 어떤 원인으로 예외가 발생된건지 알려줄 수 있음
    • 좀 더 빠르게 오류사항을 파악함 
    • 위치 파악을 할 수 있음

반환타입 따른 설정 방법 

  • 직원번호를 전달 받아서 직원 정보를 반환한다. 
    • 직원정보, 직원 번호에 해당하는 사원이 존재하지 않으면 null을 반환한다. 
    • employ의 주소값을 받을 참조변수를 설정하여, 해당 객체를 찾으면 break;하고 
    • return으로 참조변수를 보내는 방법 
    •  
  • 직원번호를 전달받아서 직원 정보를 반환한다. 
    • 직원정보, 직원 번호에 해당하는 사원이 존재하지 않으면 null이 반환한다. 
    • 해당하는 employee 객체를 찾으면 return으로 employee하는 방법, 그리고 없다면 return null하는 방법이 있다. 
    •  

  • 직원 번호를 전달받아서 직원정보를 반환한다. 
    • Exception 직원번호에 해당하는 직원이 존재하지 않으면 예외가 발생한다. 
    • for문안에 구현된 if문의 조건식이 true로 판정되는 경우가 한번도 없으면 직원 번호에 해당하는 직원정보가 없는 경우이고, 직원정보가 반환되지 않는다. 직원번호에 해당하는 직원정보가 존재하지 않을 때만 아래의 수행문이 실행되고, 예외 객체가 강제 발생된다. 
    • for문의 해당하는 employee객체를 찾으면 return하고 없으면 throw new Exception();을 준다. 
    • 예외처리를 체크하는 예외가 발생한다. 
    • throw 키워드를 사용하여, 강제 발생시킨 예외를 이 메소드를 호출한 측에게 전달한다. 

      • 직원번호를 전달 받아서 직원 정보를 반환한다. 
        • 직원정보, 직원 번호에 해당하는 사원이 존재하지 않으면 RunTimeException이 발생한다. 
        • for문을 이용하여 해당객체가 있으면 return employee를 진행하고  없으면 throw new RuntimeException()을 진행한다. 
        • 컴파일러가 예외처리 여부를 체크하지 않는 예외가 강제 발생한다. 
        • throw키워드를 사용해서 강제발생시킨 예외를 이 메소드를 호출한 측에 전달해도 되고, 하지 않아도 된다. 
        • main메소드로 올라가서 null 값이 반환되는 emp1, emp2의 경우 null이면 직원 정보가 존재하지 않는다고 println이 되도록 작성한다. 
        • 직원 번호로 조회했을 때, 직원정보가 반환되거나 예외가 발생하는 경우에는 
        • emp3의 경우 컴파일러가 예외처리 유무를 확인하기 때문에 try catch문을 사용하여 처리해준다. 
        • try부분에 employee emp3에 출력값을 넣고 catch(Exception ex)로 throw new Exception을 반환을 받아서 오류가 나면 실행할 실행문을 입력한다. 
        • 예외처리 여부를 체크하지 않는 예외가 발생할 경우 return값에 RuntimeException으로 뜨지 않고, 사용자에게 error페이지를 직접적으로 보여줄 예정으로 따로 try catch를 입력하지 않아도 된다. 
  • 반환타입이 void가 아니면 반환타입의 값(반환한다. ), 예외를 발생시키는 방법(반환하지 않는다. ) 
  • 둘 중에 하나는 가지고 있어야한다. 

자바에서 가지고 있는 예외가 내장된 라이브러리를 사용한 것이다. 

  • 예외 클래스의 이름은 어떤 예외를 발생한 것인지 나타내기도 한다. 
  • PasswordMismatchException : 비밀번호에 matching되는 것이 없다. 
  • UserAlreadyExistsException : 사용자가 존재하지 않아서 생기는 예외 
  • UserNotFoundException : 사용자가 찾아지지 않아서 생기는 예외
    • 내가 클래스를 만들 수 있다. 
    • 이것이 사용자 정의 예외, 개발자 정의 예외 이다. 

사용자 정의 예외 

  • 사용자의 예외 클래스는 2가지로 만들 수 있다.
    • checked 예외 클래스 
      • Exception클래스를 상속받아서 사용자 정의 예외 클래스를 만든다. 
      • 예외 처리 (try catch)가 필수이다. 
      • 컴파일러에서 예외처리를 확인한다. 
    • unchecked 예외 클래스 
      • RuntimeException 클래스를 상속받아서 사용자 정의 예외 클래스를 만든다. 
      • 예외 처리가 필요없다. 
      • 컴파일에서 확인하지 않는다. 
      • 현재는 대부분 unchecked예외를 선호한다. 

예외 객체의 메소드, 상속

  • 예외 메세지를 출력하는 것 getMessage()
  • 화면에 에러 수행문만 전달하는 것 printStackTrace(); 
  • super부모 생성자로 값을 전달, 전달함
  • 예외 중요 클래스는 throwable에서 전부 상속받고 전달한다. 

예외 클래스의 주요 API

  • Throwable에서 상속받고, 생성자만 입력한다고 앞에서 작성했다. 
    • 주요 생성자 
    • public Throwable(){} //기본생성자
    • public Throwable(String message){ super(message)} //오류와 관련된 메세지를 전달받는 생성자
    • public Throwable(String message, Throwable cause){super(message, cause)} 
      • 오류와 관련된 메세지 및 오류의 원인이 되었던 이전 예외 객체를 전달받는 생성자 
    • 주요 메소드 
    • Throwable getCouse() 
      •  오류발생의 원인이 되었던 오루를 반환한다. 
  • String getMessage() 
    • 오류와 관련된 상세한 메세지를 반환한다. 
  • void printStackTrace()
    • 오류 발생과 관련되어서 실행되었던 코드를 화면에 출력한다. 
  • void printStackTrace(printStream s) -->오버로딩된 printStackTrace()
    • 오류 발생과 관련되어서 실행되었던 코드를 화면이 아닌 다른 곳에 출력하게 할 수 있다. 
  • void printStackTrace(printWriter s) --> 오버로딘된 printStackTrace()
    • 오류 발생과 관련되어서 실행되었던 코드를 파일에 출력 가능하게 할 수 있다. 

사용자 정의 예외 함수 작성하기 

  • 첫 예제의 경우 내부클래스로 작성하였다. 
  • 내부클래스는 거의 사용하지 않는다. 
  • 일반적으로 별도의 클래스를 만들어서 작성해야한다. 
    • User의 VO를 작성하였다. (매개변수, getter/setter)
    • 사용자 정의 예외 클래스인 예외처리를 모두 입력할 CustomException extends RuntimeException을 만들었다. 
      • 사용자 정의 예외 클래스로 입력하였고, 
      • 내부 클래스로 만들었기 때문에 static으로 입력하였다. 
      • RuntimeException클래스나 Exception클래스를 상속받아서 만들 수 있고, 
      • 사용자 정의 예외 클래스를 정의할 때에는 주로 부모의 생성자 메소드를 호출하는 생성자 메소드를 정의하는 것이 일반적이고, 특별한 경우를 제외하기 때문에 
      • 기본 생성자 메소드 
      • 오류메세지를 인자로 전달받는 생성자 메소드 
      • 오류발생의 원인이 되는 다른 오류를 받는 생성자 메소드 
      • 오류메세지와 오류 발생의 원인이 되는 다른 오류를 전달 받는 생성자 메소드를 입력하였다 
    • UserService를 작성하였다. 
      • ArrayList<>()의 형태로 List가 받고, User의 객체의 타입을 입력하는 collection배열을 작성하였다. 
      • 원래는 웹서버에서 처리하는 User loginUser = null; 값도 입력하였다. 
      • 메소드를 만들어서 
        • 아이디를 전달받아서 해당 사용자 정보를 반환하는 메소드를 먼저 입력하였다. 
          • 향상된 for문으로 입력하였고, 사용자 정보가 없으면 null을 반환했다. 
          • public User getUserById() 
        • 새 사용자 정보를 등록하는 기능 , 같은 아이디를 사용하는 사용자가 존재하는 경우 예외를 발생
          • 아이디를 전달받아서 아이디가 중복되면 throw new CustomException("출력될 메세지를 입력");을 이용하여 값을 반환한다. (사용자 정의 예외처리를 호출한다. )
          • 예외를 발생시켜서 빠른 종료를 처리했다. 
        • 아이디와 비밀번호를 전달받아서 로그인처리를 생성하는 메소드를 입력하였다. 
          • 아이디와 비밀번호가 다르면 예외처리를 발생시킨다. (사용자 정의 예외처리를 호출한다.) 
          • 전부 통과하면 loginUser변수에 로그인된 사용자의 정보를 입력하여, 로그인처럼 만들었다. 
      • main 메소드를 입력한다. 
      • Scanner scan = new Scanner(System.in);
      • UserService service = new UserService();으로 로직구현한 것을 호출하였다.
      • 예외 메세지의 경우 통일 되어 있기 때문에 하나의 클래스와 메소드를 이용하여 일괄처리하는 편이 좋다. 
      • 원인도 담을 수 있고, 정보 표시작업을 표현 할 수 있다. 
      • 에러페이지를 예외 일괄처리 하고, 예외 일괄 처리에서 전송 후 브라우져에서 에러페이지를 출력하기 때문에 훨씬 더 경제적이다. 
      • 그렇기 때문에 main에서도 일괄처리를 진행할 예정이다. 
      • 1번과 2번에서 오류가 발생하기 때문에 
      • while(true) 바로 아래에서 try로 묶고 while문이 출력되는 모든 곳을 묶고 
      • catch(CustomException ex) {
      • System.out.println("오류 :" +getMessage());으로 입력한다. 
      • } catch(사용자 예외 처리)로 입력하여 한곳에서 처리하도록 입력했다 
        • 예외 일괄처리의 경우 예외의 종류가 1가지여야한다. 
      • 사용자 정의 예외처리가 필요한 경우는 
        • 한 종류로 처리 할 수 있기 때문이다. 

예외 처리 하기 

  1. 처리할 예외 클래스의 종류를 적게 만든다. 
    • 사용자 정의 예외 클래스를 정의하자 
    • 업무 로직 오류 발생시 사용자 정의 예외 객체를 강제 발생시킨다. 
    • 자바가 발생 시키는 예외는 사용자 정의 예외 객체로 전환한다. 
    • 처리할 예외 클래스가 줄어드는 효과가 있다. 
    • 많이 사용하는 방법이다. 
    • 일반적인 exception이 발생한 경우 inputMisMatchException이 발생한 경우 
      • try로 묶고 catch (inputMisMatchException ex) {
      • throw new CustomException("입력 값이 올바르지 않습니다. ");
      • 묶어버리고 사용자 예외 함수로 보내버린다. 
      • 이것이 예외의 전환, 변환 이라고 한다. 
        • 내가 만든 예외가 발생하게 한다. 
        • 일반 예외 catch하고, 내가 만든 사용자 정의 예외 처리를 throw한다. 
  2. 실제 업무 로직에서 발생하는 예외들은 스스로 처리하지 말고 한 곳에서 일괄 처리 시킨다. 
    • 오류 메세지 출력
    • 디버깅 정보 출력
    • 로그 파일에 오류 내역 기록
    • web에서는 오류 페이지가 응답으로 제공된다.
  3. 회사의 정책과, 필드마다 다르다. 가장 큰 맥락은 1번이 많이 사용된다.

계층적 구조의 어플리케이션 

  • 내가 개발한 프로그램의 구조가 가지는 특징
  • 표현 계층 app으로 사용자와 상호작용하는 main이 들어가 있는 계층
  • 서비스 계층 service로 끝나는 class로 업무 로직을 수행하는 계층
  • 영속화 계층 DAO로 PL/SQL을 배울 때 알게 되는, DAO로 업무 로직 수행에 필요한 데이터를 제공하는 계츨르오 나눠 져있다. 
  • class를 특정 계층으로 나눠서 개발한다. 계층이 속하는 클래스는 그 본연 계층에 취중하고, 주 업무는 주 목적 class에서 존재해야한다. 
  • 왜 계층을 나눠서 입력할까?
  • 계층을 나눠서 입력하면서, 분할되 있기 때문에 새로운 구현 체제가 아닌 추가로 구현하면 되는 장점이 있다. 

구현 

모두 Package로 구현한다. 

  • VO =사용자 정보 전달, 업무로직 없이 데이터만 작성한다. 
    • 객체에 대한 정보를 작성한다. 
    • private로 매개변수를 입력하고 
    • getter/ setter의 입력
    • 필요하다면 동등성 비교를 위한 Hash, isString()도 입력을 해준다. 
  • Exception = 예외 처리 기능 
    • 예외 클래스는 눈에 보면 한눈에 어떤 예외인지 알 수 있는 제목으로 작성한다. 
    • 한 곳에 넣을 class을 작성하고( HtaException으로 작성했다, extends RuntimeException )
    • HtaException을 상속받는 예외 클래스 3개를 입력했다. 
    • 예외 클래스 전부 생성자메소드를 입력해주면 된다. 
  • Service = 업무로직을 수행하는 기능
    • 배열을 입력하여, VO객체를 담을 수 있도록 collection배열을 사용하고, 
    • throw new 로 해당되는 예외 클래스를 입력하고, (매개변수 내용에 주체적인 예외를 만들어서 던진다);
    • 세분화 했기 때문에 for문은 1곳에서만 사용되었고, println은 한 곳도 사용되지 않았다.
    • 전부 예외로 반환하거나 , 해당되면 해당 객체로 반환하였다. 
    • 복잡한 if문도 사라졌다. 
  • App = 사용자와 상호작용하는 기능
    • class 바로 아래에 Scanner객체와, 업무로직 객체를 입력하였다. 
    • displayMenu으로 main메소드 외부에 작성하였다. 
    • 불러올 메소드들을 main메소드 외부에 각기 개별로 작성하였다. 그리고 service의 메소드를 호출하였다.
    • 그리고 displayMenu (실제로 클릭하는 메소드) if문에 외부에 작성한 메소드를 각기 호출하였다. 
    • try 문으로 클릭하는 부분을 전부 감싸고, catch문으로 처음에 RuntimeException을 extends한 HtaException으로 잡고, 내부는 getMessage를 호출하였다. 
    • main 메소드 바로 위에 displayMenu();를 입력하여, while문이 없이 본인이 호출하는, 계속 반복적으로 출력이 가능하게 하는 재귀호출 문을 사용하였다. 
    • 종료버튼의 경우 else if( menuNo == 0) {종료하기 ();}메소드를 호출하였고, public void 종료하기(){는 System.exit(0);}으로 while문이 없기 떄문에 break문이 아닌 System.exit를 이용하여 프로그램을 종료하였다. 
    • main 메소드에는 UserApp 객체를 호출하여, app이라는 참조변수 객체에 주소값을 입력했고, app.displayMenu();로 메소드 호출로 실행하게 만들었다. 
      • 메소드를 빼버리고 모듈로 만들어 버려서, 모듈화를 완성하였다. 
      • 이로써 코드의 가독성이 높아지고 결합도가 낮아지고, 응집력(연관있는 모듈끼리 함께 모여있다. )이 높아져 독립성이 높아졌다. 
    • 앞으로는 코딩은 이렇게 진행한다. 

 

 

반응형

'중앙 HTA (2106기) story > java API story' 카테고리의 다른 글

I/O(Data, Object)와 직렬화  (0) 2021.10.18
I/O  (0) 2021.10.14
Formating (포맷팅)  (0) 2021.10.08
Random class  (0) 2021.10.08
java.util.유틸리티 클래스  (0) 2021.10.08
Comments