컴파일 시점에 발생하는 에러로, 주로 문법 에러(Syntax Error) 👉🏻 컴파일러가 별도로 관리
프로그램을 실행하는 도중에 발생하는 에러로, 수행할 수 없는 작업을 시도했을 때 발생
👀 Example
Object obj = null;
obj.toString();
프로그램이 에러없이 정상적으로 실행 또는 정상동작인 것처럼 보이지만 개발자가 의도한대로 프로그램이 동작하고있지 않은 상황 👉🏻 ex) 무한루프
런타임 에러 상황을 정의하고 있는 클래스들의 최상위 부모 클래스
💡 런타임 에러를 정의! 컴파일 에러는 비교적 가벼운 문법 에러
Error클래스, Exception클래스를 자식클래스로 가짐정상적인 상황으로 복구가 안되는 심각한 수준의 문제상황 👉🏻 프로그램 코드(자체적인 방법)로 해결할 수 없는 수준
👀 Example
OutOfMemoryError ➡ 메모리 가용용량이 부족한 상태에서 할당을 시도한 상황
프로그램이 실행되는 동안 발생하는 예외적인 상황들을 정의하는 클래스 👉🏻 예외상황을 예측해서 프로그램 코드로 처리가능한 수준의 런타임 오류
try-catch 구문을 이용하여 미리 예외처리 작업을 추가Checked Exception와 Unchecked Exception는 미리 예외처리를 하느냐의 차이이지 예외가 발생하면 반드시 그에 대한 처리를 해야 함발생할 수도 있는 예외적인 상황을 미리 대비하는 코드를 작성
프로그램 실행 중 예외상황이 발생하면 프로그램이 종료, JVM이 에러상황을 Exception클래스로 Throw해줌
예외처리 구문을 사용하여 예외처리 할 수 있음 👉🏻 try-catch 구문try {
//try블록
//예외가 발생할 수도 있는 코드를 작성하는 영역
//예외 발생이 예측되는 코드
} catch( Exception e ) { //<- try 블록에서 발생한 예외 객체를 저장할 수 있는 변수 선언
//catch 블록
//프로그램이 종료되지 않고 실행할 코드를 작성하는 영역
//예외처리 수행코드를 작성
//예외정보 객체 e 변수를 사용할 수 있음
//e.printStackTrace(); 코드만 적어두는 경우가 많음
} finally {
//finally 블록
//try 블록에서 예외가 발생해도, 발생하지 않아도 무조건 실행해야만 하는 코드를 작성하는 영역
//finally블록 생략 가능
}
-------------------------------------------------------------------------------------
int[] arr = new int[5];
int i=0;
try {
while(true) {
arr[i] = i+1;
i++;
}
} catch ( ArrayIndexOutOfBoundsException e ) {
//발생한 예외상황 출력
e.printStackTrace();
} catch ( NullPointerException e ) {
} catch ( Exception e ) {
//위의 두 예외가 아닌 나머지 예외 발생시 예외처리할 코드 작성
} finally {
System.out.println("예외처리 후 실행");
}
하나의 catch 구문에서 예외 클래스를 여러개 적용하는 문법
try {
} catch ( NullPointerException | ArrayIndexOutOfBoundsException | NegativeArraySizeException e ) {
//위 셋 예외상황 처리하는 구문
} catch ( Exception e ) {
//나머지 예외상황 처리하는 구문
}
-------------------------------------------------------------------------------
try {
} catch ( NullPointerException
| ArrayIndexOutOfBoundsException
| NegativeArraySizeException e ) {
//위 셋 예외상황 처리하는 구문
} catch ( Exception e ) {
//나머지 예외상황 처리하는 구문
}
예외상황을 발생시키기 위해 개발자가 직접 사용하는 코드
String str = null;
if( str != null ) {
//null이 아니라면 문자열 길이 출력
System.out.println("str.length()); //str의 값이 null이므로 길이를 낼 수 없음 ➡ Dead Code
} else {
//null이라면 예외객체를 직접 만들어서 예외상황 발생시킴 👉🏻 예외 발생시 프로그램 여기서 종료
throw new NullPointerException();
}
------------------------------------------------------------------
//IOException ie = new IOException(); 👉🏻 throw와 위치가 다름
try {
//throw ie;
throw new IOException(); 👉🏻 throw와 예외 생성 위치 맞춰주기
} catch (IOException e) {
e.printStackTrace();
}
예외가 발생한 메소드에서 직접 예외처리를 하지 않고 자신을 호출한 메소드에게 예외처리를 미루는 키워드
Caller에게 묻는 것Caller : 메소드를 호출한 쪽의 메소드Callee : 호출당한 메소드class Test {
//unchecked Exception
public void method() throws NullPointerException {
throw new NullPointerException();
}
//checked Exception
public void method2() throws IOException {
throw new IOException();
}
}
-----------------------------------------------------------------------
public class Exception_Test {
public static void main(String[] args) {
Test tt = new Test();
tt.method();
👉🏻 unchecked exception이라서 try-catch 에러 안뜸
try {
tt.method2();
} catch (IOException e) {
e.printStackTrace();
}
👉🏻 checked exception이라서 try-catch 필수
}
}
입출력장치와 프로그램 사이에 데이터를 통신(교환)할 수 있도록 만들어진 SW적인 장치 👉🏻 데이터 스트림, 데이터의 통로, 흐름
FIFO 구조로 데이터가 전달됨FIFO : First In First Out, 선입선출 ➡ 보통 데이터를 다룰 때 많이 사용됨 / Queue(대기열) ◀▶ FILO, LIFOFILO : First In Last Out, 선입 후출 ➡ Stack영역키보드 입력 ➡read()➡ 프로그램(byte[]) 저장 ➡write(), flush()➡ 모니터 출력
System.in : 키보드 입력(기본 입력)Scanner : 키보드로 입력된 데이터 스캔 후 데이터 타입 인식InputStream OutputStreamReader Writerjava.io.InputStream : 입력스트림의 기본 클래스
public int read(byte[] b) throws IOException {
}
b 배열의 길이만큼 데이터를 읽어들임 👉🏻 한번에 최대로 읽어들일 수 있는 데이터의 크기는 b 배열의 길이b 배열에 저장, 데이터의 길이(개수)를 int형으로 반환ctrl + zInputStream is = System.in; //키보드 표준 입력 스트림객체
byte[] buf = new byte[1024]; //입력받은 데이터의 저장소 역할 👉🏻 read()메소드의 매개변수로 이용됨
int len = -1; //입력된 데이터의 길이 👉🏻 read()메소드의 반환값으로 이용
StringBuilder sb = new StringBuilder(); //입력받은 전체 문자열을 저장할 객체
int total = 0; //입력받은 문자열의 길이
try {
System.out.println("<<입력 대기중>>");
while( (len = is.read(buf)) != -1 ) {
String data = new String(buf, 0, len); //입력받은 byte[] 데이터를 String으로 변환
sb.append(data) //변환된 문자열을 저장
total += len;
//👈🏻 예외가 없을 때 read()의 사용이 끝나는 시점 ➡ 예외가 있으면 try를 통과하므로 안전하게 finally에 넣기
}
} catch ( IOException ) {
e.printStackTrace();
} fainally { //read()의 사용을 끝내는 시점
try{
//스트림 닫기
if(is!=null) is.close(); //키보드가 연결되어있다면 입력을 종료한다.
//[InputStream is = System.in;] 입력을 뜻하는 것이 아니라 키보드가 연결된 그 자체 ➡ is!=null의 의미 : 키보드가 연결되지 않은 경우 / is=null이라면 키보드가 연결된 상태
} catch ( IOException ) {
e.printStackTrace();
}
}
java.io.OutputStream : 출력스트림의 기본 클래스
public void write(byte[] b, int off, int len) throws IOException {
}
b 배열의 off 인덱스부터 시작해서 len 길이만큼 출력스트림으로 출력OutputStream os = System.out; //모니터 표준 출력 스트림 객체
byte[] buf = new byte[1024];
int len = 0; //출력할 데이터의 길이
buf[len++] = 'A';
buf[len++] = 'p';
buf[len++] = 'p';
buf[len++] = 'l';
buf[len++] = 'e';
buf[len++] = '\n';
try {
os.write(buf, 0, len);
os.flush();
} catch (IOException e) {
e.printSteackTrace();
} finally {
try{
if(os!=null) os.close();
} catch (IOExcption e) {
e.printStackTrace();
}
}
출력버퍼에 담긴 출력 데이터를 강제로 출력 장치로 내보냄 👉🏻 write() 메소드 호출 후 flush() 메소드를 호출해주는 것이 좋음
public void flush() throws IOException {
}