수정일자 2023.5.23
학습 계획
- 자바 예외 처리
- 팀코칭 질문으로 학습
TIL
- 자바 예외 처리
- Checked Exception
- throw
- throws 절
- Unchecked Exception
- 여러가지 에러 종류
- 논리 에러 (Semantic error)
- 파스 에러 (Parse Error)
- 여러가지 에러 종류
- Checked Exception
- 구문분석
- 파싱
- 토큰
- 파싱
체크드 예외(Checked Exception)
이러한 예외는 컴파일러가 컴파일 시점(코드를 실행하기 전에)에 체크합니다. 체크드 예외는 주로 외부 시스템과 상호작용하는 코드에서 발생하는 예외입니다. 예를 들어, 파일 I/O 작업, 데이터베이스 연결 등에서 발생하는 예외입니다. 체크드 예외가 발생할 수 있는 코드를 작성할 때는 반드시 이러한 예외를 처리해야 합니다. 이를 처리하는 방법은 두 가지가 있습니다:
- try-catch 블록을 사용하여 예외를 직접 처리합니다.
- 메소드에서 throws 키워드를 사용하여 예외를 선언하고, 메소드를 호출하는 코드에 예외 처리를 위임합니다.
체크드 예외는 Exception 클래스를 상속한 클래스들입니다(단, RuntimeException 클래스를 상속한 예외들은 제외). 예를 들어, IOException, SQLException 등이 체크드 예외입니다.
언체크드 예외(Unchecked Exception)
이러한 예외는 컴파일러가 컴파일 시점에 체크하지 않습니다. 대신, 이러한 예외는 프로그램을 실행하는 동안 발생합니다. 이러한 예외는 주로 프로그래밍 오류, 예를 들어, null 참조를 사용하거나, 배열의 유효하지 않은 인덱스를 사용하는 등의 오류로 인해 발생합니다. 언체크드 예외는 RuntimeException 클래스 또는 그 서브클래스를 상속한 클래스들입니다. 예를 들어, NullPointerException, ArrayIndexOutOfBoundsException 등이 언체크드 예외입니다.
체크드 예외는 무조건 예외를 발생한다고 가정하고 컴파일러 단계에서 확인을 한다고 해서 내가 이전에 학습했던 개념이 떠올라서 헷갈렸다.
내가 떠올린 개념은 컴파일 할떄의 문법 검사였다.
결론은 문법과 체크드 예외는 다른 것이였다,
문법은 문법 규칙에 안맞으면 나는 컴파일 에러고
체크드 예외는 문법 규칙 외에 다른 부분 에서 에러가 발생 할 수 있어 예외 처리를 해야 하는 경우 였다.
예를 들면 파일 읽고 쓰기 할 떄 소스상 문제는 없지만 실제 파일이 없으면 나는 에러나
지금은 정확히 무슨 에러인지는 모르겠지만 SQLException에러가 있었다. 내 예측으로 이것도 소스상으 로나 SQL 상으로는 문제는 없는데
이 것을 실행했을 떄 동작 직후 어떤 값을 가져오지 못해서 발생하는 문제 일 것으로 상상해 본다.
이런 예외는 왜 존재 할까 라고 생각을 해보았다.
어떤 식으로는 에러는 존재하게 되고 개발 중이나 이럴 때는 발견을 하면 수정을 하면 되지만
개발 된 이후에는 발견 후에는 이미 늦을 수 있고 즉시 수정이 어렵다.
그리고 개발 중 상태와 개발 된 상태와 환경이나 조건등 다른 변수가 변해서
소스가 작동을 못해서 예측을 못했거나 환경이 변해서 실서버 중에 에러가 발생 할 가능성이 있다.
에러도 여러 종류가 있고 그 에러 종류를 분류를 하면
에러가 발생 하지 않을 수 있지만 그 가능성이 다분하여 무조건 예외 처리하는 것이 정석이 된 예외 종류가 체크드 예외다.
언체크드 예외는 컴파일 당시에는 체크를 하지 않는다. 그 이유로는 내 생각으로는 컴파일 당시에 체크하는 것으로는 의미가 없거나
체크 할 수 없는 경우 인 것 같다.
언체크드 예외는 내가 알기론 프로그램 실행 중에 발생 하는 예외로 분류하는데
NullPointerException, ArrayIndexOutOfBoundsException가 있다.
지금은 입력 되는 값이 없어서 컴파일 시에는 체크 하지 않는다.
조금 생각해 보면 알 수 있을 것이다.
값이 있고 없고 여부에 따른 에러에 가깝다고 나는 생각하는데 이건 컴파일 중에는 따로 값을 넣어서 테스트 하지 않는 걸로 내가 기억상으론 알고 있기 떄문이다.
에러가 발생하면 애플리케이션이 대개 멈추는데 예외 처리를 미리 해 놓으면 애플리케이션이 멈추는 건 예방 할 수 있다.
예방이 되기도 하고 더 큰 목적은 애플리케이션의 안정성인 것 같다.
예외 상황이 발생하면 그 관련 소스 부분은 동작하지 않겠지만 전체 시스템은 계속 동작할 수 있다.
작은 불씨가 초가삼간을 태우는 건 막을 수 있다고 생각한다.
그리고 나중에 정확한 오류 메세지를 남겨서 나중에 문제를 해결하는데 도움이 된다.
또한 에러 종류 중에 논리 에러라는 용어가 있어서 알아보았다.
논리에러
논리 오류(logical error)는 프로그램 코드에서 잘못된 논리나 알고리즘으로 인해 발생하는 오류를 말합니다. 이는 주로 개발자의 실수로 인해 발생하며, 논리 오류로 인해 프로그램은 기대와 다르게 동작하거나 원하지 않는 결과를 생성할 수 있습니다.
예를 들어, 두 개의 숫자를 더하는 코드가 있는데, 실제로는 빼는 연산을 수행하는 경우, 이것은 논리 오류입니다. 코드는 정상적으로 컴파일되고 실행되지만, 결과는 개발자가 예상한 것과 다를 것입니다.
논리 오류는 컴파일 오류나 런타임 오류와는 다르게, 컴파일러나 인터프리터, 또는 CPU가 감지할 수 없습니다. 이러한 오류는 프로그램의 동작을 테스트하고 분석함으로써 해결해야 합니다. 디버깅 과정에서 개발자는 코드의 논리를 검토하고, 문제가 되는 부분을 찾아 수정해야 합니다.
내가 생각하는 논리라는 다른 것 같아서 약간 논리 오류라는 말이 잘 안 와닿아서 다시 알아보니
논리 오류(logical error)라는 이름은 프로그래밍에서 이러한 종류의 오류가 프로그램의 "논리" 또는 알고리즘에 문제가 있음을 나타내기 때문에 붙여졌습니다.
논리 오류는 프로그램의 코드가 잘못되었거나, 프로그래머가 의도한 바와 다르게 동작하는 경우 발생합니다. 즉, 프로그램의 '논리'가 잘못되었다고 볼 수 있습니다. 이러한 오류는 문법적으로는 올바르게 작성되었지만, 프로그램의 동작이나 결과가 기대한 것과 다른 경우에 발생합니다.
예를 들어, 프로그래머가 의도적으로 두 숫자를 더하는 코드를 작성했는데 실제로는 빼는 연산이 이루어지면, 이는 논리 오류입니다. 프로그램의 '논리', 즉 알고리즘이 잘못되었기 때문입니다.
논리 오류는 대개 테스트 과정에서 발견되며, 프로그래머가 코드를 재검토하고 디버깅하여 수정해야 합니다.
Q.시스템은 동작은 하는데 원하는 결과가 아니면 논리오류라고 할 수 잇는 거네 그 오류를 찾아서수정해야겟네
A.맞습니다. 시스템이 동작하는 것은 맞지만 그 결과가 프로그래머가 의도한 결과가 아니라면, 그것은 논리 오류라고 볼 수 있습니다.
이런 경우, 프로그래머는 코드를 자세히 살펴보고 문제가 되는 부분을 찾아 수정해야 합니다. 때로는 이것이 간단한 문제일 수도 있지만, 복잡한 프로그램에서는 이 문제를 찾아내고 수정하는 것이 쉽지 않을 수도 있습니다.
그렇기 때문에 프로그래밍에서는 단위 테스트, 통합 테스트 등 다양한 테스트 기법과 디버깅 도구를 사용하여 논리 오류를 찾아내고 수정하는 것이 중요합니다. 또한 코드 리뷰와 같은 프로세스를 통해 다른 개발자들이 코드를 검토하고 문제를 발견하는 것도 도움이 될 수 있습니다.
쉽게 말하면 소스상으로는 큰 문제가 없어서 작동은 하는데 개발자가 원하는 의도와 결과가 다르면
나는 에러라고 한다. (개발자의 실수다)
파스 에러라는 것도 있어서 알아보았다.
파스 에러(Parse Error)
"파스 에러"(Parse Error)는 컴퓨터 프로그램이 어떤 데이터나 명령을 해석하려고 시도할 때 발생하는 오류를 말합니다.
이 오류는 일반적으로 입력 데이터의 구조가 프로그램이 예상한 형식과 일치하지 않을 때 발생합니다. 예를 들어, 프로그램이 정수를 기대하는데 문자열이 제공되면 파스 에러가 발생할 수 있습니다. 또는 XML이나 JSON 등의 구조화된 데이터 형식에서 예상한 구조와 다른 데이터가 제공되면 파스 에러가 발생할 수 있습니다.
"파싱"이라는 과정은 어떤 데이터를 읽고 그 구조를 이해하고 분석하는 과정입니다. 프로그램은 이 과정을 통해 데이터의 의미를 파악하고, 이를 바탕으로 동작을 결정합니다. 파스 에러는 이 파싱 과정에서 발생하는 오류로, 프로그램이 데이터를 정확하게 해석하지 못하게 만듭니다.
파스 에러를 해결하기 위해서는 보통 입력 데이터가 프로그램이 예상한 형식과 일치하도록 데이터를 수정하거나, 프로그램이 다양한 입력 형식을 처리할 수 있도록 코드를 변경해야 합니다.
이하 아래는 파스 에러를 이해하기 위해 내가 알아본 개념들이다.
파싱 과정에 대해 설명해줘
"파싱"은 일련의 문자열을 의미있는 토큰(token)으로 분해하고, 이 토큰들을 이용하여 자료구조(예: 트리)를 구성하는 과정을 말합니다. 파싱은 컴퓨터 과학에서 중요한 개념으로, 프로그램의 소스 코드를 컴퓨터가 이해할 수 있는 형태로 변환하는 데 필요한 중요한 단계입니다.
파싱 과정은 대체로 두 가지 단계로 이루어집니다:
- 렉싱(Lexing) 또는 토큰화(Tokenization): 이 단계에서는 입력 문자열을 더 작고 관리 가능한 부분으로 분할합니다. 이 부분들을 "토큰(token)"이라고 합니다. 예를 들어, "1 + 2"라는 문자열은 세 개의 토큰으로 나뉘어집니다: "1", "+", "2".
- 파싱(Parsing): 이 단계에서는 토큰들을 특정 구조에 따라 정렬합니다. 이 구조는 종종 트리 형태로 표현되며, 이를 "파스 트리(parse tree)" 또는 "구문 트리(syntax tree)"라고 합니다. 예를 들어, "1 + 2"의 토큰들은 트리로 정렬될 수 있으며, "+"가 루트 노드가 되고 "1"과 "2"가 자식 노드가 됩니다.
이렇게 해석된 데이터는 컴퓨터가 이해하고 실행할 수 있는 형태로 만들어집니다. 파싱은 컴파일러와 인터프리터에서 프로그램 코드를 분석하는 데 사용되며, 웹 브라우저에서 HTML 및 CSS를 해석하는 데 사용되고, 데이터 분석에서 JSON, XML 등의 데이터 형식을 해석하는 데 사용됩니다.
렉싱과 토큰화는 같은 말이야??
"렉싱"과 "토큰화"는 많은 경우에 유사한 과정을 나타내지만, 약간 다른 측면을 강조합니다.
- 렉싱(lexing): 이는 소스 코드를 '어휘 요소' 또는 '렉스(lex)'로 분해하는 과정을 말합니다. 렉싱 단계에서는 각 문자열(혹은 문자의 시퀀스)이 어떤 유형인지 판단합니다. 예를 들어, "123"은 정수일 수 있고, "abc"는 식별자일 수 있습니다.
- 토큰화(tokenization): 토큰화는 문자열을 개별 '토큰'으로 분해하는 과정을 말합니다. 이 과정에서는 문자열의 의미는 크게 고려하지 않고, 단순히 개별 단위로 분할하는 것에 주로 초점을 맞춥니다.
렉싱은 토큰화 후에 이루어지는 경우가 많으며, 토큰화 과정에서 생성된 토큰이 어떤 유형인지를 판단합니다. 따라서 렉싱은 토큰화보다 더 구체적인 과정으로 볼 수 있습니다. 하지만 이 두 용어는 상황에 따라 서로 바꿔서 사용되기도 합니다.
구문 분석은 크게 두 단계로 나눌 수 있는데
- 토큰화(Tokenization): 이 단계에서는 소스 코드를 개별 토큰으로 나눕니다. 토큰은 코드의 최소 단위로, 각 토큰은 특정 유형(예: 식별자, 키워드, 연산자, 리터럴 등)에 속합니다.
- 구문 분석(Parsing): 이 단계에서는 토큰화된 코드를 언어의 문법 규칙에 따라 분석하고, 이를 트리 또는 다른 자료 구조로 구성합니다. 이 과정을 통해 컴파일러 또는 인터프리터는 코드의 구조를 이해하게 됩니다.
구문 분석을 하는 이유와 토큰화 하는 이유가 궁금하였다.
프로그래밍어는 고수준 언어라 컴퓨터가 이해할 수 있는 저수준 언어로 변환해야한다.
이 변환 과정이 컴파일 또는 인터프리팅이다.
이 과정에서 구문 분석으로 소스 코드의 구조를 이해하고 검증하는데 각 토큰이 어떻게 조합되어 문장을 이루는지 그리고 어떻게 연결되어 전체 프로그램을 구성하는 지 파악한다고 한다.
또한 구문 분석 과정에서 이러한 구문의 구조와 순서를 파악함으로써, 프로그램이 어떤 순서로 실행될지도 결정한다고도 한다.
파스 에러는 토큰화나(와) 렉싱이 일어나고 이것들을 정렬하는 것을 파싱이라고 하는데, 이 파싱이라는 과정 중에 일어나는 에러를 파스 에라라고 한다. 약간 별개의 내용을 덧붙이자면 이렇게 파싱을 하면 이 것(파싱)으로 구문 분석을 할 수 있는 것 같았다. 컴파일러와 인터프리터는 구문 분석을 통해 소스 코드의 구조를 이해하게 된다.
'[F-Lab 66해빗 페이백 챌린지 ]' 카테고리의 다른 글
| [F-Lab 모각코 페이백 8일차] 얕은 복사, 깊은 복사, 추상클래스와 인터페이스 차이점 (0) | 2023.05.21 |
|---|---|
| [F-Lab 모각코 챌린지 7일차] C1 컴파일러, C2 컴파일러, 인라이닝, 루프 언롤링 (0) | 2023.05.20 |
| [F-Lab 모각코 챌린지 6일차] 자바 예외 처리, 기타 개념 (0) | 2023.05.17 |
| [F-Lab 모각코 챌린지 5일차] 쓰레드 안전, Final, Static (2) | 2023.05.16 |
| [F-Lab 모각코 챌린지 4일차] 제네릭, 컬렉션 (2) | 2023.05.15 |