선택 및 선택 취소된 예외 선택 시기
Java(또는 체크된 예외가 있는 다른 언어)에서 사용자 고유의 예외 클래스를 만들 때 해당 예외 클래스를 선택 또는 선택 취소할지 결정하는 방법은?
내 본능은, 전화를 건 사람이 어떤 생산적인 방법으로 회복할 수 있는 경우에 체크된 예외를 요구할 것이고, 체크되지 않은 예외는 회복할 수 없는 경우에 더 많을 것이지만, 나는 다른 사람의 생각에 관심을 가질 것이다.
선택한 예외는 언제 사용해야 하는지 이해한다면 훌륭하다.자바 코어 API는 SQLException(그리고 때로는 IOException)에 대해 이러한 규칙을 준수하지 못하기 때문에 그러한 규칙들이 그렇게 형편없는 것이다.
확인된 예외는 복구하기에 합리적인 예측 가능하지만 예측 불가능한 오류에 사용해야 한다.
선택되지 않은 예외는 다른 모든 항목에 사용해야 한다.
대부분의 사람들이 이 말이 무슨 뜻인지 오해하고 있기 때문에, 나는 너를 위해 이것을 분해할 것이다.
- 예측 가능하지만 예측 불가능:호출자는 입력 매개변수의 유효성을 확인하기 위해 전력 내에서 모든 작업을 수행했지만, 통제할 수 없는 일부 조건으로 인해 작업이 실패하였다.예를 들어, 파일을 읽으려고 시도하지만 파일이 존재하는지 확인하는 시간과 읽기 작업이 시작되는 시간 사이에 다른 사용자가 파일을 삭제하는 경우.체크된 예외를 선언함으로써, 당신은 발신자에게 이 실패를 예상하라고 말하고 있는 것이다.
- 합리적인 복구:전화를 건 사람들에게 회복할 수 없는 예외를 예상하라고 말하는 것은 의미가 없다.사용자가 존재하지 않는 파일에서 읽으려고 하면 호출자가 새 파일 이름을 입력하라는 메시지를 표시할 수 있다.한편, 프로그래밍 버그(잘못된 방법 인수 또는 버기 방법 구현)로 인해 방법이 실패하는 경우, 응용 프로그램이 실행 중반에 문제를 해결하기 위해 할 수 있는 것은 아무것도 없다.그것이 할 수 있는 최선은 문제를 기록하고 나중에 개발자가 고칠 때까지 기다리는 것이다.
던지는 예외가 위의 조건을 모두 충족하지 않는 한, 선택되지 않은 예외를 사용해야 한다.
모든 수준에서 재평가:때로는 체크된 예외를 잡는 방법이 오류를 처리하는 데 적합하지 않다.그런 경우, 자신의 발신자에게 합리적인 것이 무엇인지 생각해 보십시오.만약 예외조항이 예측 가능하고, 예측 불가능하며, 그들이 회복할 수 있는 합리적인 것이라면, 당신은 스스로 체크된 예외조항을 제기해야 한다.그렇지 않은 경우 예외를 선택되지 않은 예외로 포장하십시오.이 규칙을 따르면 체크된 예외를 체크되지 않은 예외로 변환하거나 현재 어떤 계층에 있는지에 따라 그 반대로 변환하는 자신을 발견할 수 있다.
선택한 예외와 선택하지 않은 예외 모두에 대해 올바른 추상화 수준을 사용하십시오.예를 들어, 두 개의 다른 구현(데이터베이스 및 파일 시스템)이 있는 코드 리포지토리는 다음을 수행하여 구현별 세부 정보가 노출되지 않도록 해야 한다.SQLException
또는IOException
대신, 예외를 모든 구현(예: 모든 구현)에 걸쳐 있는 추상화로 포장해야 한다.RepositoryException
).
예외가 발생하면 당신은 예외를 포착하여 처리해야 하거나, 컴파일러에게 당신의 방법이 그러한 예외를 발생시킨다고 선언하여 처리할 수 없다고 말해야 한다. 그러면 당신의 방법을 사용하는 코드는 그 예외를 처리해야 할 것이다(또한 예외를 처리할 수 없다면 예외를 발생시킨다고 선언하는 것을 선택할 수도 있다).
컴파일러는 우리가 두 가지 일(캐치 또는 선언) 중 하나를 했는지 확인할 것이다.그래서 이것을 체크된 예외라고 부른다.그러나 오류 및 런타임 예외는 컴파일러에 의해 확인되지 않는다(수집 또는 선언하도록 선택할 수 있지만 필요하지 않음).그래서 이 두 가지를 '선택되지 않은 예외'라고 부른다.
오류는 시스템 충돌과 같이 애플리케이션 외부에서 발생하는 조건을 나타내기 위해 사용된다.런타임 예외는 대개 애플리케이션 로직의 오류에 의해 발생한다.이런 상황에서는 아무것도 할 수 없다.런타임 예외가 발생하면 프로그램 코드를 다시 작성해야 한다.그래서 이것들은 컴파일러에 의해 확인되지 않는다.이러한 런타임 예외사항은 개발 및 시험 기간에 공개될 것이다.그러면 우리는 이러한 오류를 제거하기 위해 코드를 리팩터링해야 한다.
내가 사용하는 규칙은: 체크되지 않은 예외는 절대 사용하지 마! (또는 다른 방법이 보이지 않을 때)
그 반대의 경우는 매우 강하다.선택한 예외를 사용하지 마십시오.나는 토론에서 편을 드는 것을 꺼리지만, 체크된 예외를 도입하는 것이 사후 판단에서 잘못된 결정이라는 폭넓은 공감대가 있는 것 같다.제발 메신저를 쏘지 말고 그런 주장들을 참고해줘.
많은 계층이 있는 충분히 큰 시스템에서는, 어쨌든, 예외를 처리하는 방법을 처리하기 위한 아키텍처 수준 전략이 필요하므로, 점검된 예외는 무용지물이다(고장벽 사용).
점검된 예외를 제외하고, 당신의 상태 조절 오류는 미세하게 관리되고 어떤 큰 시스템에서도 견딜 수 없다.
API 호출자가 어떤 계층에 있는지 모르기 때문에 오류가 "복구 가능한"지 모르는 경우가 대부분이다.
정수의 문자열 표현을 Int로 변환하는 StringToInt API를 만든다고 합시다.API가 "foo" 문자열로 호출되는 경우 체크된 예외를 적용해야 하는가?회복이 가능한가?나는 그의 계층에서 내 StringToInt API의 호출자가 이미 입력을 검증했을 수 있고, 만약 이 예외가 발생한다면 그것은 버그나 데이터 손상이므로 이 계층에 대해 복구할 수 없기 때문에 잘 모르겠다.
이 경우 API 호출자는 예외를 포착하지 않으려 한다.그는 단지 예외를 "버블업"으로 두기를 원한다.만약 내가 체크된 예외를 선택한다면, 이 발신자는 그 예외를 인위적으로 다시 던지기 위해서만 쓸모없는 많은 캐치 블록을 갖게 될 것이다.
회수가 가능한 것은 API의 writer가 아닌 API의 호출자에게 대부분의 시간을 의존한다.API는 체크되지 않은 예외만 예외를 포착하거나 무시하도록 선택할 수 있으므로 체크된 예외를 사용해서는 안 된다.
네 말이 맞아.
체크되지 않은 예외는 시스템이 빨리 고장나도록 하는 데 사용되는데, 이것은 좋은 일이다.제대로 작동하기 위해서는 어떤 방법이 기대되는지를 분명히 밝혀야 한다.이렇게 하면 입력의 유효성을 한 번만 확인할 수 있다.
예를 들어,
/**
* @params operation - The operation to execute.
* @throws IllegalArgumentException if the operation is "exit"
*/
public final void execute( String operation ) {
if( "exit".equals(operation)){
throw new IllegalArgumentException("I told you not to...");
}
this.operation = operation;
.....
}
private void secretCode(){
// we perform the operation.
// at this point the opreation was validated already.
// so we don't worry that operation is "exit"
.....
}
예를 들자면.요점은, 시스템이 빨리 고장나면 어디서 왜 실패했는지 알 수 있다는 겁니다.당신은 다음과 같은 스택트레이스를 받게 될 것이다.
IllegalArgumentException: I told you not to use "exit"
at some.package.AClass.execute(Aclass.java:5)
at otherPackage.Otherlass.delegateTheWork(OtherClass.java:4569)
ar ......
그리고 무슨 일이 있었는지 알게 될 거야"더 클래스"의 "더 클래스TheWork' 방법 (4569행 )은 당신의 클래스를 "퇴장" 값으로 불렀는데, 그 등은 안 될 때도 그랬다.
그렇지 않으면 당신은 당신의 코드에 검증을 뿌려야 할 것이고 그것은 오류가 발생하기 쉽다.게다가, 때때로 무엇이 잘못되었는지 추적하기 어렵고 당신은 몇 시간의 답답한 디버깅을 기대할 수 있다.
NullPointer에서도 동일한 현상이 발생함예외만약 당신이 30개의 속성을 사용하는 약 15개의 방법을 가진 700개의 라인 클래스를 가지고 있다면, 그 속성들 중 어느 것도 null일 수 없다. 만약 무효화에 대한 각각의 방법에서 검증하는 대신에, 당신은 그러한 속성들을 읽기 전용으로 만들 수 있다. 그리고 그것들을 생성자 또는 공장 방법으로 검증할 수 있다.
public static MyClass createInstane( Object data1, Object data2 /* etc */ ){
if( data1 == null ){ throw NullPointerException( "data1 cannot be null"); }
}
// the rest of the methods don't validate data1 anymore.
public void method1(){ // don't worry, nothing is null
....
}
public void method2(){ // don't worry, nothing is null
....
}
public void method3(){ // don't worry, nothing is null
....
}
Checked exceptions 프로그래머(사용자 또는 동료)가 모든 작업을 올바르게 수행하고, 입력을 검증하고, 테스트를 실행했으며, 모든 코드가 완벽할 때 유용하지만, 코드가 다운될 수 있는 타사 웹 서비스(또는 사용 중인 파일이 다른 외부 프로세스에 의해 삭제됨 등)에 연결될 수 있다.연결을 시도하기 전에 웹 서비스가 유효성을 검사할 수도 있지만, 데이터 전송 중에 뭔가 잘못되었다.
그 시나리오에서는 당신이나 동료들이 그것을 돕기 위해 할 수 있는 것은 아무것도 없다.하지만 여전히 무언가를 해야 하고 사용자의 눈에 애플리케이션만 죽거나 사라지게 해서는 안 된다.그것에 대해 체크된 예외를 사용하고 예외를 처리할 수 있다. 대부분의 경우 오류를 기록하고 작업(앱 작업)을 저장하여 사용자에게 메시지를 표시하려고 시도한다. (사이트 블레이블라가 다운되었으므로 나중에 다시 시도하십시오.)
만약 체크된 예외가 과도하게 사용된다면(모든 방법 서명에 "drow exception"을 추가함으로써), 당신의 코드는 매우 취약해질 것이다. 왜냐하면 모든 사람들이 (너무 일반적이기 때문에) 그 예외를 무시하게 될 것이고 코드의 품질은 심각하게 손상될 것이기 때문이다.
선택되지 않은 예외를 과도하게 사용하면 유사한 일이 발생할 것이다.그 코드의 사용자들은 무언가가 잘못될 수 있는지 많이 알지 못한다.{...}}캐치(던지기 가능 t )가 나타날 것이다.
이것이 나의 '최종적 엄지손가락 법칙'이다.
사용하는 항목:
- 호출자로 인한 실패에 대한 내 메서드 코드 내에서 선택되지 않은 예외(명시하고 완전한 문서 포함)
- 내 코드를 사용하고자 하는 사람에게 명시적으로 해야 하는 결함으로 인한 실패에 대한 예외 확인
앞의 답변과 비교했을 때, 이것은 한 가지 또는 다른 종류의 예외(또는 두 가지 모두)의 사용에 대한 명확한 근거(동의하거나 반대할 수 있는 근거)이다.
두 예외 모두 매우 일반적인 체크되지 않은 예외(예: NullPointer)를 제외하고, 내 응용 프로그램에 대해 선택되지 않은 고유한 예외(여기 언급된 모범 사례)를 만들 것이다.예외)
예를 들어, 아래 특정 기능의 목표는 물체를 만드는(또는 이미 존재하는 경우
의미:
- 만들거나 가져올 개체의 컨테이너가 존재해야 함(Caller의 책임)
=> 선택되지 않은 예외, 그리고 이 호출된 함수에 대한 자바도크 주석 지우기) - 다른 매개 변수는 null일 수 없음
(전화 걸기 코더 선택: 코더가 null 매개변수를 확인하지 않고 코더가 DOS DOCATION IT를 문서화함) - 결과가 NULL일 수 없음
(발신자에게 큰 관심이 될 수 있는 선택, 캘리브 코드 선택 및 선택)
=> 체크된 예외는 모든 발신자가 객체를 생성/발견할 수 없는 경우 반드시 결정을 내려야 하기 때문에, 그리고 그 결정은 컴파일 시간에 시행되어야 하기 때문이다. 즉, 그들은 이 가능성을 다루지 않고는 이 기능을 사용할 수 없다. 즉, 이 체크된 예외를 의미한다.
예:
/**
* Build a folder. <br />
* Folder located under a Parent Folder (either RootFolder or an existing Folder)
* @param aFolderName name of folder
* @param aPVob project vob containing folder (MUST NOT BE NULL)
* @param aParent parent folder containing folder
* (MUST NOT BE NULL, MUST BE IN THE SAME PVOB than aPvob)
* @param aComment comment for folder (MUST NOT BE NULL)
* @return a new folder or an existing one
* @throws CCException if any problems occurs during folder creation
* @throws AssertionFailedException if aParent is not in the same PVob
* @throws NullPointerException if aPVob or aParent or aComment is null
*/
static public Folder makeOrGetFolder(final String aFoldername, final Folder aParent,
final IPVob aPVob, final Comment aComment) throws CCException {
Folder aFolderRes = null;
if (aPVob.equals(aParent.getPVob() == false) {
// UNCHECKED EXCEPTION because the caller failed to live up
// to the documented entry criteria for this function
Assert.isLegal(false, "parent Folder must be in the same PVob than " + aPVob); }
final String ctcmd = "mkfolder " + aComment.getCommentOption() +
" -in " + getPNameFromRepoObject(aParent) + " " + aPVob.getFullName(aFolderName);
final Status st = getCleartool().executeCmd(ctcmd);
if (st.status || StringUtils.strictContains(st.message,"already exists.")) {
aFolderRes = Folder.getFolder(aFolderName, aPVob);
}
else {
// CHECKED EXCEPTION because the callee failed to respect his contract
throw new CCException.Error("Unable to make/get folder '" + aFolderName + "'");
}
return aFolderRes;
}
예외에서 회복할 수 있는 능력만이 문제가 아니다.내 생각에 가장 중요한 것은 전화를 건 사람이 예외를 잡는 데 관심이 있느냐 없느냐 하는 것이다.
다른 곳에서 사용할 라이브러리를 작성하거나 응용 프로그램의 하위 계층을 작성할 경우, 발신자가 사용자의 예외를 파악하는 데 관심이 있는지 자신에게 물어보십시오.만약 그렇지 않다면, 당신은 그에게 불필요하게 부담을 주지 않도록, 배제하지 않은 예외를 사용하라.
이것이 많은 틀에서 사용하는 철학이다.특히 봄과 겨울잠이 떠오른다. 자바에서 체크된 예외가 과도하게 사용되기 때문에, 그들은 정확히 알려진 체크된 예외를 체크되지 않은 예외로 변환한다.내가 생각해 낼 수 있는 한 예는 json.org의 JSONException인데, 이것은 체크된 예외 사항이고 대부분 짜증나는 것이다 - 그것은 체크되지 않아야 하지만 개발자는 단지 그것을 끝까지 생각해보지 않았다.
그런데, 예외에 대한 발신자의 관심은 대부분 예외로부터 회복할 수 있는 능력과 직결되어 있지만, 항상 그런 것은 아니다.
여기 당신의 체크/미체크 딜레마에 대한 매우 간단한 해결책이 있다.
규칙 1: 코드가 실행되기 전에 선택되지 않은 예외를 테스트 가능한 조건으로 생각하십시오.예를 들어…
x.doSomething(); // the code throws a NullPointerException
여기서 x는 null...…코드에 다음 사항이 있을 수 있음...
if (x==null)
{
//do something below to make sure when x.doSomething() is executed, it won’t throw a NullPointerException.
x = new X();
}
x.doSomething();
규칙 2: 체크된 예외를 코드가 실행되는 동안 발생할 수 있는 테스트할 수 없는 조건이라고 생각해 보십시오.
Socket s = new Socket(“google.com”, 80);
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
…위의 예에서, DNS 서버가 다운되어 URL(google.com)을 사용할 수 없을 수 있다.DNS 서버가 작동 중인 순간에도 'google.com' 이름을 IP 주소로 확인했는데, google.com에 접속하면 언제든 애프터 워드로 네트워크가 다운될 수 있다.스트림을 읽고 쓰기 전에 네트워크를 항상 테스트할 수는 없다.
문제가 있는지 알기 전에 코드를 실행해야 할 때가 있다.개발자들에게 Checked Exception을 통해 이러한 상황을 다루도록 강요하는 방식으로 코드를 쓰도록 강요함으로써, 나는 이 개념을 발명한 자바의 창조자에게 내 모자를 기울여야 한다.
일반적으로 자바에 있는 거의 모든 API는 위의 두 가지 규칙을 따른다.파일에 쓰려고 하면 쓰기 전에 디스크가 가득 찰 수 있다.다른 공정으로 인해 디스크가 꽉 찼을 가능성이 있다.이 상황을 시험할 방법이 전혀 없다.언제든지 하드웨어를 사용할 때 오류가 발생할 수 있는 하드웨어와 상호 작용하는 사용자에게 체크된 예외가 이 문제에 대한 우아한 해결책인 것 같다.
이것에는 애매한 부분이 있다.많은 테스트가 필요한 경우(&&&, ||를 많이 쓴다면 마음이 흔들린다)에 던져지는 예외는 단순히 맞추기가 너무 힘들기 때문에 CheckedException이 될 것이다. 단순히 이 문제가 프로그래밍 오류라고 말할 수는 없다.테스트가 10개보다 훨씬 적을 경우(예: 'if (x == null)'), 프로그래머 오류는 UncontinuedException이어야 한다.
언어 통역사를 대할 때 상황은 흥미로워진다.위의 규칙에 따라 구문 오류를 선택됨 또는 선택되지 않음 예외로 간주해야 하는가?언어 구문을 실행하기 전에 테스트할 수 있다면 언어가 UncludedException이어야 한다고 주장하고 싶다.개인 컴퓨터에서 어셈블리 코드가 실행되는 방법과 유사하게 언어를 테스트할 수 없는 경우 구문 오류는 확인 예외여야 한다.
위의 두 가지 규칙은 아마도 어떤 것을 선택할지에 대한 당신의 관심의 90%를 제거할 것이다.규칙을 요약하려면 이 패턴을 따르십시오… 1) 실행할 코드가 실행되기 전에 테스트되어 올바르게 실행될 수 있는지, 예외(예: 프로그래머 오류)가 발생하면 예외는 체크되지 않은 예외(Runtime의 하위 클래스)가 되어야 한다.예외)2) 실행될 코드가 제대로 실행되기 전에 테스트할 수 없는 경우, 예외는 Checked Exception(Exception의 하위 클래스)이어야 한다.
선택되거나 선택되지 않은 예외라고 할 수 있지만, 두 가지 유형의 예외는 모두 프로그래머가 잡을 수 있으므로 가장 좋은 대답은 예외를 모두 선택되지 않은 것으로 기록하고 문서화하는 것이다.그렇게 하면 당신의 API를 사용하는 개발자가 그 예외를 포착하고 어떤 일을 하고 싶은지 선택할 수 있다.체크된 예외는 모든 사람의 시간을 완전히 낭비하는 것이고 그것은 당신의 코드를 보면 충격적인 악몽이 된다.적절한 유닛 테스트는 여러분이 포착해서 무언가를 해야 할지도 모르는 어떤 예외를 제기할 것이다.
선택한 예외:클라이언트가 예외에서 복구할 수 있으며 계속하려면 선택한 예외를 사용하십시오.
선택되지 않은 예외:예외 이후 고객이 아무 것도 할 수 없는 경우, 체크되지 않은 예외를 제기하십시오.
예:만약 당신이 방법 A()에서 그리고 A()의 출력에 기초하여 산술 연산을 해야 한다면, 당신은 다른 연산을 해야 한다.실행 시간 동안 예상하지 못한 방법 A()에서 출력이 null이면 실행 시간 예외인 Null 포인터 예외를 발생시켜야 한다.
여기를 참조하십시오.
다년간의 개발 경험을 통해 얻은 의견을 나누고자 한다.
확인 예외.이는 비즈니스 활용 사례 또는 통화 흐름의 일부분이며, 이는 우리가 기대하거나 기대하지 않는 애플리케이션 로직의 일부분이다.예를 들어 연결 거부, 조건이 충족되지 않는 등우리는 그것을 처리하고 무엇이 일어났는지 그리고 다음에 무엇을 해야 하는지 지시와 함께 사용자에게 상응하는 메시지를 보여줄 필요가 있다(나중에 다시 시도하라.나는 보통 이것을 후처리 예외 또는 "사용자" 예외라고 부른다.
선택되지 않은 예외.이는 프로그래밍 예외의 일부로서 소프트웨어 코드 프로그래밍의 일부 실수(bug, 결함)이며 프로그래머가 설명서에 따라 API를 어떻게 사용해야 하는지를 반영한다.외부 lib/framework 문서가 NPE 또는 ForganArgument로 인해 NULL이 아닌 범위에서 데이터를 가져올 것으로 예상하는 경우예외를 발생시키므로 프로그래머는 이를 예상해야 하며 설명서에 따라 API를 올바르게 사용해야 한다.그렇지 않으면 예외가 발생할 것이다.나는 보통 그것을 전처리 예외 또는 "유효확인" 예외라고 부른다.
대상 관객에 의해.이제 (내 의견에 따라) 예외조항이 고안된 대상 청중이나 그룹에 대해 이야기해 봅시다.
- 확인 예외.대상 고객은 사용자/고객이다.
- 선택되지 않은 예외.대상 청중은 개발자.즉, 선택되지 않은 예외는 개발자만을 위해 설계된다.
애플리케이션 개발 라이프사이클 단계별.
- 점검된 예외는 애플리케이션이 예외적인 경우를 처리하는 정상적인 예상 메커니즘으로서 전체 생산 라이프사이클 동안 존재하도록 설계된다.
- 확인되지 않은 예외는 애플리케이션 개발/테스트 라이프사이클 동안만 존재하도록 설계되며, 이 예외는 모두 해당 기간 동안 수정되어야 하며, 애플리케이션이 이미 프로덕션에서 실행 중일 때 발생해서는 안 된다.
프레임워크가 일반적으로 확인되지 않은 예외(예: 스프링)를 사용하는 이유는 프레임워크가 애플리케이션의 비즈니스 논리를 결정할 수 없기 때문이며, 이는 개발자들이 이를 포착하고 자신의 논리를 설계하는 데 달려 있다.
나는 특히 API를 설계할 때 체크되지 않은 예외를 원칙으로 선호한다는 것에 동의한다.호출자는 항상 문서화되고 확인되지 않은 예외를 포착하도록 선택할 수 있다.너는 단지 전화를 건 사람에게 불필요하게 강요하는 것이 아니야.
확인된 예외는 하위 수준에서 구현 세부사항으로 유용하다는 것을 알게 되었다.종종 특정한 오류 "반환 코드"를 관리해야 하는 것보다 제어 메커니즘의 흐름이 더 나은 것처럼 보인다.때때로 낮은 수준의 코드 변경에 대한 아이디어의 영향을 보는 데 도움이 될 수 있다...다운스트림에서 점검된 예외를 선언하고 누구를 조정해야 할지 검토한다.일반적인 것이 많은 경우 이 마지막 지점은 적용되지 않는다: 캐치(예외 e) 또는 일반적으로 잘 고려되지 않는 예외를 던진다.
우리는 프로그래머 에러인지 아닌지 여부에 따라 이 두 가지 유형의 예외를 구분해야 한다.
- 오류가 프로그래머 오류인 경우, 선택되지 않은 예외여야 한다.예: SQLException/IOException/NullPointer예외.이러한 예외는 프로그래밍 오류다.그것들은 프로그래머에 의해 처리되어야 한다.JDBC API에서 SQLLException이 Checked Exception, In Spring JDB에 있음CTEMplate 이것은 선택되지 않은 예외다.프로그래머는 Spring을 사용할 때 SQLException에 대해 걱정하지 않는다.
- 오류가 프로그래머 오류가 아니고 외부에서 발생한 오류일 경우, 이는 체크된 예외여야 한다.예를 들어 파일을 삭제하거나 다른 사용자가 파일 권한을 변경한 경우 파일을 복구해야 한다.
FileNotFoundException은 미묘한 차이를 이해하는 좋은 예다.파일을 찾을 수 없는 경우 FileNotFoundException이 발생함이 예외에는 두 가지 이유가 있다.파일 경로가 개발자에 의해 정의되거나 GUI를 통해 최종 사용자로부터 가져오는 경우, 선택되지 않은 예외여야 한다.다른 사용자가 파일을 삭제한 경우, 해당 파일은 [체크된 예외]여야 한다.
Checked Exception은 두 가지 방법으로 처리할 수 있다.이들은 시도 캐치를 사용하거나 예외를 전파한다.예외 전파의 경우 예외 취급 때문에 콜 스택의 모든 방법이 긴밀하게 결합된다.그렇기 때문에 우리는 Checked Exception을 신중하게 사용해야 해.
레이어드 엔터프라이즈 시스템을 개발하는 경우 대부분 체크되지 않은 예외를 선택하여 버려야 하지만, 아무것도 할 수 없는 경우에는 체크된 예외를 사용하는 것을 잊지 마십시오.
확인된 예외는 호출자에게 정보를 제공하려는 복구 가능한 경우(즉, 권한이 부족하거나 파일을 찾을 수 없는 경우 등)에 유용하다.
사용자나 프로그래머에게 런타임 중 심각한 오류나 예기치 않은 상황을 알리기 위해 체크되지 않은 예외는 거의 사용되지 않는다.컴파일러가 사용자의 소프트웨어를 강제로 잡거나 선언하지 않으므로 소프트웨어가 확인되지 않은 예외를 발생시킬 것으로 예상하지 않을 수 있으므로 다른 사용자가 사용할 코드나 라이브러리를 작성하는 경우 이러한 예외를 두지 마십시오.
예외를 예상하지 못하는 경우, 그리고 우리는 그것을 잡은 후에도 진행할 수 있고, 우리는 그 예외를 피하기 위해 어떤 것도 할 수 없다. 그러면 우리는 체크된 예외를 사용할 수 있다.
특정 예외가 발생할 때와 해당 예외가 예상되지만 확실하지 않을 때 의미 있는 작업을 하고 싶을 때마다 체크된 예외를 사용할 수 있다.
예외가 다른 계층을 탐색할 때마다 모든 계층에서 예외를 포착할 필요는 없으며, 이 경우 런타임 예외 또는 래핑 예외를 선택되지 않은 예외로 사용할 수 있다.
런타임 예외는 예외가 발생할 가능성이 가장 높고, 더 이상 나아갈 방법이 없으며, 복구할 수 있는 것이 없을 때 사용된다.그래서 이 경우 우리는 그 예외와 관련하여 예방조치를 취할 수 있다.EX: NULLPointer예외, ArrayOutofBoundsException.이런 일이 일어날 가능성이 더 높다.이 시나리오에서는 이러한 예외를 피하기 위해 코딩하는 동안 예방 조치를 취할 수 있다.그렇지 않으면 우리는 어디에나 시도 캐치 블록을 써야 할 것이다.
더 많은 일반 예외를 선택 해제할 수 있으며, 더 적은 일반을 선택한다.
나는 우리가 몇 가지 질문으로부터 엑소스를 생각할 수 있다고 생각한다.
왜 탈출이 일어날까?그런 일이 일어나면 우리는 무엇을 할 수 있을까?
실수로 벌레가 생겼어예를 들어, null object의 메서드가 호출한다.
String name = null;
... // some logics
System.out.print(name.length()); // name is still null here
이런 종류의 예외는 시험 중에 고쳐져야 한다.그렇지 않으면 생산이 중단되고, 당신은 즉시 고쳐야 할 매우 높은 버그를 갖게 된다.이런 종류의 예외는 확인할 필요가 없다.
외부로부터의 입력에 의해 외부 서비스의 출력을 제어하거나 신뢰할 수 없다.
String name = ExternalService.getName(); // return null
System.out.print(name.length()); // name is null here
여기서 이름이 null일 때 계속하려면 null인지 여부를 확인해야 할 수도 있고, 그렇지 않으면 그냥 내버려두면 여기서 멈추고 호출자에게 런타임 예외를 부여할 수도 있다.이런 종류의 예외는 확인할 필요가 없다.
외부로부터의 런타임 예외에 의해, 외부 서비스를 제어하거나 신뢰할 수 없다.
여기서 ExternalService가 발생할 때 계속하려면 ExternalService의 모든 예외를 파악해야 할 수 있으며, 그렇지 않으면 그대로 두면 여기서 중지되고 호출자에게 런타임 예외를 부여할 수 있다.
외부로부터의 예외에 의해, 당신은 외부 서비스를 통제하거나 신뢰할 수 없다.
여기서 ExternalService가 발생할 때 계속하려면 ExternalService의 모든 예외를 파악해야 할 수 있으며, 그렇지 않으면 그대로 두면 여기서 중지되고 호출자에게 런타임 예외를 부여할 수 있다.
이 경우 ExternalService에서 어떤 예외가 발생했는지 알아야 하는가?다음에 따라 달라진다.
만약 당신이 어떤 종류의 예외를 처리할 수 있다면, 당신은 그것들을 잡고 처리해야 한다.다른 사람들은 거품을 내라.
사용자에게 특정 실행이 필요한 경우 로그나 응답을 받을 수 있다.다른 사람들은 거품을 내라.
응용 프로그램 예외를 선언할 때 선택되지 않은 예외, 즉 런타임의 하위 클래스가 되어야 한다고 생각한다.예외.트라이캐치로 애플리케이션 코드를 어수선하게 하지 않고 방법에 선언문을 던지기 때문이다.만약 당신의 애플리케이션이 Java API를 사용하고 있다면, Java API는 어쨌든 처리해야 할 예외를 발생시킨다.다른 경우, 응용 프로그램은 확인되지 않은 예외를 발생시킬 수 있다.애플리케이션 호출자가 여전히 확인되지 않은 예외를 처리해야 하는 경우, 이를 수행할 수 있다.
내가 사용하는 규칙은: 체크되지 않은 예외는 절대 사용하지 마! (또는 다른 방법이 보이지 않을 때)
개발자가 당신의 라이브러리를 사용하거나 최종 사용자가 당신의 라이브러리/애플리케이션을 사용하는 관점에서 볼 때, 생각지도 않은 예외로 인해 충돌하는 어플리케이션에 직면하는 것은 정말 짜증나는 일이다.그리고 모든 것을 캐치-올에 기대는 것도 좋지 않다.
이러한 방식으로 최종 사용자는 애플리케이션이 완전히 사라지는 대신 오류 메시지를 계속 표시할 수 있다.
참조URL: https://stackoverflow.com/questions/27578/when-to-choose-checked-and-unchecked-exceptions
'IT이야기' 카테고리의 다른 글
SPA VueJS에서 mapState 및 mapUtions를 전체적으로 선언 (0) | 2022.04.19 |
---|---|
"__attribute__(포장, 정렬(4))"의 의미는 무엇인가? (0) | 2022.04.19 |
vuej에서 vuex를 사용하여 소품을 통해 상태 항목을 가져오는 방법 (0) | 2022.04.19 |
Java에서 null 및 빈 컬렉션을 검증하는 모범 사례 (0) | 2022.04.19 |
한 줄에 배열 목록 초기화 (0) | 2022.04.19 |