자바(Java)의 기초 박살내기 - 예외처리(Exception) & java.lang 패키지


이번 시간에는 예외처리와 java.lang 패키지에 대해 공부하겠습니다.

예외처리를 잘쓰느냐 못쓰느냐가 잘하는 개발자인지 못하는 개발자인지 구분 가능하다고 했습니다.


 1. Package & Import 


- 패키지 : 서로 관련된 클래스와 인터페이스의 컴파일 된 클래스 파일들을 하나의 디렉터리에 묶어 놓은 것


- import : 클래스의 사용을 간편하게 하기 위햐서 줄여쓸 수 있도록 하기 위한 개념

- import 패키지명.*; : 패키지의 모든 클래스를 줄여서 사용하고자 하는경우

- import 패키지명.클래스명 : 특정 클래스만 줄여쓰기를 하고자 하는 경우

- static import : 클래스의 static 멤버나 final 변수를 클래스 이름 없이 사용하고자 할 때 사용 

- import static [패키지경로.클래스명.*];

- import static [패키지경로.클래스명.final변수명];



- 다른 패키지 갖다 쓰는법

- import를 이용하지 않는 경우

- 소스 내에서 매번 전체 패키지 이름과 클래스 이름을 써주어야함

- import 키워드를 이용하는 경우

- 소스의 시작 부분에 패키지 명시시 계속 사용 가능


<예제 소스코드 - StaticImport.class>

1
2
3
4
5
6
7
8
9
10
11
12
13
// 소스 시작부분에 import 사용법
import static java.lang.System.out;
import static java.lang.Thread.MAX_PRIORITY;
 
public class StaticImport 
{
    public static void main(String arg[])
    {
        out.println("Hello");
        out.println(MAX_PRIORITY);
    }
}
 
cs



<결과>


- 패키지의 특징

① 계층구조

- 클래스나 인터페이스가 너무 많아지면 관리의 어려움

- 관련된 클래스 파일을 하나의 패키지로 계층화햐여 관리 용이

② 패키지별 접근제한

- default로 선언된 클래스나 멤버는 동일 패키지 내의 클래스들이 자유롭게 접근하도록 허용

③ 동일한 이름의 클래스와 인터페이스의 사용 가능

- 서로 다른 패키지에 이름이 같은 클래스와 인터페이스 존재 가능

④ 높은 소프트웨어 재사용성

- 오라클에서 제공하는 자바 API는 패키지로 구성되어 있음

- java.lang, java.io등의 패키지들 덕분에 일일이 코딩하지 않고 입출력 프로그램을 간단히 작성 가능


- JDK 패키지

- 자바에서는 관련된 클래들을 표준패키지로 묶어 사용자에게 제공합니다.

- C언어 표준 라이브러리와 유사합니다.

C:\Program Files\Java\jdk1.8.0_121\jre\lib 안에 rt.jar에 압축되어 있습니다.


<JDK 패키지 직접 보는법>

① C:\Program Files\Java\jdk1.8.0_121\jre\lib 이동합니다.

② rt.jar 오른쪽 클릭후 압축을 푸시던가 저처럼 미리보기 기능을 이용해 들어갑니다.


③ java -> awt 폴더로 이동하시면 JDK에서 지원하는 클래스들을 확인 하실 수 있습니다. 


- JDK 패키지 종류

- java.lang

- 자바 language 패키지 : String, Math메소드, 입출력 등 기본적인 클래스와 인터페이스

- 자동으로 import됨 - import 할 필요 없음

- java.util

- 자바 유틸리티 패키지 : 날짜, 시간, 벡터, 해쉬테이블 등 다양한 유틸리티 클래스와 인터페이스 제공

- java.io

- 키보드, 모니터, 프린터, 디스크 등 입출력 할 수 있는 클래스와 인터페이스

- java.awt

- 자바 GUI 프로그래밍을 위한 클래스와 인터페이스

- javax.swing

- 자바 GUI 프로그래밍을 위한 스윙 패키지


 2. 예외(Exception) 


- 예외 : 문법적으로는 이상이 없어서 컴파일 시점에는 아무런 문제가 없지만 프로그램 실행 중에 발생하는 예기치 않는 사건으로 발생하는 오류


- 예외가 발생하는경우

① 정수를 0으로 나눈 경우

② 배열의 첨자가 음수 또는 범위를 벗어나는 경우

③ 부적절한 형 변환이 일어나는 경우

④ 입출력을 위한 파일이 없는 경우 등등


- 예외처리의 용도

① 정상 종료

② 예외내용 보고

③ 예외 발생 시 무시하고 계속 실행

④ 정상적인 값으로 변경


<예외처리 발생하는경우 예제 소스코드 - ExceptionExist.class>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ExceptionExist 
{
    public static void main(String[] args) 
    {
        func();                 //메소드 호출
    }
    
    static void func() 
    {
        int i = 1;
        int j = 0;
        System.out.println(i/j);    // 1을 0으로 나눈다. 예외 발생
    }
}
cs


<결과>



 3. 예외 관련 클래스 


- 자바는 예외를 객체로 취급


- 예외 관련 클래스를 java.lang 패키지에서 제공


- 모든 예외 관련 클래스는 java.lang.Throwable 클래스의 하위 클래스


- 자바 예외 처리 최상 클래스 : Throwable


- Exception 클래스의 주요 하위 클래스들

 NoSuchMethodException

 메소드가 존재하지 않을 때 

 ClassNotFoundException

 클래스가 존재하지 않을 때 

 CloneNotSupportException

 객체의 복제가 지원되지 않는 상황에서 복제를 시도하고자하는 경우 

IllegalAccessException

 클래스에 대한 부정적인 접근

 InstantiationException

 추상클래스나 인터페이스로부터 객체를 생성하고자 하는 경우 

 InteruptedException

 스레드가 인터럽트 되었을 때 

 RuntimeException

 실행시간에 예외가 발생한 경우 

 IOException

 입출력과 관련된 예외 처리 


- RuntimeException 클래스의 주요 하위 클래스

 ArithmeticException

 0으로 나누는 등의 산술적인 예외 

 NegativeArraySizeException

 배열의 크기를 지정할 때 음수의 사용 

 NullPointerException

 Null 객체의 메소드나 멤버 변수에 접근하고자 하는 경우 

 IndexOutOfBoundException

 배열이나 스트링 범위를 벗어날 때 

 SecurityException

 보안을 이유로 메소드를 수행할 수 없을때 


- 주요 멤버

- public String getMessage()

- Throwable 오브젝트의 상세 메세지 캐릭터 라인을 돌려줍니다.

- public void printStackTrace()

- Throw 가능 오브젝트 및 그 백트레이스를 표준 에러 스트림에 출력


- 예외 처리하는 방법

- 예외가 발생된 메소드 내에서 처리하는 방법(try, catch절 사용)

- 예외가 발생된 메소드를 호출한 메소드에게 예외의 처리를 넘겨주는 방법

(Throws 절 사용)


<예외처리 안하는 경우 예제 소스코드 - ExceptionProblem.class>

1
2
3
4
5
6
7
8
9
10
11
public class ExceptionProblem 
{
    public static void main(String[] args) 
    {
        int ar[] = {10,20,30};
        for(int i=0 ; i <= ar.length ; i++)
        {
            System.out.println("ar[" + i + "] : " + ar[i]);    
        }        
    }
}
cs


<결과>

- 정상적으로 동작하다가 마지막에 배열의 요소가 3개인데 4번째 까지 출력하고자 했으므로 4번째 출력문에서 에러가 발생하게 된다.


<예외처리 하는 경우 예제 소스코드 - ExceptionProblem.class>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class ExceptionProblem 
{
    public static void main(String args[])
    {
        int[] ar = {102030};
        
        try
        {
            for(int i = 0 ; i <=3 ; i++)
            {
                System.out.println("ar[" + i + "] : " + ar[i]);
            }
        }catch(Exception e)
        {
            System.out.println("예외가 발생 했습니다....");
        }finally //에러가 발생하든 안하든 실행
        {
            System.out.println("==================================");
            System.out.println("예외 발생여부와 상관없이 수행됩니다.");  
        }
    }
}
cs


<결과>

- 예외처리 형식

try

{

// try 블록: 예외가 발생할 가능성이 있는 문장을 지정

}catch(예외타입1 매개변수1)

{

// 예외 처리 블록1: 예외의 종류에 따라 처리하는 처리

}catch(예외타입N 매개변수N)

{

// 에외 처리 블록N

}finally

{

// finally 블록: 예외의 발생여부와 상관없이 무조건 수행되는 블록

// 생략가능

}


 4. 예외의 인위적 발생 


- 예외를 발생시키기 위해 throw문 사용

- throw 예외객체;

또는

- throw new 예외객체타입(매개변수);


<예제 소스코드 - Accident.class>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Accident 
{
    public static void main(String[] args)
    {
        try
        {
            int Jumsu = Integer.parseInt(args[0]);
            
            if(Jumsu > 100)
            {
                throw new NumberFormatException("점수가 너무 큼");
                //예외 인위적 발생
            }
        }catch(NumberFormatException e)
        {
            System.out.println("=====================");
            System.out.println(e.getMessage() + "예외 발생");
        }
    }
}
cs


<결과>



 5. 사용자 정의 예외 클래스 


- 사용자가 새로운 예외를 정의하여 사용할 수 있습니다.


- 예외에 대한 정보를 변경하려고 할 때 사용자가 직접 작성하여 예외를 발생시켜 원하는 결과를 얻는데 목적이 있습니다.


- 사용자 정의 Exception을 작성하기 위해서는  Throwalbe로 부터 상속받지 않고 그 하위에 있으면서 보다 많은 기능들로 확장되어 있는 Exception으로부터 상속 받는 것이 유용합니다.


- 입출력 관련된 예외만 작성할 때에는 IOException으로 부터 상속을 받아도 상관없습니다.


<예제 소스코드1 - UserException.class>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import java.io.BufferedReader;
import java.io.InputStreamReader;
 
public class UserException 
{
    public static void main(String args[])
    {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        
        // 예외처리
        try
        {
            System.out.println("하나의 숫자를 입력하세요 => ");
            int jumsu = Integer.parseInt(in.readLine());
            
            if(jumsu < 0)    // jumsu변수가 0보다 작을 경우 인위적 예외처리
            {
                throw new UserException1("점수가 너무 작음");
            }else if(jumsu > 100)    // jumsu변수가 0보다  경우 인위적 예외처리
            {
                throw new UserException2("점수가 너무 큼");
            }
            System.out.println("정상적인 점수 입력");
        }catch(UserException1 e)
        {
            System.out.println("UserException1 처리 루틴 : ");
            System.out.println(e + "발생");
        }catch(UserException2 e)
        {
            System.out.println("UserException2 처리 루틴 : ");
            System.out.println(e + "발생");
        }catch(Exception e)
        {
            System.out.println("모든 예외 처리 루틴 : ");
            System.out.println(e + "발생");
        }
    }
}
cs


<예제 소스코드2 - UserException1.class>

1
2
3
4
5
6
7
8
9
// 사용자 정의 예외는 Exception 클래스로부터 
public class UserException1 extends Exception
{
    public UserException1(String message)
    {
        super(message);
    }
}
 
cs


<예제 소스코드3 - UserException2.class>

1
2
3
4
5
6
7
8
9
// 사용자 정의 예외는 Exception 클래스로부터 상속
public class UserException2 extends Exception 
{
    public UserException2(String message)
    {
        super(message);
    }
}
 
cs


<결과>

① 정상적인 결과


② 0보다 작을 경우 결과 - 사용자 정의 예외처리1 발생(UserException1)


③ 100보다 클 경우 결과 - 사용자 정의 예외처리2 발생(UserException2)


④ 문자 입력했을때 결과 -> 모든 예외처리 발생(Exception)



 6. ASSERTION 


- ASSERTION이란 프로그래머 자신이 작성한 코드에서 프로그래머 자신이 생각하고 있는 움직임과 그리고 특정 지점에서의 프로그램상의 설정 값들이 일치하고 있는지를 검사


- 형식

- assert[boolean식];

- assert[boolean식]: "메시지";

- Ex) assert var > 10 : 10보다 큰 값이어야함

   assert str != null : "str에 null값이 들어오면 안됨!";


<Assertion설정하기>

- 이클립스에서는 Assertion을 무시하도록 default 되어있기 때문에 설정을 해줘야한다.


① 좌측상단을 보시면 Run 아이콘 옆에 화살표를 눌러 RunConfigurations에 들어간다.

② 창이 하나 뜨면 arguments 탭으로 들어간다.


③ VM arguments에 "-ea"를 입력후 적용을 누른다.


<예제 소스코드 - AssertTest.class>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.io.BufferedReader;
import java.io.InputStreamReader;
 
public class AssertTest 
{
    public static void main(String args[]) 
    {
        int a;
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
 
        try
        {
            System.out.println("점수를 입력하세요");
            a = Integer.parseInt(in.readLine());
            // 0부터 99까지 숫자이외의 입력시 assertiong발생!
            assert (a < 100 && a >= 0): "올바르지 못한 점수를 입력하셨습니다.";
            System.out.println("올바른 점수를 입력하셨습니다");
        }catch(Exception e)
        {
            System.out.println("예외 발생");
            
        }            
    }
}
 
cs


<결과>


 7. java.lang.Object 


- Object 클래스

- 모든 자바 프로그램의 최상위 클래스이다.

- extends 예약어를 사용하지 않아도 상속 됩니다.


- Object 클래스의 메소드

- Object() : 디폴트 생성자

- Object clone() : 객체를 복제하기 위해 사용하는 메소드

- boolean equals(Object object) : 두 개의 객체가 같은 지를 비교하여 같으면 true, 다르면 false

- void finalize() : 객체가 점유되고 있던 자원들을 해제하는데 사용하는 메소드

- int hashCode() : 호출한 객체와 연관된 hash코드를 반환

- String toString() : 현재 객체의 문자열 표현을 반환

- void notify() : 대기 중인 스레드 중 하나의 스레드를 시작

- void notifyAll() : 대기 중인 모든 스레드를 다시 시작

- void wait() : 실행을 중지시키고 대기 상태로 이동


<예제 소스코드 - AssertTest.class>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class ObjectTest 
{
    int data;
    // Object 생성자
    public ObjectTest(int x)
    {
        data = x;
    }
    
    // 객체를 복제 하기위한 사용자 메소드
    public ObjectTest clone() throws CloneNotSupportedException
    {
            ObjectTest Temp = new ObjectTest(this.data);
            return Temp;
    }
    
    
    public static void main(String args[])
    {
        ObjectTest Obj1 = new ObjectTest(10);
        ObjectTest Obj2 = Obj1;
        ObjectTest Obj3 = new ObjectTest(10);
        ObjectTest Obj4 = Obj1;
        
        try
        {
            // 객체 복제
            Obj4 = Obj3.clone();
        }catch(CloneNotSupportedException e)
        {
            Obj4 = null;
            System.out.println("복제할 Object가 없음");
        }
        
        int i = 10;
        int j = 10;
        if(i == j)
            System.out.println("i와 j의 값은 같음");
        if(Obj1 == Obj2)
            System.out.println("Obj1과 Obj2의 위치는 같음");
        else
            System.out.println("Obj1과 Obj2의 위치는 다름");
        
        if(Obj1 == Obj3)
            System.out.println("Obj1과 Obj3의 위치는 같음");
        else
            System.out.println("Obj1과 Obj3의 위치는 다름");
        
        if(Obj1.equals(Obj2))
            System.out.println("Obj1과 Obj2의 내용은 같음");
        else
            System.out.println("Obj1과 Obj2의 내용은 다름");
    }
}
cs


<결과>



>> 여기까지 예외처리와  java.lang 패키지에대해서 알아보았습니다. 다음 시간에는 스레드에 대해서 공부하겠습니다.

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유