#7 Exception (์์ธ์ฒ๋ฆฌ)
by JiwonDev์๋ฐ์์์ ์ค๋ฅ, ์์ธ
์๋ฐ์์ ์์ธ, ์ค๋ฅ๋ java.lang.Throwable ํด๋์ค๋ฅผ ์์๋ฐ์ผ๋ฉฐ ๊ตฌํํ๋ฉฐ 3๊ฐ์ง ์ข ๋ฅ๋ก ๋๋๋ค.
- Error
์๋ฐ ํ๋ก๊ทธ๋จ ๋ฐ์์ ๋ฐ์ํ ์์ธ. ํ๋ก์ธ์ค์ ์ํฅ, ๋ ์ด์ ์คํ ๋ถ๊ฐ๋ฅ
๋ณดํต ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ๊ฑฐ๋ ๊ฐ์๋จธ์ ์์ฒด์ ๋ฌธ์ ๋ก ์ฑ ์์์ ์์ธ์ฒ๋ฆฌ๊ฐ ๋ถ๊ฐ๋ฅํ๋ค. - Runtime Exception (= unchecked Exception)
๋ฐํ์์์ ๋ฐ์ํ ์์ธ. ์ปดํ์ผ ๋จ๊ณ์์ ํ์ธํ ์ ์์ด unchecked๋ผ๊ณ ๋ ๋ถ๋ฅธ๋ค. - Checked Exception
์ปดํ์ผ ๋จ๊ณ์์ ํ์ธ ๊ฐ๋ฅํ ์์ธ๋ค.
Exception ์์ | ์์ธ ๋ฐ์ ์ด์ |
ArithmeticException | ์ ์๋ฅผ 0์ผ๋ก ๋๋๊ฒฝ์ฐ ๋ฐ์ |
ArrayIndexOutOfBoundsExcetion | ๋ฐฐ์ด์ ๋ฒ์๋ฅผ ๋ฒ์ด๋ index๋ฅผ ์ ๊ทผํ ์ ๋ฐ์ |
ClassCastExcetion | ๋ณํํ ์ ์๋ ํ์ ์ผ๋ก ๊ฐ์ฒด๋ฅผ ๋ฐํ ์ ๋ฐ์ |
NullPointException | ์กด์ฌํ์ง ์๋ ๋ ํผ๋ฐ์ค๋ฅผ ์ฐธ์กฐํ ๋ ๋ฐ์ |
IllegalArgumentException | ์๋ชป๋ ์ธ์๋ฅผ ์ ๋ฌ ํ ๋ ๋ฐ์ |
IOException | ์ ์ถ๋ ฅ ๋์ ์คํจ ๋๋ ์ธํฐ๋ฝํธ ์ ๋ฐ์ |
OutOfMemoryException | ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ ๊ฒฝ์ฐ ๋ฐ์ |
NumberFormatException | ๋ฌธ์์ด์ด ๋ํ๋ด๋ ์ซ์์ ์ผ์นํ์ง ์๋ ํ์ ์ ์ซ์๋ก ๋ณํ์ ๋ฐ์ |
Throwable ํด๋์ค
๋ชจ๋ ์ค๋ฅ, ์์ธํด๋์ค์ ๊ณตํต๋ ์กฐ์์ด๋ฉฐ Exception์ ์ฌ์ฉ๋๋ ๊ธฐ๋ณธ ๋ฉ์๋๋ค์ ์ ์ํ๊ณ ์๋ค.
Throwable.getMessage()
์์ธ ๋ฉ์์ง(์์ธ)์ ๊ฐ๋จํ๊ฒ String์ผ๋ก ๋ฐ๋๋ค.
Throwable.toString()
...print(e) ๋ชจ์์ผ๋ก ์ฃผ๋ก ์ฌ์ฉํ๋ฉฐ, getMessage() ๋ฉ์๋๋ณด๋ค๋ ์ฝ๊ฐ ๋ ์์ธํ๊ฒ, ์์ธ ํด๋์ค ์ด๋ฆ๋ ๊ฐ์ด ์ ๊ณตํ๋ค.
Throwable.printStackTrace()
์์ธ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ๊ณ ๋ ๋ฒ์งธ ์ค๋ถํฐ ์์ธ๊ฐ ๋ฐ์ํ๊ฒ ๋ ๋ฉ์๋๋ค์ ํธ์ถ ๊ด๊ณ(์คํ ํธ๋ ์ด์ค)๋ฅผ ์ถ๋ ฅํด์ค๋ค.
๋๋ฒ๊น ์ด๋ ์์ธ ๋ฉ์์ง๋ ์๋น์ค์ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ๋ ธ์ถ์ํฌ ์ ์๊ธฐ์ ์จ๊ธฐ๋ ๊ฒ์ด ์ข๋ค. ๊ทธ ์ด์ ๋ง๊ณ ๋ printStackTrace() ๊ฐ์ ์ฝ์ ์ถ๋ ฅ ์์ ์ ์์์ ๋ง์ด ์ก์๋จน๋ ํ๋ก์ธ์ค์ด๊ณ Therad-Safety ํ์ง ์๊ธฐ ๋๋ฌธ์ ์ค์ ์๋น์ค์์๋ ์ฌ์ฉํ๋ฉด ์๋๋ค. ๋ก๊ทธ๊ฐ ํ์ํ๋ค๋ฉด ๋ผ์ด๋ธ๋ฌ๋ฆฌ(log4j2, slf4j)๋ฑ์ ์ฌ์ฉํ๋๋ก ํ์.
์ ์ฌ์ฉํ๋ฉด ์๋๋๊ฑฐ์ฃ ?
[์๋ฌธ ๋งํฌ]
์์ธ ๋ฉ์์ง๊ฐ ์ต์ข ์ฌ์ฉ์์๊ฒ ๋ณด์์ผ๋ก์ ์๊ธฐ๋ ๋ณด์ ๋ฌธ์ ๋ ๋น์ฉ ๋ฌธ์ ๋ ์๊ฒ ์ง๋ง, ๋ค๋ฅธ ๋ฌธ์ ๋ ์์ต๋๋ค. ์ฐ์ , Throwable.printStackTrace() ๋ ์คํ ์ถ์ ๋ด์ฉ์ System.err ๋ผ๋ ํ์ค ์ฝ์์ถ๋ ฅ ์คํธ๋ฆผ์ ์ ์ต๋๋ค. System.err ๋ ์ฝ์์ด ์๋ ๋ค๋ฅธ ํ์ผ์ ๋ฆฌ๋ค์ด๋ ์ (System.setErr() ์ฌ์ฉ) ๋ ์ ์๊ณ ์ด๋ฐ ๋ฐฉ์์ ๋ก๊ทธ๋ ์ฝ๊ฒ ๋ถ์ํ๊ธฐ ์ด๋ ต์ต๋๋ค. ๊ฒ๋ค๊ฐ Throwable.printStackTrace()๋ ๋ค์ค ์ค๋ ๋ ์ฑ์์ ๋์ ํธ์ถ ๋ ๋, ์คํ ์ถ์ ์ ๊ฒน์น์ง ์๊ฒ ํ๋ ๋๊ธฐํ ๋ฉ์ปค๋์ฆ์ด ์์ต๋๋ค. ์ด๋ฌํ ๋์์ ์์คํ ์ ์์ด ์ฌ๊ฐํ ์ค๋ฅ์ Side-Effect๋ฅผ ์ผ๊ธฐํ๊ธฐ ๋๋ฌธ์ ์ค์ ์๋น์ค์์ ํธ์ถํ๋ฉด ์๋๋ ๋ฉ์๋์ ๋๋ค.
์๋ฐ 1.4๋ถํฐ ์ ๊ณต๋ java.util.logging ํจํค์ง๊ฐ ์์ง๋ง, ๊ธฐ๋ฅ์ด ์ข์ ํธ์ ์๋๋ผ 1.4 ๋ฒ์ ์ถ์ ๋น์์๋ log4j๊ฐ ์ฃผ๋ก ์ฌ์ฉ๋์์ต๋๋ค. ๋ง์ฝ ๋ก๊ทธ๊ฐ ํ์ํ๋ค๋ฉด log4j2๋ slf4j ๊ฐ์ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ์ ๊ถ์ฅํฉ๋๋ค.
# ์์ธ ์ฒ๋ฆฌ์ ์์ธ ๋ฐ์ (try, catch, finally, throw)
try, catch ๋ฌธ์ผ๋ก ์์ธ๋ฅผ ์ฒ๋ฆฌ ํ ์์๋ค. ๋ง์ฝ ์์ธ์ฒ๋ฆฌ ์ฌ๋ถ์ ์๊ด์์ด ์คํํ ์ฝ๋๊ฐ ์๋ค๋ฉด finally๋ฅผ ์ฌ์ฉํ๋ค.
try{
// ์๋ฌ๊ฐ ๋ฐ์ํ ์ ์๋ ์ฝ๋
// ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด ์ฝ๋ ์คํ์ ๋ฉ์ถ๊ณ catch๋ก ๋์ด๊ฐ๋ค.
}catch (Exception e){
// ์๋ฌ๊ฐ ๋ฐ์ ํ์ ๋ ์ฒ๋ฆฌํ ์ฝ๋. Exception ๊ฐ์ฒด๋ก ์์ธ๋ฅผ ํ์ธํ๋ค.
System.out.println(e); //์ค๋ฅ ์ถ๋ ฅ(๋ฐฉ๋ฒ์ ์ฌ๋ฌ๊ฐ์ง)
}finally{
//์์ธ ์ฒ๋ฆฌ ์ฌ๋ถ์ ์๊ด์์ด ๋ฌด์กฐ๊ฑด ์ํ
}
์์ธ๋ throw [Exception ๊ฐ์ฒด] ๋ฅผ ์ด์ฉํ์ฌ ๋ฐ์์ํฌ ์ ์๋ค.
public void throwException(int number){
try{
if(number>12){ // ์์ธ ๋ฐ์ ์ฝ๋
throw new Exception("Number is over than 12");
}
System.out.println("Number is " + number);
}catch(Exception e){
e.printStackTrace();
}
}
๋ง์ฝ catch ๋ฌธ์ ํด๋นํ๋ ์์ธ ๊ฐ์ฒด๊ฐ ์๋ค๋ฉด, ๋ฉ์๋์ throws ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ ๋ฉ์๋ ๋ฐ์ผ๋ก ๋์ ธ๋ฒ๋ฆด ์ ์๋ค. ์ด๋ฅผ ์์ธ ์ฒ๋ฆฌ๋ฅผ ์์ํ๋ค๊ณ ํํํ๋ฉฐ, catch ๋ฌธ์ ๋ง๋ ๋ ๊น์ง ๊ณ์ํด์ ์์ธ๋ฅผ ๋ฐ์ผ๋ก ์ ๋ฌํ๊ฒ ๋๋ค.
public void throwsException(int number) throws Exception{
// ์์ธ์ฒ๋ฆฌ๋ฅผ ํ์ง ์์ผ๋ฉด ๋ฉ์๋ ๋ฐ(๋ฉ์๋๊ฐ ํธ์ถ ๋ ๊ณณ)์ผ๋ก ์์ธ์ฒ๋ฆฌ๋ฅผ ์์ํ๋ค.
throw new Exception("Number is over than 12");
}
๋ฌผ๋ก ์ด๋ฐ์์ผ๋ก ์์ธ๋ฅผ ๋์ง๋ฉด ๋ฐ๋์ ์์ ๋ฉ์๋์์ try-catch๋ฌธ์ผ๋ก ์์ธ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ์ด์ผํ๋ค. ๋ง์ฝ ๋๊น์ง ํด์ฃผ์ง ์๊ณ ์ฑ์ ์ง์ ์ (Main)์์ ๊น์ง ์์ธ๋ฅผ ๋์ง๊ฒ ๋๋ฉด Main ๋ฉ์๋๋ฅผ ํธ์ถํ๋ JVM์์ ์์ธ๋ฅผ ์ก์(catch) ์ฒ๋ฆฌํ๊ฒ ๋๋ค.
# ๋๋ง์ ์์ธ ๋ง๋ค๊ธฐ
ํ์ํ๋ค๋ฉด Exception ์ด๋ RuntimeException์ ์์๋ฐ์ ์ง์ ์์ธ๋ฅผ ๋ง๋ค ์๋ ์๋ค. ์์ธ๋ฅผ ๋ง๋ฌ์ผ๋ก์ ๊ฐ์ฒด ์ฌ์ฉ์์๊ฒ ์ค๋ฅ์ํฉ์ ๋ณต๊ตฌ ํ ์ ์๋ ๊ธฐํ๋ฅผ ์ฃผ๊ณ ์์ธ ์ฒ๋ฆฌ๋ฅผ ๊ฐ์ ํ๋ ํจ๊ณผ๊ฐ ์๋ค.
// Divide 0 ์์ธ๋ฅผ ์ง์ ๋ง๋ค์๋ค.
class DivideException extends Exception {
DivideException(){
super();
}
DivideException(String message){
super(message);
}
}
class Calculator{
int left, right;
public void setOprands(int left, int right){
this.left = left;
this.right = right;
}
public void divide() throws DivideException{
if(this.right == 0){
throw new DivideException("0์ผ๋ก ๋๋๋ ๊ฒ์ ํ์ฉ๋์ง ์์ต๋๋ค.");
}
System.out.print(this.left/this.right);
}
}
// ๊ธฐ๋ณธ์ผ๋ก ์ ๊ณต๋๋ Exception ํด๋์ค๋ค๊ณผ ๋์ผํ๊ฒ ์ฌ์ฉ ํ ์ ์๋ค.
public class CalculatorDemo {
public static void main(String[] args) {
Calculator c1 = new Calculator();
c1.setOprands(10, 0);
try {
c1.divide();
} catch (DivideException e) {
e.printStackTrace();
}
}
}
# Try with Resource ๋ฌธ (์์ ํด์ )
Java7๋ถํฐ ์ ๊ณตํ๋ ๊ธฐ๋ฅ์ผ๋ก ์์คํ ์์ ํด์ (๋ฐํ)์ ์ฝ๊ฒ ํ ์์๊ฒ ํด์ค๋ค. ๊ธฐ์กด์ try-catch-finally ๊ตฌ๋ฌธ์ผ๋ก๋ ํ๋ก๊ทธ๋จ์ด ๋์ํ๋ค๊ฐ ๋ฉ์ถ๊ฒฝ์ฐ, ํ๋ก๊ทธ๋จ์ด ์ ์๋์ํ ๊ฒฝ์ฐ๋ฅผ ๋ค ๋๋ ๊ฐ๊ฐ ๋ค๋ฅด๊ฒ ์์ ํด์ ์ฝ๋( .close() )๋ฅผ ์์ฑํด์ผ ํ๋ค๋ฉด, ์ด๋ฅผ JVM์๊ฒ ์์ํ๋ ๋ฐฉ๋ฒ์ด๋ค.
public static void main(String args[]) {
// try (~) ์ ํ์ํ ์์ ๊ฐ์ฒด๋ฅผ ์ ์ธํ๋ค.
try (
FileInputStream is = new FileInputStream("file.txt");
BufferedInputStream bis = new BufferedInputStream(is)
) {// ์์ ์ฌ์ฉ
int data = -1;
while ((data = bis.read()) != -1)
System.out.print((char) data);
} catch (IOException e) {
// ์์ธ ์ฒ๋ฆฌ ์ฝ๋
}
// ์ด๋ ๊ฒ Try-Resource ๊ตฌ๋ฌธ์ ์ด์ฉํ๋ฉด Finally๋ฅผ ์ด์ฉํด ์์์ ํด์ ํ์ง ์์๋ ๋๋ค.
}
์ฐธ๊ณ ๋ก Java9 ๋ถํฐ๋ Try-with-resoucre๋ฌธ์ ์ข ๋ ์ ์ฐํ๊ฒ ์ฌ์ฉํ ์ ์๊ฒ ๋ฐ๋์๋ค. ๋ฐ์์ ์ ์ธํ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ ์ฌ์ฉํด๋ ๋์ผํ๊ฒ ์์์ ๊ด๋ฆฌํด์ค๋ค.
public class Class1 {
public method1() throws Exception {
Connection conn = DriverManager.getConnection("...");
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("SELECT 1 from dual")
try (conn; stat; rs) {
// ...
} catch (Exception e) {
// ...
}
}
}
๊ทธ๋ฐ๋ฐ ์๋ฐ์์ ์์์ด๋ ๋ฉ๋ชจ๋ฆฌ๋ JVM์ด ์์์ ๊ด๋ฆฌํด์ฃผ๋๊ฑฐ ์๋์๋์?
์ฌ๊ธฐ์์ ์๋ฌธ์ ๋๋ผ๋ ์ฌ๋๋ ์์ ๊ฒ์ด๋ค. ๋ถ๋ช ์๋ฐ์ ๋ฉ๋ชจ๋ฆฌ๋ JVM์ Garbage Collector๊ฐ ์์์ ๊ด๋ฆฌํด์ค๋ค๊ณ ํ๋๋ฐ, ์ ๊ตณ์ด .close() ๋ฉ์๋๋ก ์์์ ํด์ ํด์ผ ํ๋ ๊ฒ์ผ๊น?
์ฌ๊ธฐ์ .close()๋ฅผ ํด์ฃผ์ด์ผ ํ๋ ์์์ GC์์ ๊ด๋ฆฌํ๋ ์์(๋ฉ๋ชจ๋ฆฌ์ ํ ๋น๋ ์ธ์คํด์ค)์ด ์๋๋ผ ํ๋ก๊ทธ๋จ์ ์ฌ์ฉ๋๋ ์ธ๋ถ ์์, ์ฆ ์ด์์ฒด์ ์์ ์ ๊ณตํ๋ ์์คํ ์์์ ์๋ฏธํ๋ค.
์ธ๋ถ์์์ ํ์ผ๋ก ์๋ฅผ ๋ค๋ฉด A.txt ์ถ๋ ฅ์ ์ํด์ ๋์คํฌ์ ์ ์ฅ๋์ด์๋ A.txt์ ๋ด์ฉ์ ํ์ฌ ํ๋ก์ธ์ค์ ๋ฉ๋ชจ๋ฆฌ๋ก ๊ฐ์ ธ์์ผ ํ๋๋ฐ, ํด๋น ํ์ผ์ ๋ด์ฉ์ ์ ๋ถ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ฆฌ๋ ๊ฒ์ ์๋นํ ๋นํจ์จ์ ์ด๊ณ ๋ถ๋ด์ด ๋ง์ ์์ ์ด๋ค. ๊ทธ๋์ ํ์ผ์ ํต์ผ๋ก ๊ฐ์ ธ์ค๋๊ฒ ์๋๋ผ, ํ์ผ์ ๋ํ ์ ์ถ๋ ฅ Stream์ ์์ฑํ์ฌ ์ฐ๊ฒฐํ๊ณ ๊ทธ Stream์ ์ด์ฉํ์ฌ ํ์ผ์ ์ํ๋ ๋ถ๋ถ์ ์ํ๋ ๋งํผ ์ฝ๊ณ ์ฐ๋๋ฐ, ์ฌ๊ธฐ์์ ์ ์ถ๋ ฅ Stream์ ์ด์์ฒด์ ์์ ์ ๊ณตํด์ฃผ๋ ์์(๋ช ๋ น์ด)์ ์ด์ฉํ๋ฉฐ ๋ง๋ ๋ค. ์ด๋ฐ ์์ผ๋ก DB์ปค๋ฅ์ , ๋คํธ์ํฌ ์ปค๋ฅ์ , ์ฐ๋ ๋๋ฑ์ ์ฌ์ฉํ๋ค.
๋ณดํต ์ด๋ฌํ Stream ํด๋์ค๋ค์ ์ฌ์ฉ์ ๋ง์น๊ณ ์ด์์ฒด์ ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ฐํํ๋ .close() ๋ฉ์๋๊ฐ ์ ๊ณต๋๋ค. ๋ฌผ๋ก close๋ฅผ ํธ์ถํ์ง ์์๋ JVM์์ ์ฌ์ฉํ์ง ์๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ถ์ ํ์ฌ ๋ฐํํ๊ธฐ๋ ํ์ง๋ง ๋๋๋ก์ด๋ฉด ํ๋ ๊ฒ์ด ์ข๋ค. ํ์ง๋ง ์์คํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ฐํํ๋ ์์ ์ ์์ธ์ฒ๋ฆฌ๊ฐ ๋งค์ฐ ๊น๋ค๋ก์ด๋ฐ ์ด๋ฅผ ์ฝ๊ฒ ์ฒ๋ฆฌํ๊ธฐ ์ํด Java7๋ถํฐ try (~) ์์ ์ ์ธ๋ ๊ฐ์ฒด๋ ํด๋น ๊ตฌ๋ฌธ์ด ๋๋๋ฉด ์๋์ผ๋ก ์์์ ๋ฐ๋ฉํ๋๋ก ๊ธฐ๋ฅ์ ๋ง๋ค์ด์ฃผ์๋ค.
'๐ฑBackend > Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
#10 Modern Java (Java8~) (0) | 2021.07.12 |
---|---|
#8 Java - 3 (์ฐ๋ ๋, IO, ๋คํธ์ํฌ) (0) | 2021.07.09 |
#6. Java - 2 ํด๋์ค (์์ฑ์์ ) (0) | 2021.07.07 |
#5. ์๋ฐ์ Interface (2) | 2021.07.01 |
#4. ์๋ฐ ํจ์ํ ์ธํฐํ์ด์ค (0) | 2021.07.01 |
๋ธ๋ก๊ทธ์ ์ ๋ณด
JiwonDev
JiwonDev