본문 바로가기

개발/Java

Java Exception처리

반응형
package Exception;
 
import java.util.Scanner;
 
public class DivideByZero {
    
    public static void main(String[] args) {
        
        System.out.println("두 개의 정수 입력 : ");
        Scanner keyboard = new Scanner(System.in);
        int num1 = keyboard.nextInt();
        int num2 = keyboard.nextInt();
        
        try {
            
            System.out.println("나눗셈 결과의 몫 : "+(num1/num2));
            System.out.println("나눗셈 결과의 나머지 : "+(num1%num2));
            
        } catch (ArithmeticException e) {
            
            System.out.println("나눗셈 불가능!");
            System.out.println(e.getMessage());
            
        }
        
        System.out.println("프로그램을 종료 합니다.");
        
    }
 
}

1. 자바 가상머신이 0으로 나누는 예외상황이 발생했음을 인식
2. 이 상황을 위해 정의된 ArithmeticException 클래스의 인스턴스를 생성한다.
3. 이렇게 생성된 인스턴스의 참조값을 catch 영역에 선언된 매개변수에 전달한다. 

 

■ 예외상황을 알리는 클래스는 모두 정의가 되어 있나요? 일단 초보니까 몇개만 알도록 하자 

⊙ 배열의 접근에 잘못된 인덱스 값을 사용하는 예외상황
→ 예외 클래스 : ArrayIndexOutOfBoundException
⊙ 허용할 수 없는 형변환 연산을 진행하는 예외상황
→ 예외 클래스 : ClassCastException
⊙ 배열선언 과정에서 배열의 크기를 음수로 지정하는 예외상황
→ 예외 클래스 : NegativeArraySizeException
참조변수가 null로 초기화된 상황에서 메소드를 호출하는 상황
→ 예외 클래스 : NullPointerException
 

■ 예외상황의 발생여부와 상관없이 항상 실행되는 영역 : finally

package Exception;
 
public class FinallyTest {
    
    public static void main(String[] args) {
        
        boolean divOK = divider(4, 2);
        if (divOK)             
            System.out.println("연산 성공");
        else 
            System.out.println("연산 실패");
        
        divOK = divider(4, 0);
        if (divOK) 
            System.out.println("연산 성공");
        else 
            System.out.println("연산 실패");
        
    }
    
    public static boolean divider(int num1, int num2) {
        
        try {
            
            int result = num1/num2;
            System.out.println("나눗셈 결과는 "+result);
            return true;
            
        } catch (ArithmeticException e) {
            
            System.out.println(e.getMessage());
            return false;
            
        } finally {
            
            System.out.println("finally 영역 실행");
            
        }
    }
 
}

보통은 "예외상황의 발생여부에 상관없이 실행되는 영역"으로만 이해하다보니, 필요한 때에 finally를 활용하지 못하는 경우가 많다.

보다 정확한 표현은 다음과 같다. "try 영역으로 일단 들어가면 무조건 실행되는 영역" → finally
중간에 return을 하더라도 finally 영역을 실행되고 나서 메소드를 빠져나가게된다. 
 
18-2 프로그래머가 직접 정의하는 예외의 상황
package Exception;
 
import java.util.Scanner;
 
class AgeInputException extends Exception {
    
    public AgeInputException() {
        
        super("유효하지 않은 나이가 입력되었습니다.");
    }
}
 
public class ThrowsFromMain {
    
    public static void main(String[] args) throws AgeInputException {
        
        System.out.println("나이를 입력하세요 : ");
        
        try {
            
            int age = readAge();
            System.out.println("당신은 "+age+"세입니다.");
            
        } catch (AgeInputException e) {
        
            System.out.println(e.getMessage());
            
        }
        
        
    }
    
    public static int readAge() throws AgeInputException {
        
        Scanner keyboard = new Scanner(System.in);
        int age = keyboard.nextInt();
        
        if (age<0) {
            
            AgeInputException excpt = new AgeInputException();
            throw excpt;
            
        }
        return age;
    }
 
}
나이를 입력하세요 : 
-2
Exception in thread "main" Exception.AgeInputException: 유효하지 않은 나이가 입력되었습니다.
    at Exception.ThrowsFromMain.readAge(ThrowsFromMain.java:30)
    at Exception.ThrowsFromMain.main(ThrowsFromMain.java:18)

 

가상머신의 예외처리

1 getMessage 메소드를 출력한다.

2 예외상황이 발생해서 전달되는 과정을 출력해준다.

3 프로그램을 종료한다.

 

import java.util.ArrayList;
 
public class Main {
 
   public static void main(String[] args) {
                      
          try {
               Main.divide(3, 0);
          } catch (ArithmeticException ae){
               // 경고 팝업을 띄운다
               System.out.println("0으로 나눴습니다. 다시 계산해주세요..");
          }
   }
    
   public static int divide(int a, int b) {
          return a/b;
   }
  
   public static void addAllStudent() throws ListOverflowException, ListNullException {
       SungSinGirlSchool school = new SungSinGirlSchool();
       school.addStudent("songhee");
       school.addStudent("songhee");
       school.addStudent("songhee");
       school.addStudent("songhee");
   }
  
}
 
class SungSinGirlSchool {
  
   private ArrayList<String> studentList = new ArrayList<String>();
  
   public SungSinGirlSchool() {
   }
  
   public void addStudent(String studentName) throws ListOverflowException, ListNullException {
      if(studentList.size() == 3) {
         throw new ListOverflowException("학생이 꽉 찼습니다. >.<");
      }
     
      studentList.add(studentName);
   }
  
}
 
class ListOverflowException extends Exception {
   private static final long serialVersionUID = -7105555152321998192L;
  
   public ListOverflowException() {
      super("리스트가 꽉찼어요");
   }
  
   public ListOverflowException(String exceptionName) {
      super(exceptionName);
   }
  
}
 
class ListNullException extends Exception {
   private static final long serialVersionUID = -7105555152321998192L;
  
   public ListNullException() {
      super("리스트가 꽉찼어요");
   }
  
   public ListNullException(String exceptionName) {
      super(exceptionName);
   }
  
}

 

 
try 
{
    // try 영역 
}
 
try 영역에서 발생한 AAA예외상황은 
catch(AAA e)
{
   // catch 영역
}
이어서 등장하는 catch 영역에서 처리된다. 
                         

 

반응형
LIST

'개발 > Java' 카테고리의 다른 글

이클립스 주석 적용(Shift + Alt + J)  (0) 2020.05.04
이클립스 테마 어둡게  (0) 2020.05.04
Collection  (0) 2018.08.13
변수(Variable)와 자료형(Data Type), 연산자(Operator)  (0) 2018.05.19
Exception 처리  (0) 2018.05.19