본문 바로가기

기록/자바_국비

[배운내용정리] 1123 자바 국비교육

728x90

2020년 11월 23일 9시 ~ 15시 30분 zoom으로 수업 진행

 

11월 24일 프로그래밍 시험

 - 스터디때 서로 예상문제 + 요점정리 해서 스터디 진행하기로 했음

 - 나는 상속~


예외처리

프로그램 오류

 프로그램 수행 시 치명적 상황이 발생하여 비정상 종료 상황이 발생한 것,

 프로그램 에러라고도 함

 

오류의 종료

 1. 컴파일 에러 : 프로그램의 실행을 막는 소스 상의 문법 에러, 소스 구문을 수정하여 해결

 2. 런타임 에러 : 입력 값이 틀렸거나, 배열의 인덱스 범위를 벗어났거나, 계산식의 오류 등 주로 if문 사용으로 에러처리

 3. 시스템 에러 : 컴퓨터 오작동으로 인한 에러, 소스 구문으로 해결 불가

 

오류 해결 방법

 소스 수정으로 해결 가능한 에러를 예외(Exception) 라고 하는데, 이러한 예외 상황

 (예측 가능한 에러) 구문을 처리하는 방법인 예외 처리를 통해 해결

 

예외 클래스 계층구조

 Exception과 Error 클래스 모두 Object 클래스의 자손이며, 모든 예외의 최고 조상은 Exception 클래스이다, 반드시 예외 처리해야 하는 Checked Exception 과 해주지 않아도 되는 UnChecked Exception으로 나뉨

 

RuntimeException 클래스

 UnChecked Exception으로 주로 프로그래머의 부주의로 인한 오류인 경우가 많아 예외처리보다 코드 수정이 더 필요한 경우가 많음

 

RuntimeException의 후손 클래스

ArithmeticException

0으로 나누는 경우 발생, if문으로 나누는 수가 0인지 확인

NullPointerException

Null인 참조 변수로 객체 멤버 참조 시도 시 발행

객체 사용 전에 참조 변수가 null 인지 확인

NegativeArraySizeException

배열 크기를 음수로 지정한 경우 발생

배열 크기를 0 보다 크게 지정해야 한다

ArrayIndexOutOfBoundsException

배열의 index 범위를 넘어서 참조하는 경우

배열명.length를 사용하여 배열의 범위 확인

ClassCastException

Cast 연산자 사용 시 타입 오류

instanceof 연산자로 객체 타입 확인 후 cast 연산

 

 

 

예외처리(Exception)

 java api document에서 해당 클래스에 대한 생성자나 메소드를 검색하면

 그 메소드가 어떤 Exception을 발생시킬 가능성이 있는지 확인 가능

 해당 메소드를 사용하려면 반드시 뒤에 명시된 예외 클래스를 처리해야 함

 

throw 써져있으면 해당 메소드 사용할 때 꼭 exception 처리 해줘야 함

 

예외처리 방법

+ 크게 4가지로 구분

  - if 문 이용해 예외처리

  - throws

  - try ~ catch

  - try with resource

 

1. Exception 처리를 호출한 메소드에게 위임

 메소드 선언 시 throws ExceptionName문을 추가하여 호출한 상위 메소드에게 처리 위임

 계속 위임하면 main()메소드까지 위임하게 되고 거기서도 처리하지 않는 경우 비정상 종료

 

2. Exception이 발생한 곳에서 직접 처리

 try ~ catch문을 이용해 예외처리

   try : exception 발생할 가능성이 있는 코드를 안에 기술

   catch : try 구문에서 exception 발생 시 해당하는 exception에 대한 처리 기술

               여러 개의 exception 처리가 가능하나  exception간의 상속 관계 고려

  finally : exception 발생 여부와 관계없이 꼭 처리해야 하는 로직 기술

              중간에 return 문을 만나도 finally 구문은 실행되지만,

              System.exit(); 를 만나면 무조건 프로그램 종료,

              주로 java.io나 java.sql 패키지의 메소드 처리 시 이용

 

throw 와 throws 

 throw는 해당하는 클래스의 객체를 생성하면서 예외를 발생시킨다.

해당 코드에서 바로 예외처리를 해줘야하나 메소드 선언부에 작성 한 throws 때문에 해당 메소드를 호출 한 곳에서 예외처리를 한다!

 

main 메소드에서도 throws로 넘긴 예외는 JVM이 처리한다

 


package com.ch01.runtime.run;

import com.ch01.runtime.controller.RuntimeException;

public class Run {

	public static void main(String[] args) {
		RuntimeException re = new RuntimeException();
		//re.ArithEx();
		re.classNArrayEx();
	}

}

 

package com.ch01.runtime.controller;

import java.util.Scanner;

public class RuntimeException {

	//런타임
	//소스 코드 수정으로 해결 가능, 치명적인 예외 상황의 표현에 사용되지 않는다.
	//ArrayIndexOutOfBoundsException : 배열의 접근이 잘못된 인덱스 값을 사용하는 경우
	//ClassCastException : 허용할 수 없는 형변환 연산을 진행하는 경우
	//NullPointerException : 참조변수가 null로 초기화된 상황에서 메소드를 호출하는 경우
	
	Scanner sc = new Scanner(System.in);
	
	//런타임
	public void ArithEx() {
		
		int ran = 0;
		double res = 0.0;
		
		while(true) {
			System.out.print("정수 하나 입력 : ");
			int no = sc.nextInt();
			/*
			ran = (int)(Math.random()*10)+1;
			res = ran/(double)no;
			
			System.out.printf("%d / %d = %.2f\n", ran, no, res);
			//0입력 받을경우 Infinity 출력된다
			 * */
			if(no != 0) {
				ran = (int)(Math.random()*10)+1;
				res = ran/(double)no;
				
				System.out.printf("%d / %d = %.2f\n", ran, no, res);
			}
			else {
				System.out.println("0이 아닌 값을 입력해주세요");
			}
		}
		
		
	}
	
	public void classNArrayEx() {
		//원래 한번에 다 작성했지만 나중에 보기 편하라구 따로따로 코드 작성합니다!
		
		//ClassCastException
		/*
		Object obj='a';
		//캐릭터 'a'가 객체화 되고 객체화 된 친구가 Object형으로 포장된다
		System.out.println(obj);
		
		String str = (String)obj;
		System.out.println(str);//예외 발생하면서 실행안됨
		//ClassCastException 발생
		//Character를 String으로 바꿀 수 없어서 에러난다
		*/
		
		/*
		try {
			Character ch = 'a';
			Object obj = ch;
			System.out.println(obj);
			
			String str = (String)obj;//ClassCastException
			System.out.println(str);//실행 안됨
			
		}catch(ClassCastException e) {
			System.out.println("ClassCastException 발생!~!!! 내가 잡았따!!!!!");
			e.printStackTrace();
		}
		*/
		
		
		//ArrayIndexOutOfBoundsException
		/*
		try {
			int arr[] = new int[2];
			arr[0] = 1;
			arr[1] = 2;
			
			arr[2] = 3;//ArrayIndexOutOfBoundsException발생!
			//Index 2 out of bounds for length 2
			
			System.out.println("여기도 실행 될까?");//실행 안됨!
			//여기서 알 수 있는 점
			//예외가 발생하면 그 밑으로는 실행 안되고 바로 catch문으로 이동
			
		}catch(ClassCastException e) {
			System.out.println("ClassCastException 발생!~!!! 내가 잡았따!!!!!");
			e.printStackTrace();
		}
		catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("ArrayIndexOutOfBoundsException 발생!~!!! 내가 잡았따!!!!!");
			e.printStackTrace();
		}
		*/
		
		//NullPointerException
		
		try {
			String str = null;
			int length = str.length();
			//NullPointerException 발생
			
		}
		catch(ClassCastException e) {
			System.out.println("ClassCastException 발생!~!!! 내가 잡았따!!!!!");
			e.printStackTrace();
		}
		catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("ArrayIndexOutOfBoundsException 발생!~!!! 내가 잡았따!!!!!");
			e.printStackTrace();
		}
		catch(NullPointerException e) {
			System.out.println("NullPointerException 발생!~!!! 내가 잡았따!!!!!");
			e.printStackTrace();
		}
		finally {
			//에러 다 출력하고 finally 블럭 내부의 코드 실행
			//에러 없을 경우 try문 끝나고 바로 실행
			//에러가 발생하거나 안하거나 상관없이 무조건 실행되는 블럭
			//여기서도 try ~ catch 사용 가능
			System.out.println("여기는 무조건 실행!!!");
		}
		
		
	}
	
}

package com.chap02.throwsPrac;

import java.io.IOException;

public class Run {

	public static void main(String[] args) throws IOException{
		//방법1
		//메인 메소드 선언부에 throws IOException 작성
		//JVM이 알아서 예외 처리해준다
		methodA();
		
		//방법2
		/*
		try{
			methodA();
		}catch(IOException e) {
			System.out.println("메인에서 예외처리!");
			e.printStackTrace();
		}
		*/
		System.out.println("프로그램 종료");
		
	}

	public static void methodA() throws IOException{
		methodB();
	}

	public static void methodB() throws IOException{
		methodC();
	}

	public static void methodC() throws IOException{
		/*
		try{
			throw new IOException();
		}catch(IOException e) {
			
		}
		*/
		
		throw new IOException();
		//해당 메소드를 호출한 곳에서 throws나 try~catch를 사용하지 않으면 에러남
		
	}

}

package com.chap03.myException;

public class MyException extends Exception{

	public MyException() {
		System.out.println("내가 만든 예외 클래스 !");
		
	}
	
	public MyException(String msg) {
		super(msg);
		
	}
	
}

 

package com.chap03.myException;

import java.util.Scanner;

public class Run {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		System.out.print("정수 하나 입력 :");
		
		try {
			checkNum(sc.nextInt());
		} catch (MyException e) {
			//e.printStackTrace();
			
			System.out.println(e.getMessage());
			//throw new MyException();
			//이거 사용 했을 때
			//내가 만든 예외 클래스 !
			//null
			//가 뜨는데 메세지에 아무 말도 써있지 않음을 알 수 있음!
			
			//throw new MyException("hello");
			//이거 사용했을 때는
			//hello
			//만 출력된다. 별 다른 출력문 없이 메세지로 "hello" 값을 전달 받았기 때문에
			//전달받은 메세지 hello만 출력되는 것
			//Exception의 부모 Throwable 때문에 이런 작업이 가능!
			//Throwable 클래스의 생성자로 msg를 넘기면 detailMessage 변수에 msg 값을 저장
			//저장된 msg는 Throwable 클래스의 메소드 getMessage()에서 반환된다.
			
		}

	}
	
	public static void checkNum(int num) throws MyException{
		if(num >= 10) {
			System.out.println(num + "은 10보다 크거나 같습니다.");
		}
		else {
			//throw new MyException();
			//내가 만든 예외 클래스 ! 출력
			
			throw new MyException("hello");
			//에러 뜬 클래스 옆에 : hello 뜸
		}
	}

}