ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] 예외(Exception)
    Programming/Java 2021. 5. 19. 03:03

    예외 클래스 

    예외 클래스 계층 구조 

    Error와 Exception은 모두 Throwable 클래스를 상속받음

    위의 그림을 통해 Exception 2가지 종류에 대해 알 수 있음

     

    1. Checked Exception -> 일반(컴파일 체크) 예외

    • 예외 처리 코드가 없으면 컴파일 오류 발생 
    • 예외 확인 시점 : 컴파일 단계

     

    2. Unchecked Exception -> 실행 예외 

    • 예외처리 코드 생략해도 컴파일 됨 
    • 예외 확인 시점 : 실행 단계 
    • RuntimeException 클래스의 하위 클래스들 

    예외 처리

    1. Checked Exception

    1-1. 예외 처리 전

    import java.io.FileReader;
    
    public class CheckedException {
    
    	public static void main(String[] args) {
    		FileReader file = new FileReader("something.txt");
    	}
    
    }

    컴파일 에러 - 에외 처리 필수

    1-2. 예외 처리 후

    예외처리1) try-catch문 사용 

    import java.io.FileNotFoundException;
    import java.io.FileReader;
    
    public class CheckedException {
    
    	public static void main(String[] args) {
    		
    		try {
    			FileReader file = new FileReader("something.txt");
    		}catch(FileNotFoundException e) {
    			e.printStackTrace();
    		}	
            
    	}
    }

    예외처리2) throws 사용 

    import java.io.FileNotFoundException;
    import java.io.FileReader;
    
    public class CheckedException {
    
    	public static void main(String[] args) throws FileNotFoundException {
    		
    		FileReader file = new FileReader("something.txt");
            
    	}
    }

     

    2. Unchecked Exception

    import java.io.FileReader;
    import java.io.IOException;
    
    public class UncheckedException{
    	public static void main(String[] args) {
    		try{
    			FileReader file = new FileReader("hello.txt");
             
    			file = null; 
             
    			file.read(); //NullPointerException 발생 
    		} catch (IOException e) {
            //Alternate logic
            e.printStackTrace();
        	}
    	}
    }

    실행 결과

    --> Checked Exception과 달리 NullPointerException에 대한 예외 처리를 하지 않았음에도 컴파일이 되고 실행됨 


    예외 발생시키고 처리해보기 (Java11 기준)

    1. 실행 예외 : 0으로 나눴을 때 --> ArithmeticException 발생

    ArithmeticException클래스의 상속 관계

    import java.util.Scanner;
    
    public class DivdeByZero {
    
    	public static void main(String[] args) {
    		Scanner kbd = new Scanner(System.in);
    		int dividend; //나눠지는 수 
    		int divisor; //나누는 수 
    		
    		
    		while(true) {
    			System.out.print("나눠지는 수 입력 : ");
    			dividend = kbd.nextInt();
    			System.out.print("나누는 수 입력 : ");
    			divisor = kbd.nextInt();
    			try {
    				System.out.println("몫은 " + dividend/divisor); //divisor 0 입력 시 예외 발생
    				break; //올바른 입력 시 반복문 종료 
    			}catch(ArithmeticException e) { //예외 처리 
    				System.out.println("divisor는 0이 될 수 없음 다시 입력하셈");
    				//e.printStackTrace(); //예외 발생 코드 추적 내용 확인 
    			}
    		}
    	}
    
    }

    실행 결과

     

    2. 실행 예외 : 범위를 벗어난 배열의 접근 --> ArrayIndexOutOfBoundsException 발생

    ArrayIndexOutOfBoundsException클래스의  상속 관계 

    public class ArrayIndexOut {
    
    	public static void main(String[] args) {
    		int[] intArr = new int[3];
    		
    		try {
    			for(int i = 0; i<=intArr.length; i++) {
    				intArr[i] = i*i;
    				System.out.println(intArr[i]);
    			}
    		}catch(ArrayIndexOutOfBoundsException e) { //예외 처리 
    			e.printStackTrace();
    			System.out.println("배열의 인덱스 범위를 벗어났습니다.");
    		}
    
    	}
    
    }

    실행 결과

     

    3. 실행 예외 : 입력 오류 시 --> java.util.InputMismatchException 발생

    InputMismatchException클래스 상속 관계

    import java.util.InputMismatchException; //java.util 패키지 이므로 import 해줘야 함 
    import java.util.Scanner;
    
    public class InputMismatch {
    
    	public static void main(String[] args) {
    		Scanner kbd = new Scanner(System.in);
    		System.out.println("정수 3개를 입력하세요.");
    		int sum = 0, n=0;
    		
    		for(int i = 0; i<3; i++) {
    			System.out.print(i + ">>");
    			try {
    				n = kbd.nextInt(); //정수 입력 -> 정수 이외의 값 입력 시 InputMismatchException 발생 
    				
    			}catch(InputMismatchException e) {
    				System.out.println("정수가 아닙니다. 다시 입력!");
    				System.out.println(kbd.next()); //입력 스트림에 있는 정수가 아닌 토큰 버림 
    				i--;
    				continue;
    			}
    			sum += n;
    		}
    		
    		System.out.println("합은 " + sum);
    
    	}
    
    }

    실행 결과

     

    4. 실행 예외 : 정수가 아닌 문자열을 정수로 변환할 때 --> NumberFormatException 발생

    NumberFormatException클래스 상속 관계

    public class NumberFormat {
    
    	public static void main(String[] args) {
    		String[] stringNum = {"03", "25", "3.1515", "28"};
    		
    		int i = 0; //catch블록에서 i 값 사용하기 위해 try 블록 밖에서 선언해줌   
    		try {
    			for(i=0; i<stringNum.length; i++) {
    				int j = Integer.parseInt(stringNum[i]);
    				System.out.println("변환된 값 : " + j);
    			}
    		}catch(NumberFormatException e) {
    			System.out.println(stringNum[i]+ "는 정수로 변환할 수 없습니다.");
    		}
    		
    	}
    
    }

    실행 결과

     


    추가 정리 

    void printStackTrace()

    • java.lang.Throwable 클래스에 정의된 메소드로 Exception클래스는 Throwable 클래스를 상속 받으므로 Exception 클래스의 모든 하위 클래스들은 해당 메소드 사용 가능함
    • 메서드 기능 : 예외 발생 코드 추적한 내용을 모두 콘솔에 출력 --> 프로그램 테스트하면서 오류 찾을 때 유용함
    • 사용 예시 :
      try-catch 문으로 예외처리 시 예외 발생 코드 추적한 내용은 나오지 않는데, printStackTrace()를 사용하면 예외 발생 코드 추적한 내용을 콘솔에 출력해줌

     

    try 블록 내의 변수

    • try 블록 내에 선언된 변수는 해당 블록 내에서만 알 수 있어서 catch 블록이나 finally 블록에서도 사용하려면, try 블록 외부에 미리 선언해두어야 함
    • 사용 예시 :
      try 블록 내에 선언된 변수 i 를 catch 블록에서 사용했으므로 컴파일 에러 발생

     

    [참고]

    https://www.nextree.co.kr/p3239/

    https://howtodoinjava.com/java/exception-handling/checked-vs-unchecked-exceptions-in-java/#types

    'Programming > Java' 카테고리의 다른 글

    Java의 ==, equals 연산자를 통한 문자열 비교  (0) 2022.02.27
    JVM 구조  (0) 2022.02.19
    Java 활용 포켓몬 게임  (0) 2022.01.30

    댓글

Designed by Tistory.