자바-예외
예외 (또는 예외 이벤트)는 프로그램 실행 중에 발생하는 문제입니다. 때Exception 프로그램의 정상적인 흐름이 중단되고 프로그램 / 애플리케이션이 비정상적으로 종료되는 경우가 발생하므로 권장되지 않으므로 이러한 예외를 처리해야합니다.
여러 가지 이유로 예외가 발생할 수 있습니다. 다음은 예외가 발생하는 몇 가지 시나리오입니다.
사용자가 잘못된 데이터를 입력했습니다.
열어야하는 파일을 찾을 수 없습니다.
통신 중에 네트워크 연결이 끊어 졌거나 JVM의 메모리가 부족합니다.
이러한 예외 중 일부는 사용자 오류로, 다른 일부는 프로그래머 오류로, 다른 일부는 어떤 식 으로든 실패한 물리적 리소스로 인해 발생합니다.
이를 바탕으로 세 가지 범주의 예외가 있습니다. Java에서 예외 처리가 작동하는 방식을 이해하려면이를 이해해야합니다.
Checked exceptions− 확인 된 예외는 컴파일 시간에 컴파일러가 확인 (알림)하는 예외이며 컴파일 시간 예외라고도합니다. 이러한 예외는 단순히 무시할 수 없으며 프로그래머는 이러한 예외를 처리 (처리)해야합니다.
예를 들어 FileReader생성자에 지정된 파일이 존재하지 않는 경우 프로그램의 클래스가 파일에서 데이터를 읽으면 FileNotFoundException이 발생하고 컴파일러는 프로그래머에게 예외를 처리하도록 프롬프트합니다.
예
import java.io.File;
import java.io.FileReader;
public class FilenotFound_Demo {
public static void main(String args[]) {
File file = new File("E://file.txt");
FileReader fr = new FileReader(file);
}
}
위의 프로그램을 컴파일하려고하면 다음과 같은 예외가 발생합니다.
산출
C:\>javac FilenotFound_Demo.java
FilenotFound_Demo.java:8: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
FileReader fr = new FileReader(file);
^
1 error
Note − 방법 이후 read() 과 close() FileReader 클래스에서 IOException이 발생하면 컴파일러가 FileNotFoundException과 함께 IOException을 처리하도록 알립니다.
Unchecked exceptions− 확인되지 않은 예외는 실행시 발생하는 예외입니다. 이것들은 또한Runtime Exceptions. 여기에는 논리 오류 또는 부적절한 API 사용과 같은 프로그래밍 버그가 포함됩니다. 런타임 예외는 컴파일시 무시됩니다.
예를 들어, 프로그램에서 크기 5의 배열을 선언하고 배열의 6 번째 요소 를 호출하려고 하면 ArrayIndexOutOfBoundsExceptionexception 이 발생합니다.
예
public class Unchecked_Demo {
public static void main(String args[]) {
int num[] = {1, 2, 3, 4};
System.out.println(num[5]);
}
}
위의 프로그램을 컴파일하고 실행하면 다음과 같은 예외가 발생합니다.
산출
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at Exceptions.Unchecked_Demo.main(Unchecked_Demo.java:8)
Errors− 이는 예외가 아니라 사용자 또는 프로그래머의 통제를 벗어난 문제입니다. 오류에 대해 거의 아무것도 할 수 없기 때문에 오류는 일반적으로 코드에서 무시됩니다. 예를 들어 스택 오버플로가 발생하면 오류가 발생합니다. 또한 컴파일시 무시됩니다.
예외 계층
모든 예외 클래스는 java.lang.Exception 클래스의 하위 유형입니다. 예외 클래스는 Throwable 클래스의 하위 클래스입니다. 예외 클래스 외에 Throwable 클래스에서 파생 된 Error라는 또 다른 하위 클래스가 있습니다.
오류는 심각한 오류가 발생한 경우 발생하는 비정상적인 조건이며 Java 프로그램에서 처리하지 않습니다. 런타임 환경에서 생성 된 오류를 나타 내기 위해 오류가 생성됩니다. 예 : JVM에 메모리가 부족합니다. 일반적으로 프로그램은 오류에서 복구 할 수 없습니다.
Exception 클래스에는 IOException 클래스와 RuntimeException 클래스의 두 가지 주요 하위 클래스가 있습니다.
다음은 가장 일반적인 확인 및 확인되지 않은 Java의 내장 예외 목록 입니다.
예외 방법
다음은 Throwable 클래스에서 사용할 수있는 중요한 메서드 목록입니다.
Sr. 아니. | 방법 및 설명 |
---|---|
1 | public String getMessage() 발생한 예외에 대한 자세한 메시지를 반환합니다. 이 메시지는 Throwable 생성자에서 초기화됩니다. |
2 | public Throwable getCause() Throwable 객체가 나타내는 예외의 원인을 반환합니다. |
삼 | public String toString() getMessage ()의 결과와 연결된 클래스 이름을 리턴합니다. |
4 | public void printStackTrace() 스택 추적과 함께 toString ()의 결과를 오류 출력 스트림 인 System.err에 인쇄합니다. |
5 | public StackTraceElement [] getStackTrace() 스택 추적의 각 요소를 포함하는 배열을 반환합니다. 인덱스 0의 요소는 호출 스택의 맨 위를 나타내고 배열의 마지막 요소는 호출 스택의 맨 아래에있는 메서드를 나타냅니다. |
6 | public Throwable fillInStackTrace() 이 Throwable 개체의 스택 추적을 현재 스택 추적으로 채우고 스택 추적의 이전 정보에 추가합니다. |
예외 잡기
메소드는 다음 조합을 사용하여 예외를 포착합니다. try 과 catch키워드. 예외를 생성 할 수있는 코드 주위에 try / catch 블록이 배치됩니다. try / catch 블록 내의 코드를 보호 코드라고하며 try / catch를 사용하는 구문은 다음과 같습니다.
통사론
try {
// Protected code
} catch (ExceptionName e1) {
// Catch block
}
예외가 발생하기 쉬운 코드는 try 블록에 배치됩니다. 예외가 발생하면 발생한 예외는 연관된 catch 블록에 의해 처리됩니다. 모든 try 블록 바로 뒤에 catch 블록 또는 finally 블록이 와야합니다.
catch 문에는 catch하려는 예외 유형을 선언하는 것이 포함됩니다. 보호 코드에서 예외가 발생하면 try 다음에 나오는 catch 블록 (또는 블록)이 검사됩니다. 발생한 예외 유형이 catch 블록에 나열되어 있으면 인수가 메서드 매개 변수에 전달되는 것처럼 예외가 catch 블록에 전달됩니다.
예
다음은 2 개의 요소로 선언 된 배열입니다. 그런 다음 코드는 예외를 발생시키는 배열 의 세 번째 요소에 액세스하려고합니다 .
// File Name : ExcepTest.java
import java.io.*;
public class ExcepTest {
public static void main(String args[]) {
try {
int a[] = new int[2];
System.out.println("Access element three :" + a[3]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Exception thrown :" + e);
}
System.out.println("Out of the block");
}
}
이것은 다음 결과를 생성합니다-
산출
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3
Out of the block
다중 캐치 블록
try 블록 뒤에 여러 catch 블록이 올 수 있습니다. 여러 catch 블록의 구문은 다음과 같습니다.
통사론
try {
// Protected code
} catch (ExceptionType1 e1) {
// Catch block
} catch (ExceptionType2 e2) {
// Catch block
} catch (ExceptionType3 e3) {
// Catch block
}
앞의 명령문은 세 개의 catch 블록을 보여 주지만 한 번의 시도 후에 여러 개의 catch 블록을 가질 수 있습니다. 보호 된 코드에서 예외가 발생하면 목록의 첫 번째 catch 블록에 예외가 throw됩니다. 던져진 예외의 데이터 유형이 ExceptionType1과 일치하면 거기에서 포착됩니다. 그렇지 않은 경우 예외는 두 번째 catch 문으로 전달됩니다. 이는 예외가 포착되거나 모든 포착을 통과 할 때까지 계속됩니다.이 경우 현재 메서드가 실행을 중지하고 예외가 호출 스택의 이전 메서드로 던져집니다.
예
다음은 여러 try / catch 문을 사용하는 방법을 보여주는 코드 세그먼트입니다.
try {
file = new FileInputStream(fileName);
x = (byte) file.read();
} catch (IOException i) {
i.printStackTrace();
return -1;
} catch (FileNotFoundException f) // Not valid! {
f.printStackTrace();
return -1;
}
여러 유형의 예외 포착
Java 7부터는 단일 catch 블록을 사용하여 둘 이상의 예외를 처리 할 수 있으므로이 기능은 코드를 단순화합니다. 방법은 다음과 같습니다.
catch (IOException|FileNotFoundException ex) {
logger.log(ex);
throw ex;
Throws / Throw 키워드
메서드가 확인 된 예외를 처리하지 않는 경우 메서드는 throws예어. throws 키워드는 메서드의 서명 끝에 나타납니다.
다음을 사용하여 새로 인스턴스화 된 예외 또는 방금 포착 한 예외를 throw 할 수 있습니다. throw 예어.
throws와 throw 키워드의 차이점을 이해하려고하면 throws 는 확인 된 예외 처리를 연기하는 데 사용 되며 throw 는 명시 적으로 예외를 호출하는 데 사용됩니다.
다음 메소드는 RemoteException을 던진다 고 선언합니다.
예
import java.io.*;
public class className {
public void deposit(double amount) throws RemoteException {
// Method implementation
throw new RemoteException();
}
// Remainder of class definition
}
메서드는 둘 이상의 예외를 throw한다고 선언 할 수 있습니다.이 경우 예외는 쉼표로 구분 된 목록에 선언됩니다. 예를 들어, 다음 메소드는 RemoteException과 InsufficientFundsException을 던진다 고 선언합니다.
예
import java.io.*;
public class className {
public void withdraw(double amount) throws RemoteException,
InsufficientFundsException {
// Method implementation
}
// Remainder of class definition
}
마지막 블록
finally 블록은 try 블록 또는 catch 블록을 따릅니다. finally 코드 블록은 예외 발생에 관계없이 항상 실행됩니다.
finally 블록을 사용하면 보호 된 코드에서 어떤 일이 발생하더라도 실행하려는 모든 정리 유형 문을 실행할 수 있습니다.
finally 블록은 catch 블록의 끝에 표시되며 다음 구문을 사용합니다.
통사론
try {
// Protected code
} catch (ExceptionType1 e1) {
// Catch block
} catch (ExceptionType2 e2) {
// Catch block
} catch (ExceptionType3 e3) {
// Catch block
}finally {
// The finally block always executes.
}
예
public class ExcepTest {
public static void main(String args[]) {
int a[] = new int[2];
try {
System.out.println("Access element three :" + a[3]);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Exception thrown :" + e);
}finally {
a[0] = 6;
System.out.println("First element value: " + a[0]);
System.out.println("The finally statement is executed");
}
}
}
이것은 다음 결과를 생성합니다-
산출
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3
First element value: 6
The finally statement is executed
다음을 참고하십시오-
try 문없이 catch 절은 존재할 수 없습니다.
try / catch 블록이있을 때마다 finally 절이 있어야하는 것은 아닙니다.
try 블록은 catch 절이나 finally 절 없이는 존재할 수 없습니다.
try, catch, finally 블록 사이에는 어떤 코드도 존재할 수 없습니다.
시도 자원
일반적으로 스트림, 연결 등과 같은 리소스를 사용할 때 finally 블록을 사용하여 명시 적으로 닫아야합니다. 다음 프로그램에서는 다음을 사용하여 파일에서 데이터를 읽습니다.FileReader 그리고 finally 블록을 사용하여 닫습니다.
예
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class ReadData_Demo {
public static void main(String args[]) {
FileReader fr = null;
try {
File file = new File("file.txt");
fr = new FileReader(file); char [] a = new char[50];
fr.read(a); // reads the content to the array
for(char c : a)
System.out.print(c); // prints the characters one by one
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fr.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
try-with-resources, 일컬어 automatic resource management는 try catch 블록 내에서 사용되는 리소스를 자동으로 닫는 Java 7에 도입 된 새로운 예외 처리 메커니즘입니다.
이 문을 사용하려면 괄호 안에 필요한 리소스를 선언하기 만하면됩니다. 생성 된 리소스는 블록 끝에서 자동으로 닫힙니다. 다음은 try-with-resources 문의 구문입니다.
통사론
try(FileReader fr = new FileReader("file path")) {
// use the resource
} catch () {
// body of catch
}
}
다음은 try-with-resources 문을 사용하여 파일의 데이터를 읽는 프로그램입니다.
예
import java.io.FileReader;
import java.io.IOException;
public class Try_withDemo {
public static void main(String args[]) {
try(FileReader fr = new FileReader("E://file.txt")) {
char [] a = new char[50];
fr.read(a); // reads the contentto the array
for(char c : a)
System.out.print(c); // prints the characters one by one
} catch (IOException e) {
e.printStackTrace();
}
}
}
try-with-resources 문을 사용하는 동안 다음 사항을 염두에 두어야합니다.
try-with-resources 문으로 클래스를 사용하려면 다음을 구현해야합니다. AutoCloseable 인터페이스 및 close() 그것의 메서드는 런타임에 자동으로 호출됩니다.
try-with-resources 문에서 둘 이상의 클래스를 선언 할 수 있습니다.
try-with-resources 문의 try 블록에서 여러 클래스를 선언하는 동안 이러한 클래스는 역순으로 닫힙니다.
괄호 안의 리소스 선언을 제외하고 모든 것은 try 블록의 일반 try / catch 블록과 동일합니다.
try에서 선언 된 리소스는 try-block이 시작되기 직전에 인스턴스화됩니다.
try 블록에서 선언 된 리소스는 암시 적으로 final로 선언됩니다.
사용자 정의 예외
Java에서 고유 한 예외를 만들 수 있습니다. 자신의 예외 클래스를 작성할 때 다음 사항을 염두에 두십시오.
모든 예외는 Throwable의 자식이어야합니다.
Handle 또는 Declare Rule에 의해 자동으로 적용되는 확인 된 예외를 작성하려면 Exception 클래스를 확장해야합니다.
런타임 예외를 작성하려면 RuntimeException 클래스를 확장해야합니다.
아래와 같이 Exception 클래스를 정의 할 수 있습니다.
class MyException extends Exception {
}
미리 정의 된 Exception자신의 예외를 만드는 클래스. 이는 확인 된 예외로 간주됩니다. 다음과 같은InsufficientFundsExceptionclass는 Exception 클래스를 확장하여 확인 된 예외로 만드는 사용자 정의 예외입니다. 예외 클래스는 유용한 필드와 메서드를 포함하는 다른 클래스와 같습니다.
예
// File Name InsufficientFundsException.java
import java.io.*;
public class InsufficientFundsException extends Exception {
private double amount;
public InsufficientFundsException(double amount) {
this.amount = amount;
}
public double getAmount() {
return amount;
}
}
사용자 정의 예외 사용을 설명하기 위해 다음 CheckingAccount 클래스에는 InsufficientFundsException을 발생시키는 withdraw () 메서드가 포함되어 있습니다.
// File Name CheckingAccount.java
import java.io.*;
public class CheckingAccount {
private double balance;
private int number;
public CheckingAccount(int number) {
this.number = number;
}
public void deposit(double amount) {
balance += amount;
}
public void withdraw(double amount) throws InsufficientFundsException {
if(amount <= balance) {
balance -= amount;
}else {
double needs = amount - balance;
throw new InsufficientFundsException(needs);
}
}
public double getBalance() {
return balance;
}
public int getNumber() {
return number;
}
}
다음 BankDemo 프로그램은 CheckingAccount의 deposit () 및 withdraw () 메서드를 호출하는 방법을 보여줍니다.
// File Name BankDemo.java
public class BankDemo {
public static void main(String [] args) {
CheckingAccount c = new CheckingAccount(101);
System.out.println("Depositing $500...");
c.deposit(500.00);
try {
System.out.println("\nWithdrawing $100...");
c.withdraw(100.00);
System.out.println("\nWithdrawing $600...");
c.withdraw(600.00);
} catch (InsufficientFundsException e) {
System.out.println("Sorry, but you are short $" + e.getAmount());
e.printStackTrace();
}
}
}
위의 세 파일을 모두 컴파일하고 BankDemo를 실행합니다. 이것은 다음 결과를 생성합니다-
산출
Depositing $500...
Withdrawing $100...
Withdrawing $600...
Sorry, but you are short $200.0
InsufficientFundsException
at CheckingAccount.withdraw(CheckingAccount.java:25)
at BankDemo.main(BankDemo.java:13)
일반적인 예외
Java에서는 예외 및 오류의 두 범주를 정의 할 수 있습니다.
JVM Exceptions− JVM에서 배타적으로 또는 논리적으로 발생하는 예외 / 오류입니다. 예 : NullPointerException, ArrayIndexOutOfBoundsException, ClassCastException.
Programmatic Exceptions− 이러한 예외는 애플리케이션 또는 API 프로그래머에 의해 명시 적으로 발생합니다. 예 : IllegalArgumentException, IllegalStateException.