예외
- 프로그램 실행 중에 발생할 수 있는 예기치 않은 상황(예외)에 대한 처리를 말한다.
- 예외에 대한 예를 들어보면 배열의 크기가 n이면 사용할 수 있는 인덱스는 0 ~ n-1 이다. 그 범위가 아닌 인덱스에 접근하는 상황을 뜻한다. 이 때는 ArrayIndexOutOfBoundsException 객체가 자동생성된다.
- 또한 숫자 형식에 맞지 않으면 NumberFomatException객체가 생성된다.
- 또 어떤 수를 0으로 나누는 상황에 문법 자체에 문법적 오류는 없으나, 실행 중에 사용자의 입력값이 바람직하지 않아 발생할 수 있는 예기치 않는 상황을 뜻한다.
- 자바는 대부분 예기치 않은 상황에 대해서 클래스가 만들어져있다. 그래서 그 상황이 되면 예외 객체를 생성해준다.(오류에 대한 text)
- 예외가 발생했을 때 자바는 new 예외클래스()를 한다.(예외 객체 생성)
예외처리 하는 방법
try{
//예외가 발생할 만한 문장들
}catch(예외클래스명 변수명){
//처리할 명령어(들)
}catch(예외클래스명 변수명){
//처리할 명령어(들)
}finally{
//반드시 처리할 명령어들(생략 가능)
}
//예외클래스명 변수명: Java에서 미리 만들어둔 객체 + 잡아올 변수명
//프로그램 실행 시에 두 개의 정수를 전달받아 나누기 한 결과를 출력
import java.util.Scanner;
class Calc02
{
public static void main(String[] args)
{
try{
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
int div = a/b;
System.out.println("나누기 결과:"+div);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("나누기할 두 수를 전달해주세요!");
}catch(NumberFormatException e){
System.out.println("정수를 입력해주세요");
}catch(ArithmeticException e){
System.out.println("0으로 나눌 수 없습니다.");
}
}
}
- 단, 실제 처리보다 예외처리떄문에 더욱더 길어지는 경향이 있었다.
- 이 예외들의 조상이 있으므로 하나로 묶을 수 있다. 굳이 세분화하여 예외처리할 필요가 없다면 하나로 묶어서 처리를 하도록 한다. 단, Arithmetic Exception 만은 따로 두고 싶을경우 그것만 따로 빼서 예외처리를 한다.
- 단, 포함 관계(상속 관계 등)에 있는 Exception을 쓸 경우, 자식을 먼저 쓰고 부모를 쓴다.
//프로그램 실행 시에 두 개의 정수를 전달받아 나누기 한 결과를 출력
import java.util.Scanner;
class Calc04
{
public static void main(String[] args)
{
try{
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
int div = a/b;
System.out.println("나누기 결과:"+div);
}catch(ArithmeticException e){
System.out.println("0으로 나눌 수 없습니다.");
}catch(Exception e){
System.out.println("나누기할 두 정수를 확인해주세요");
}
}
}
- 10번 줄의 catch(Exception e) 이 이미 모든 예외 상황을 처리 하기 때문에 12번 줄의 catch (ArithMethicException e)로 올 수 없어요.
- 이와 같이 catch 절을 여러개 쓸 때에는 자식의 catch 절이 먼저 오도록 해야 한다.
- 정상적으로 동작하는 경우는 try 안의 문장들이 다 동작이 되지만, 예외가 생기는 경우 catch문 안의 실행문들만 실행된다.
//프로그램 실행 시에 두 개의 정수를 전달받아 나누기 한 결과를 출력
import java.util.Scanner;
class Calc06
{
public static void main(String[] args)
{
try{
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
int div = a/b;
System.out.println("나누기 결과:"+div);
System.out.println("작업종료");
}catch(ArithmeticException e){
System.out.println("0으로 나눌 수 없습니다.");
}catch(Exception e){
System.out.println("나누기할 두 정수를 확인해주세요");
}
}
}
- 단, finally 를 쓰면 작업 종료는 두 경우 모두 동작 하게 된다.
- 정상동작하거나 예외가 발생하거나 반드시 동작시키고자 하는 명령어들을 써준다.
- 예외 처리 하지 않은 동작도 여기서는 동작하게 된다. 만약 finally 뒤에 일반 문장에 둔다면 해당 문장은 동작하지 않는다.
- return 문을 catch문에 적어주어도 동작한다.
//프로그램 실행 시에 두 개의 정수를 전달받아 나누기 한 결과를 출력
import java.util.Scanner;
class Calc08
{
public static void main(String[] args)
{
try{
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
int div = a/b;
System.out.println("나누기 결과:"+div);
}catch(ArithmeticException e){
System.out.println("0으로 나눌 수 없습니다.");
}finally{
System.out.println("작업종료");
}
}
}
메소드 안에서 예외가 발생이 될 때
- 메소드 자신이 직접 try ~catch를 써서 예외처리를 한다.
class ExceptionTest02
{
public static void calcDiv(int a, int b){
try{
int r = a / b;
System.out.println("나누기 결과 :" + r);
}catch(ArithmeticException e){
System.out.println("0으로 나눌수 없음");
}finally{
System.out.println("작업종료");
}
}
public static void main(String[] args)
{
try{
calcDiv(4,2);
calcDiv(4,0);
}catch(ArithmeticException e){
System.out.println();
}
}
}
- 메소드 호출하는 쪽으로 예외처리를 맞긴다.
- 메소드 선언부 매개변수 뒤쪽에 throws 를 적고 그 뒤에 예외들을 나열
- 여기서 e 가 예외 메세지를 갖고 있기 때문에 읽어올 수 있다.
class ExceptionTest03
{
public static void calcDiv (int a, int b) throws ArithmeticException{
int r = a / b;
System.out.println("나누기 결과 :" + r);
}
public static void main(String[] args)
{
try{
calcDiv(4,2);
calcDiv(4,0);
}catch(ArithmeticException e){
System.out.println("예외발생 : "+e);
}
}
}
- Exception()의 자식 클래스들은 super 로 내용을 전달받는다. 따라서 Excepttion에게 오류메세지를 가지고 있는것이다. 이때 Exception 의 부모 Throwble클래스를 보면 Error(오류), Exception(예외) 를 가지고 있다. 여기서 공통적으로 가지고 있는 printStackTrace() 메소드를 이용하면 어느 부분에서 에러가 났는지 확인할 수 있다.
- printStackTrace(): 예외가 발생항면 어디에서 문제가 발생하였는지 추적해가면서 정보를 출력해줄 수 있다.(이 때 자신이 입력한 코드와 라이브러리에서 입력된 코드의 위치까지 나온다. 오류와 관련있는 코드들은 모두 나오는 형식이다.)
import java.io.FileWriter;
import java.io.IOException;
class FileWriterTest6
{
public static void pro(String fname) throws IOException{
// FileWriter fw = new FileWriter("c:/data/hello.txt");
FileWriter fw = new FileWriter(fname);
fw.write("hello java");
fw.close();
System.out.println("파일을 생성하였습니다.");
}
public static void main(String[] args)
{
try{
pro("c:/datja/hello.txt");
}catch(IOException e){
e.printStackTrace();
//System.out.println("예외발생: "+e);
}
}
}
'Kosta DevOps 과정 280기 > Java' 카테고리의 다른 글
임계영역 (Critical Section) (0) | 2024.05.30 |
---|---|
멀티스레드-2 (0) | 2024.05.30 |
문자열 처리 (0) | 2024.05.28 |
정규표현식 (0) | 2024.05.27 |
문자열 (0) | 2024.05.27 |