자바 이상 처리 에 대한 몇 가지 제안동력 노드 자바 대학 정리
Point Advice:이상 은 비정상적인 조건 에 만 사용 되 어야 합 니 다.그들 은 영원히 정상 적 인 제어 흐름 에 사용 되 어 서 는 안 됩 니 다.
아래 의 두 코드 를 비교 하여 설명 하 다.
코드 1
try {
int i=0;
while (true) {
arr[i]=0;
i++;
}
} catch (IndexOutOfBoundsException e) {
}
코드 2
for (int i=0; i<arr.length; i++) {
arr[i]=0;
}
두 코드 의 역할 은 모두 arr 배열 을 옮 겨 다 니 며 배열 의 모든 요소 의 값 을 0 으로 설정 합 니 다.코드 1 은 이상 을 통 해 종 료 됩 니 다.매우 어려워 보 입 니 다.코드 2 는 배열 경 계 를 통 해 종 료 됩 니 다.우 리 는 코드 1 이라는 방식 을 피해 야 한다.주요 원인 은 세 가지 가 있다.
public class Advice1 {
private static int[] arr = new int[]{1,2,3,4,5};
private static int SIZE = 10000;
public static void main(String[] args) {
long s1 = System.currentTimeMillis();
for (int i=0; i<SIZE; i++)
endByRange(arr);
long e1 = System.currentTimeMillis();
System.out.println("endByRange time:"+(e1-s1)+"ms" );
long s2 = System.currentTimeMillis();
for (int i=0; i<SIZE; i++)
endByException(arr);
long e2 = System.currentTimeMillis();
System.out.println("endByException time:"+(e2-s2)+"ms" );
}
// arr :
private static void endByException(int[] arr) {
try {
int i=0;
while (true) {
arr[i]=0;
i++;
//System.out.println("endByRange: arr["+i+"]="+arr[i]);
}
} catch (IndexOutOfBoundsException e) {
}
}
// arr :
private static void endByRange(int[] arr) {
for (int i=0; i<arr.length; i++) {
arr[i]=0;
//System.out.println("endByException: arr["+i+"]="+arr[i]);
}
}
}
실행 결과:
endByRange time:8ms
endByException time:16ms
그 결과 이상 을 통 해 옮 겨 다 니 는 속도 가 일반 방식 보다 훨씬 느 립 니 다!제2 조:복구 가능 한 조건 에 대해 검 사 된 이상 을 사용 하고 프로그램 오류 에 대해 실행 시 이상 을 사용 합 니 다.
Arithmetic Exception(예 를 들 어 나 누 기 는 0),Index OutOf Bounds Exception(예 를 들 어 배열 이 경 계 를 넘 는 것)등 은 모두 운행 시 이상 에 속한다.이런 이상 에 대해 우 리 는 코드 수정 을 통 해 그것 이 발생 하지 않도록 해 야 한다.검 사 된 이상 에 대해 서 는 처 리 를 통 해 프로그램 을 다시 실행 시 킬 수 있다.예 를 들 어 한 사용자 가 충분 한 수량 을 저장 하지 않 았 기 때문에 그 가 유 료 전화 에서 호출 을 하려 고 하면 실패 할 것 이다.그래서 검사 이상 을 던 졌 다.
제3 조:검 사 된 이상 을 불필요 하 게 사용 하지 않도록 한다.
'검 사 된 이상'은 자바 언어의 좋 은 특성 이다.반환 코드 와 달리'검 사 된 이상'은 프로그래머 에 게 예외 적 인 조건 을 강요 해 프로그램의 신뢰성 을 크게 높 인 다.
그러나 검사 이상 을 지나치게 사용 하면 API 사용 이 불편 하 다.한 방법 이 하나 이상 검 사 된 이상 을 던 지면 이 방법 을 호출 하 는 코드 는 하나 이상 catch 구문 블록 에서 이 이상 을 처리 하거나 throws 성명 을 통 해 이 이상 을 던 져 야 합 니 다.catch 처 리 를 통 해 든 throws 성명 을 통 해 던 지 든 프로그래머 에 게 무시 할 수 없 는 부담 을 주 었 다.
'검 사 된 이상'에 적용 하려 면 두 가지 조건 을 동시에 만족 시 켜 야 한다.첫째,API 를 정확하게 사용 하 더 라 도 이상 조건 의 발생 을 막 을 수 없다.둘째,이상 이 생기 면 API 를 사용 하 는 프로그래머 는 유용 한 동작 으로 프로그램 을 처리 할 수 있다.
제4 조:가능 한 한 표준적 인 이상 을 사용한다
코드 재 활용 은 제창 할 만하 다.이것 은 통용 규칙 이 고 이상 도 예외 가 아니다.기 존의 이상 을 다시 사용 하면 몇 가지 장점 이 있 습 니 다.
첫째,이것 은 당신 의 API 를 더욱 쉽게 배우 고 사용 할 수 있 게 한다.왜냐하면 이것 은 프로그래머 가 원래 익숙 했 던 습관 적 인 용법 과 일치 하기 때문이다.
둘째,이 API 를 사용 하 는 프로그램 에 있어 서 는 프로그래머 가 익숙 하지 않 은 이상 이 가득 하지 않 기 때문에 가 독성 이 더 좋다.
셋째,이상 류 가 적 을 수록 메모리 사용량 이 적 고 이런 종 류 를 옮 기 는 시간 도 적 다 는 것 을 의미한다.
자바 플랫폼 라 이브 러 리 가 지금까지 가장 많이 사 용 된 이상 이지 만 허 가 된 조건 에서 다른 이상 도 사 용 될 수 있 습 니 다.예 를 들 어 복수 나 행렬 같은 산술 대상 을 실현 하려 면 Arithmetic Exception 과 NumberFormat Exception 을 재 활용 하 는 것 이 적절 하 다.이상 하 게 당신 의 요 구 를 만족 시 키 려 면 주저 하지 말고 사용 하면 됩 니 다.그러나 이상 한 조건 을 던 지 는 것 이 이 이상 한 문서 에서 설명 한 조건 과 일치 하 는 지 확인 해 야 합 니 다.이런 중용 은 반드시 의미 의 기초 위 에 세 워 져 야 지,이름 의 기초 위 에 세 워 져 서 는 안 된다!
마지막 으로 어떤 이상 을 재 활용 하 는 지 는 반드시 지 켜 야 할 규칙 이 없다 는 것 을 잘 알 아야 한다.예 를 들 어 카드 대상 의 상황 을 고려 하여 카드 를 보 내 는 방법 이 있다 고 가정 하면 그의 매개 변수(handSize)는 카드 를 보 내 는 카드 의 개수 이다.호출 자가 이 매개 변수 에서 전달 하 는 값 이 전체 카드 의 나머지 장수 보다 크다 고 가정 합 니 다.그러면 이런 상황 은 Illegal Argument Exception(handSize 의 값 이 너무 크다)으로 해 석 될 수도 있 고 Illegal State Exception(고객 의 요청 에 비해 카드 대상 의 카드 가 너무 적다)으로 해 석 될 수도 있다.
제5 조:던 진 이상 은 해당 하 는 추상 에 적합 해 야 한다.
만약 한 방법 이 던 진 이상 이 그 가 수행 한 임무 와 뚜렷 한 관련 이 없다 면 이런 상황 은 사람 을 어찌 할 바 를 모 르 게 할 것 이다.한 방법 이 저층 추상 에서 던 진 이상 을 전달 할 때 종종 이런 상황 이 발생 한다.이런 상황 이 발생 했 을 때 당 혹 스 러 울 뿐만 아니 라 고위 층 API 도'오염'시 켰 다.
이 문 제 를 피하 기 위해 고위 층 은 저층 의 이상 을 포착 하고 고위 층 의 추상 에 따라 소개 할 수 있 는 이상 을 던 져 야 한다.이런 방법 은'이상 번역(exception translation)'이 라 고 불 린 다.
예 를 들 어 자바 의 집합 프레임 워 크 AbstractSequential List 의 get()방법 은 다음 과 같다(JDK 1.7.0 기반40):
public E get(int index) {
try {
return listIterator(index).next();
} catch (NoSuchElementException exc) {
throw new IndexOutOfBoundsException("Index: "+index);
}
}
listIterator(index)는 ListIterator 대상 을 되 돌려 줍 니 다.이 대상 의 next()방법 을 호출 하면 NoSuchElement Exception 이상 을 던 질 수 있 습 니 다.get()방법 에 서 는 NoSuch Element Exception 이상 을 던 지 는 것 이 당 혹 스 럽 다.그래서 get()은 NoSuchElement Exception 을 캡 처 하고 Index OutOf Bounds Exception 이상 을 던 졌 습 니 다.즉,NoSuchElement Exception 을 Index OutOf Bounds Exception 이상으로 번역 한 셈 이다.제6 조:모든 방법 에 이상 이 있 으 면 문서 가 있어 야 한다.
검 사 된 이상 을 따로 밝 히 고 자바 doc 의@throws 표 시 를 이용 하여 모든 이상 이 던 져 진 조건 을 정확하게 기록 해 야 합 니 다.
만약 한 클래스 의 많은 방법 이 같은 원인 에 있어 서 같은 이상 을 던진다 면,이 클래스 의 문서 주석 에서 이 이상 을 문서 로 만 드 는 것 은 모든 방법 을 위해 단독으로 문 서 를 만 드 는 것 이 아니 라 받 아들 일 수 있 습 니 다.
제7 조:세부 메시지 에 실패-포획 메시지 포함
한 마디 로 이상 을 사용자 정의 하거나 이상 을 던 졌 을 때 실패 와 관련 된 정 보 를 포함해 야 한 다 는 것 이다.
프로그램 이 캡 처 되 지 않 은 이상 으로 실 패 했 을 때 시스템 은 이 이상 한 스 택 궤적 을 자동 으로 출력 합 니 다.스 택 궤적 에 이 이상 한 문자열 표시 가 포함 되 어 있 습 니 다.전형 적 인 상황 에서 이 이상 류 의 유형 과 그 뒤 를 따 르 는 세부 적 인 소식 을 포함한다.
제8 조:실 패 를 원자 성 을 유지 하도록 노력한다.
대상 이 이상 을 던 진 후에 도 우 리 는 이 대상 이 여전히 정의 가 좋 은 사용 가능 한 상태 에 있 기 를 기대한다.검 사 를 받 은 이상 에 있어 서 는 특히 중요 하 다.호출 자 들 은 검 사 를 받 은 이상 에서 회복 되 기 를 기대 하기 때문이다.
일반적으로 실패 한 방법 호출 은 대상 을 호출 되 기 전의 상태 로 유지 해 야 한다.이런 속성 을 가 진 방법 은'실패 원자 성(failureatomic)'이 라 고 불 린 다.실패 해도 원자 성 을 유지 하고 있다 는 뜻 으로 읽 힌 다.대상 이'실패 원자 성'을 유지 하 는 방식 은 몇 가지 가 있다.
(01)비 가 변 대상 을 설계 한다.
(02)가 변 대상 에서 작업 을 수행 하 는 방법 에 대해'실패 원자 성'을 얻 는 가장 흔 한 방법 은 작업 을 수행 하기 전에 매개 변수의 유효성 을 검사 하 는 것 이다.다음(Stack.java 의 pop 방법):
public Object pop() {
if (size==0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null;
return result;
}
(03)이전 방법 과 유사 하여 계산 처리 과정 에 대해 순 서 를 조정 하여 실패 할 수 있 는 모든 계산 부분 이 대상 상태 가 수정 되 기 전에 발생 하도록 할 수 있다. (04)복구 코드 를 작성 하여 작업 과정 에서 발생 한 실 패 를 설명 하고 대상 을 작업 시작 전 상태 로 되 돌려 줍 니 다.
(05)대상 의 임시 복사 에서 작업 을 수행 하고 작업 이 끝 난 후에 임시 복사 중의 결 과 를 원래 의 대상 에 게 복사 합 니 다.
'대상 의 실패 원자 성 유지'는 기대 목표 이지 만 항상 할 수 있 는 것 은 아니다.예 를 들 어 여러 스 레 드 가 적당 한 동기 화 체제 가 없 는 상황 에서 한 대상 을 동시 방문 하려 고 한다 면 이 대상 은 일치 하지 않 는 상태 에 남 을 수 있다.
실패 원자 성 을 실현 할 수 있 는 자리 에서 도 항상 기대 되 는 것 은 아니다.어떤 조작 에 대해 서 는 비용 이나 복잡성 을 현저히 증가 시 킬 것 이다.
전체적인 규칙 은 방법 규범 의 일부분 으로서 그 어떠한 이상 도 대상 이 이 방법 을 사용 하기 전의 상 태 를 바 꾸 지 말 아야 한다.만약 에 이 규칙 이 위반 되면 API 문서 에서 대상 이 어떤 상태 에 있 는 지 명확 하 게 밝 혀 야 한다.
제9 조:이상 을 무시 하지 마라
API 디자이너 가 하나의 방법 이 이상 한 것 을 던 질 것 이 라 고 밝 혔 을 때 그들 은 어떤 일 을 설명 하려 고 노력 하고 있다.그 러 니 무시 하지 마 세 요!다음 과 같은 이상 코드 무시:
try {
...
} catch (SomeException e) {
}
빈 catch 블록 은 이상 하 게 목적 을 달성 하지 못 하 게 할 수 있 습 니 다.이상 한 목적 은 비정상적인 조건 을 처리 하도록 강요 하 는 것 입 니 다.이상 하 나 를 무시 하 는 것 은 화재 신 호 를 무시 하 는 것 과 같다.화재 신호 기 를 끄 면 진정한 화재 가 발생 했 을 때 화재 신 호 를 보 는 사람 이 없다.따라서 적어도 catch 블록 은 이 이상 을 무시 하 는 이 유 를 설명 하 는 데 적합 하 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.