예외는 호출 메소드가 가능하더라도 즉시 호출 코드가 처리 할 준비가되지 않는 조건을 나타내야합니다 . 예를 들어, 파일에서 일부 데이터를 읽는 코드는 유효한 파일이 유효한 레코드로 끝나고 부분 레코드에서 정보를 추출 할 필요가 없다고 합법적으로 가정 할 수 있습니다.
읽기 데이터 루틴이 예외를 사용하지 않고 읽기 성공 여부를 단순히보고 한 경우 호출 코드는 다음과 같아야합니다.
temp = dataSource.readInteger();
if (temp == null) return null;
field1 = (int)temp;
temp = dataSource.readInteger();
if (temp == null) return null;
field2 = (int)temp;
temp = dataSource.readString();
if (temp == null) return null;
field3 = temp;
유용한 각 작업에 대해 세 줄의 코드를 사용하는 등 반대로, readInteger
파일의 끝에서 발생하면 예외가 발생하고 호출자가 단순히 예외를 전달할 수 있으면 코드는 다음과 같이됩니다.
field1 = dataSource.readInteger();
field2 = dataSource.readInteger();
field3 = dataSource.readString();
일이 정상적으로 작동하는 경우에 훨씬 더 중점을 두어 훨씬 간단하고 깔끔하게 보입니다. 직접 호출자 가 조건을 처리 할 것으로 예상되는 경우 오류 코드를 리턴하는 메소드가 예외를 발생시키는 메소드보다 종종 도움이됩니다. 예를 들어 파일의 모든 정수를 합산하려면 다음을 수행하십시오.
do
{
temp = dataSource.tryReadInteger();
if (temp == null) break;
total += (int)temp;
} while(true);
대
try
{
do
{
total += (int)dataSource.readInteger();
}
while(true);
}
catch endOfDataSourceException ex
{ // Don't do anything, since this is an expected condition (eventually)
}
정수를 요구하는 코드는 이러한 호출 중 하나가 실패 할 것으로 예상합니다. 코드가 끝없는 루프를 사용하게되면 리턴 값을 통해 실패를 나타내는 방법을 사용하는 것보다 훨씬 효율적입니다.
클래스는 종종 클라이언트가 어떤 조건을 기대할 것인지 알지 못하기 때문에 일부 발신자가 기대할 수있는 방식으로 실패 할 수있는 다른 두 가지 버전의 메소드를 제공하는 것이 도움이 될 수 있습니다. 그렇게하면 두 가지 유형의 발신자 모두에게 이러한 방법을 깔끔하게 사용할 수 있습니다. 상황이 발생하면 호출자가 예상하지 못한 "try"메소드도 예외를 처리해야합니다. 예를 들어, tryReadInteger
깨끗한 파일 끝 조건이 발생하면 예외를 발생시키지 않아야합니다 (발신자가 예상하지 못한 경우, 발신자는readInteger
). 반면에 데이터를 포함하는 메모리 스틱이 분리되어 데이터를 읽을 수없는 경우 예외가 발생합니다. 이러한 이벤트는 항상 가능성으로 인식되어야하지만 즉각적인 호출 코드가 응답에 유용한 작업을 수행 할 준비가되지는 않습니다. 파일 끝 조건과 같은 방식으로보고되지 않아야합니다.