예외와 에러의 차이
- 예외: 개발자가 대응할 수 있는 것.
- 에러: 개발자가 대응할 수 없는 것.(단전, OS문제, JDK(JRE)의 문제)
- 자바는 객체를 통해 예외를 처리한다.
- 예외에서의 최상위 부모클래스: Exception
예외 발생 시 콘솔을 통해 알 수 있는 것.
1) 예외의 발생 위치 (java.lang.ArithmeticException: / by zero)
2) 예외의 발생 원인 (at kr.co.tj.Test.f2(Test.java:7))
public class Test {
public void f2(int a, int b) {
System.out.println(111);
System.out.println(a/b);
System.out.println(2222);
}
}
=============================================
import kr.co.tj.Test;
public class MainEx {
public static void main(String[] args) {
Test t1 = new Test();
t1.f2(10, 5);
t1.f2(10, 0); // 예외 발생
}
}
================Console=========================
111
2
2222
111
Exception in thread "main" java.lang.ArithmeticException: / by zero // 원인
at kr.co.tj.Test.f2(Test.java:7) // 위치
at kr.co.main.MainEx.main(MainEx.java:16) // 위치
예외처리:
- try~catch와 throws를 구별해서 처리할 수 있어야 한다.
- 예외가 아닌데 논리적으로 예외를 직접 유발하고 싶을 땐 throw를 이용한다.
- 이 때, 사용자 정의 예외클래스를 생성해서 처리한다.
- 끝으로, 예외 여부와 상관없이 무조건 실행해야 하는 코드는 finally구문으로 처리할 수 있다.
- e.printStackTrace(); -> 예외발생 원인과 위치를 알려줌.
- 개발할 때는 표기
- 배포할 때는 미표기
try~catch
- try에 예외가 발생할 가능성이 있는 코드를 적고,
catch에 예외가 발생했을 때 실행할 코드를 적는다.
- 예외가 발생할 가능성이 있는 코드
- 메서드에 매개변수가 있는 경우
- catch에 들어갈 내용을 확실하게 알고 있고, 그에 대한 책임을 개발자가 감내할 수 있을 때 사용.
public class Test2 {
public void w3(int idx) {
int[] arr = {1};
try {
int num = arr[idx];
System.out.println(num);
} catch (Exception e) { // 원래는 ArrayIndexOutOfBoundsException
System.out.println("죄송합니다.");
System.out.println("100억원을 드리겠습니다.");
e.printStackTrace();
}
}
}
===========================================================
import kr.co.tj.Test2;
public class MainEx {
public static void main(String[] args) {
Test2 t2 = new Test2();
t2.w3(2);
}
}
======================Console==============================
죄송합니다.
100억원을 드리겠습니다.
java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 1
at kr.co.tj.Test2.w3(Test2.java:13)
at kr.co.main.MainEx.main(MainEx.java:17)
Throws
- 해당 메서드를 호출한 쪽에서 예외처리를 하도록 권한 위임.
- 예외 발생의 원인을 정확히 모를 때 사용
public class Test4 {
public void p2(String msg, int idx) throws Exception{ // StringIndexOutOfBoundsException
System.out.println(1111);
char c = msg.charAt(idx); // 예외 발생 위치
System.out.println(c);
System.out.println(2222); //예외 발생 전까지 실행되고 예외 발생 뒤의 코드는 실행x
}
}
============================================================
public class MainEx {
public static void main(String[] args) {
Test4 t4 = new Test4();
try { //(throws 사용)
t4.p2("hello", 1000); // 예외 발생 위치
} catch (Exception e) {
System.out.println("죄송합니다.");
System.out.println("늦더라도 제대로 고치겠습니다.");
}
}
}
=====================Console================================
1111
죄송합니다.
늦더라도 제대로 고치겠습니다.
java.lang.StringIndexOutOfBoundsException: String index out of range: 1000
at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:48)
at java.base/java.lang.String.charAt(String.java:1515)
at kr.co.tj.Test4.p2(Test4.java:97)
at kr.co.main.MainEx.main(MainEx.java:33)
public class Test4 {
String[] weapons = {"활","검","대포"};
String haveWeapon = weapons[0];
public void changeWeapon(int idx) throws Exception{ // ArrayIndexOutOfBoundsException
haveWeapon = weapons[idx]; // 예외 발생 위치
System.out.println(haveWeapon+"으로 변경됨.");
}
}
=====================================================
public class MainEx {
public static void main(String[] args) {
Test4 t4 = new Test4();
try {
t4.changeWeapon(3); // 예외 발생 위치
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
System.out.println("무기 변경 실패");
System.out.println("바른 값을 넣으세요.");
}
}
}
===================Console==========================
java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
at kr.co.tj.Test4.changeWeapon(Test4.java:18)
at kr.co.main.MainEx.main(MainEx.java:13)
무기 변경 실패
바른 값을 넣으세요.
finally
- 작업이 실패하든 성공하든 무조건 실행해야 하는 코드는 finally구문으로 처리
- try~catch와 같이 사용
- 주의사항: try~catch 구문 밖에 작성하는 것과 구별해야 함(같은 묶음은 finally로 처리)
- return보다 효력이 강력함.
- try와 catch에 return문이 있어도, 반드시 finally구문을 실행하고 return문이 나중에 실행됨.
- 나중에 I/O 학습과 DB학습 때 사용
public class Test7 {
public int me2(int idx) {
int[] arr = {1, 2};
try {
System.out.println(arr[idx]); // 예외 발생 위치
return 200;
} catch (Exception e) {
e.printStackTrace();
System.out.println("빠른 시일 내에 조치하겠음.");
return 500;
} finally { // return보다 강함
System.out.println("close()메서드 호출");
}
}
}
=============================================================
public class MainEx {
public static void main(String[] args) {
Test7 t7 = new Test7();
t7.me2(10); // 예외 발생 위치
}
}
=======================Console===============================
java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 2
at kr.co.tj.Test7.me2(Test7.java:9)
at kr.co.main.MainEx.main(MainEx.java:10)
빠른 시일 내에 조치하겠음.
close()메서드 호출
Throw
- 문법적으로 예외가 아닌 상황이지만 논리적으로 예외일 때, 강제로 예외를 유발하는 기능
ex) 정책적인 것들(댓글의 욕 제한)
- 메서드 뒤에 throws Exception 삽입(문법적으로 예외가 아니므로 Exception만 가능)
public class Test8 {
public void ee1(String reply) throws Exception { //throws Exception 삽입
String[] arr = {"fuck", "ㅅㅂ"};
for(int i=0; i<arr.length; i++) {
String msg = arr[i];
if(reply.contains(msg)) {
throw new Exception("욕하지 마"); // return대신 throw
}
}
System.out.println(reply);
}
}
============================================================================
import kr.co.tj.Test8;
public class MainEx {
public static void main(String[] args) {
Test8 t8 = new Test8();
try {
t8.ee1("센스 있는데");
} catch (Exception e) {
e.printStackTrace();
System.out.println("불온문자가 포함되어 있음");
}
try {
t8.ee1("ㅅㅂ");
} catch (Exception e) {
e.printStackTrace();
System.out.println("불온문자가 포함되어 있음");
}
}
}
=========================Console===================================
센스 있는데
java.lang.Exception: 욕하지 마
at kr.co.tj.Test8.ee1(Test8.java:12)
at kr.co.main.MainEx.main(MainEx.java:21)
불온문자가 포함되어 있음
사용자 정의 예외클래스
- throw를 사용하면 문법적 예외가 아니므로 관련 예외 객체를 어떤 클래스로 만들지에 대한 문제점이 생긴다.
- 당연히 이와 관련된 예외 클래스는 존재하지 않는다.
- 따라서 직접 논리적 예외와 관련된 예외클래스를 만들어주고, 이를 사용한다.
- throw클래스의 구조 + 사용자 정의 예외클래스
- 사용자 정의 예외클래스 생성방법
- 클래스명 extends Exception
- Add default serial version ID(마우스 올려놓기)
- 슈퍼클래스의 사용자 생성자 생성(String에 대해서만)
- throw구문 사용 위치에서 Exception을 직접 만든 예외클래스로 바꾸기
public class DoNotSwearException extends Exception { //직접 만든 Exception + extends Exception
private static final long serialVersionUID = 1L;
// 슈퍼클래스(Exception)의 사용자 생성자->String만
public DoNotSwearException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
}
================================================================
public class Test8 {
public void ee1(String reply) throws Exception {
String[] arr = {"인마"};
for(int i=0; i<arr.length; i++) {
String msg = arr[i];
if(reply.contains(msg)) {
// 우리가 직접 만든 Exception으로 바꾸기
throw new DoNotSwearException("욕하지 마세요.");
}
}
System.out.println(reply);
}
}
==================================================================
public class MainEx {
public static void main(String[] args) {
Test8 t8 = new Test8();
try {
t8.ee1("야, 인마!");
} catch (Exception e) {
e.printStackTrace();
System.out.println("불온문자가 포함되어 있음.");
}
}
}
=============================Console===============================
kr.co.tj.DoNotSwearException: 욕하지 마세요.
at kr.co.tj.Test8.ee1(Test8.java:12)
at kr.co.main.MainEx.main(MainEx.java:11)
불온문자가 포함되어 있음.
'자바(java)' 카테고리의 다른 글
Calendar(GetInstance) (0) | 2023.03.14 |
---|---|
Random (0) | 2023.03.14 |
내부클래스(Inner Class) (0) | 2023.03.13 |
Enum(Enumeration) (0) | 2023.03.10 |
람다식(Lambda) (0) | 2023.03.10 |