Java에서 Throw와 Throw의 차이점

1. 소개

이 튜토리얼에서는 Java 의 throwthrow 에 대해 살펴 보겠습니다 . 언제 각각을 사용해야하는지 설명하겠습니다.

다음으로 기본 사용법의 몇 가지 예를 보여 드리겠습니다.

2. 던져예외

간단한 소개부터 시작하겠습니다. 이러한 키워드는 예외 처리와 관련이 있습니다. 애플리케이션의 정상적인 흐름이 중단되면 예외가 발생합니다.

많은 이유가있을 수 있습니다. 사용자가 잘못된 입력 데이터를 보낼 수 있습니다. 연결이 끊어 지거나 다른 예기치 않은 상황이 발생할 수 있습니다. 좋은 예외 처리는 이러한 불쾌한 순간이 나타난 후에도 애플리케이션이 계속 작동하도록하는 열쇠입니다.

throw 키워드를 사용 하여 코드에서 예외를 명시 적으로 throw합니다 . 모든 메서드 또는 정적 블록 일 수 있습니다. 이 예외는 Throwable 의 하위 클래스 여야합니다 . 또한 Throwable 자체 가 될 수 있습니다 . 한 번의 throw로 여러 예외를 throw 할 수 없습니다 .

Throws 키워드는 메서드 선언에 배치 할 수 있습니다. 이 메서드에서 발생할 수있는 예외를 나타냅니다. try-catch로 이러한 예외를 처리해야합니다.

이 두 키워드는 서로 바꿔서 사용할 수 없습니다!

3. 자바에서 던져

메서드에서 예외를 던지는 기본 예제를 살펴 보겠습니다.

우선, 우리가 간단한 계산기를 작성하고 있다고 상상해보십시오. 기본적인 산술 연산 중 하나는 나눗셈입니다. 이로 인해이 기능을 구현하도록 요청 받았습니다.

public double divide(double a, double b) { return a / b; }

0으로 나눌 수 없기 때문에 기존 코드를 약간 수정해야합니다. 예외를 제기하기에 좋은 순간 인 것 같습니다.

이렇게합시다 :

public double divide(double a, double b) { if (b == 0) { throw new ArithmeticException("Divider cannot be equal to zero!"); } return a / b; }

보시다시피, 우리는 우리의 필요에 완벽하게 맞는 ArithmeticException 을 사용했습니다 . 예외 메시지 인 단일 String 생성자 매개 변수를 전달할 수 있습니다 .

3.1. 좋은 습관

우리는 항상 가장 구체적인 예외를 선호해야합니다. 우리는 예외적 인 이벤트에 가장 적합한 클래스를 찾아야합니다. 예를 들어 IllegalArgumentException 대신 NumberFormatException 을 throw 합니다. 불특정 Exception 던지는 것을 피해야 합니다.

예를 들어, java.lang 패키지에 Integer 클래스가 있습니다. 팩토리 메서드 선언 중 하나를 살펴 보겠습니다.

public static Integer valueOf(String s) throws NumberFormatException 

String 에서 Integer 인스턴스 를 생성하는 정적 팩토리 메서드입니다 . 잘못된 입력 String 인 경우 메서드는 NumberFormatException 을 throw 합니다.

좋은 생각은 우리 자신의 더 설명적인 예외를 정의하는 것입니다. 우리에 계산기 클래스 예를 들어이 될 수있는 DivideByZeroException인지.

샘플 구현을 살펴 보겠습니다.

public class DivideByZeroException extends RuntimeException { public DivideByZeroException(String message) { super(message); } }

3.2. 기존 예외 래핑

때때로 우리는 기존 예외를 우리가 정의한 예외로 래핑하려고합니다.

우리 자신의 예외를 정의하는 것부터 시작합시다 :

public class DataAcessException extends RuntimeException { public DataAcessException(String message, Throwable cause) { super(message, cause); } }

생성자는 예외 메시지와 Throwable의 하위 클래스가 될 수있는 원인이라는 두 가지 매개 변수를 사용 합니다.

findAll () 함수에 대한 가짜 구현을 작성해 보겠습니다 .

public List findAll() throws SQLException { throw new SQLException(); }

이제 SimpleService 에서 SQLException 이 발생할 수있는 저장소 함수를 호출 해 보겠습니다 .

public void wrappingException() { try { personRepository.findAll(); } catch (SQLException e) { throw new DataAccessException("SQL Exception", e); } }

DataAccessException 이라는 자체 예외로 래핑 된 SQLException을 다시 던지고 있습니다. 모든 것은 다음 테스트로 확인됩니다.

@Test void whenSQLExceptionIsThrown_thenShouldBeRethrownWithWrappedException() { assertThrows(DataAccessException.class, () -> simpleService.wrappingException()); }

이렇게하는 데는 두 가지 이유가 있습니다. 우선, 나머지 코드는 시스템에서 가능한 모든 예외에 대해 알 필요가 없기 때문에 예외 래핑을 사용합니다.

또한 상위 수준의 구성 요소는 하위 수준의 구성 요소 나 발생하는 예외에 대해 알 필요가 없습니다.

3.3. 자바를 사용한 멀티 캐치

때때로 우리가 사용하는 메소드는 많은 다른 예외를 던질 수 있습니다.

보다 광범위한 try-catch 블록을 살펴 보겠습니다.

try { tryCatch.execute(); } catch (ConnectionException | SocketException ex) { System.out.println("IOException"); } catch (Exception ex) { System.out.println("General exception"); }

The execute method can throw three exceptions: SocketException, ConnectionException, Exception. The first catch block will catch ConnectionException or SocketException. The second catch block would catch Exception or any other subclass of Exception. Remember, that we should always catch a more detailed exception first.

We can swap the order of our catch blocks. Then, we'd never catch SocketException and ConnectionException because everything will go to the catch with Exception.

4. Throws in Java

We add throws to the method declaration.

Let's take a look at one of our previous method declaration:

public static void execute() throws SocketException, ConnectionException, Exception

The method may throw multiple exceptions. They are comma-separated at the end of a method declaration. We can put both, checked and unchecked exceptions in the throws. We have described the difference between them below.

4.1. Checked and Unchecked Exceptions

A checked exception means that it's checked at the compile time. Note, that we must handle this exception. Otherwise, a method must specify an exception by using throws keyword.

The most common checked exceptions are IOException, FileNotFoundException, ParseException. FileNotFoundException may be thrown when we create FileInputStream from File.

There's a short example:

File file = new File("not_existing_file.txt"); try { FileInputStream stream = new FileInputStream(file); } catch (FileNotFoundException e) { e.printStackTrace(); }

We can avoid using try-catch block by adding throws to the method declaration:

private static void uncheckedException() throws FileNotFoundException { File file = new File("not_existing_file.txt"); FileInputStream stream = new FileInputStream(file); }

Unfortunately, a higher level function still has to handle this exception. Otherwise, we have to put this exception in method declaration with throws keyword.

As the opposite, unchecked exceptions aren't checked at the compile time.

The most common unchecked exceptions are: ArrayIndexOutOfBoundsException, IllegalArgumentException, NullPointerException.

Unchecked exceptions are thrown during runtime. The following code will throw a NullPointerException. Probably it's one of the most common exceptions in Java.

Calling a method on a null reference will result in this exception:

public void runtimeNullPointerException() { String a = null; a.length(); }

Let's verify this behavior in the test:

@Test void whenCalled_thenNullPointerExceptionIsThrown() { assertThrows(NullPointerException.class, () -> simpleService.runtimeNullPointerException()); }

이 코드와 테스트는 의미가 없음을 기억하십시오. 런타임 예외를 설명하기위한 학습 목적으로 만 사용됩니다.

Java에서 ErrorRuntimeException 의 모든 하위 클래스 는 확인되지 않은 예외입니다. 확인 된 예외는 Throwable 클래스 아래의 모든 것 입니다.

5. 결론

이 기사에서는 throwthrows 라는 두 Java 키워드의 차이점에 대해 설명했습니다 . 우리는 기본적인 사용법을 살펴보고 모범 사례에 대해 조금 이야기했습니다 . 그런 다음 확인 및 확인되지 않은 예외에 대해 이야기했습니다.

항상 그렇듯이 소스 코드는 GitHub에서 찾을 수 있습니다.

Java에서 예외 처리에 대해 더 자세히 알아 보려면 Java 예외에 대한 기사를 참조하십시오.