본문 바로가기
JAVA

JAVA(예외처리, 날짜처리, 컬렉션)

by 글로리. 2020. 6. 15.

예외상황 : 에러가 발생하여 실행을 못하는 것.

에러의 종류

컴파일 에러

  • 소스코드 구문오류로 인한 컴파일 불가.
  • 이클립스에서 빨간색밑줄로 표시됨.
  • 프로그램이 실행되기전에 발견되므로 상대적으로 수정에 용이함.

런타임 에러

  • 구문상 에러는 없으나, 실행과정에서 다양한 경우의 수에 대응하지 못하여 발생하는 예외상황.
  • 런타임 에러시 프로그램 강제종료.
  • 우리가 흔히 말하는 프로그램 에러는 대부분 런타임 에러에 해당.

런타임 에러 종류

  1. 논리오류
    • 논리적 모순이 생기지 않도록 코드를 작성해야 함.
  2. 자바가상머신 자체 오류 (메모리 과다사용)
    • 프로그래머가 책임 질 수 있는 수준의 오류가 아님.
  3. 예외
    • 프로그램 실행 중에 발생할 수 있는 예기치 찮은 사건으로, 프로그래머의 노력으로 처리가능.
    • 자바가상머신은 프로그램 실행중에 예외가 발생하면 관련된 예외 클래스로부터 예외객체를 생성하여 프로그램에서 지정된 예외처리 구문으로 넘긴다.
    • 예외가 발생하면 프로그램에 지정된 구문이 자바가상머신에 의해 호출, 이 때 전달되는 예외객체를 넘겨받아 적절한 처리를 수행.

에러 방지 방법

  • 고전적인 에러 방지 방법
    • if문 사용

자주 접하게 되는 예외상황 클래스

예외 클래스 상황
ArithmeticException 어떤 수를 0으로 나누는 것과 같이 비정상 계산 중 발생
NullPointerException NULL객체 참조시 발생
IllegalArgumentException 메소드의 전달 인자값이 잘못될 경우 발생
IllegalStateException 객체의 상태가 메소드 호출에는 부적합할 경우 발생
IndexOutOfBoundsException index값이 범위를 넘어갈 경우 발생
UnsupportedOperationException 객체가 메소드를 지원하지 않은 경우 발생
SecurityException 보안 위반 발생 시 보안 관리 프로그램에서 발생
ProviderException 구성 공급자 오류시 발생
NoSuchElementException 구성요소가 그 이상 없는 경우 발생
ArrayStoreException 객체 배열에 잘못된 객체 유형 저장시 발생
ClassCastException 클래스 간의 형 변환 오류시 발생
EmptyStackException 스택이 비어있는데 요소를 제거하려고 할시 발생

java의 예외처리 (try ~ catch ~ finally 구문사용)

try {
    // 기본적으로 실행되는 내용
}
catch (예외클래스이름 객체이름) {
    // try 블록에서 예외가 발생한 경우 이곳으로 넘어온다.
}
finally {
    // 예외 상황의 발생여부에 상관없이 무조건 실행되는 부분
    // finally 블록은 생략 가능
}
  • try블록 실행 도중 catch에서 명시한 예외 클래스에 해당하는 에러 발생 시
    • try블록 중단 -> catch 블록 실행 -> finally 블록 실행
  • 예외 발생 하지 않을 시
    • try 블록 종료 -> finally 블록 실행.

Exception 클래스

  • java에서 예외상황을 의미하는 모든 클래스들의 최상위 클래스
  • Exception 클래스 이름으로 catch블록을 구성하면 모든 예외상황에 가능하지만 어떤 예외상황인지 판가름 할수는 없다.
  • Excrption 클래스에 대한 예외처리는 대부분 맨 마지막에 입력하며 생각하지 못한 예외상황에 대해 대비함.

에러 객체 'e'의 기능

  • e.getMassage()
    • 간략한 에러 메시지 리턴.
    • e.getLocaliseMassage()도 같은 기능을 함.
  • e.printStackTrace()
    • 실제 예외 상황시에 출력되는 메시지를 강제 출력
    • 개발자가 catch 블록 안에서 예외상황을 분석하기 위한 용도로 사용.(예외상황이 예측되어 입력했으나 어떤부분에서 어떤 내용으로 에러인지 알고 싶을때)

날짜처리

1) java.util.Caledar 클래스의 기본사용방법

import java.util.Calendar;

public class Main01 {
    public static void main(String[] args) {
        // 캘린더 객체의 생성 --> 싱글톤 객체
        Calendar cal = Calendar.getInstance();

        // 년, 월, 일, 시, 분, 초>> 24시간제
        int yy = cal.get(Calendar.YEAR);
        // 자바에서의 월은 0부터 시작된다
        // 자바에서 월은 배열형태로 되어 있어 출력시 인덱스번호를 사용하므로 +1을 해줘야 한다.
        int mm = cal.get(Calendar.MONTH)+1;
        int dd = cal.get(Calendar.DAY_OF_MONTH);
        int hh = cal.get(Calendar.HOUR_OF_DAY);
        int mi = cal.get(Calendar.MINUTE);
        int ss = cal.get(Calendar.SECOND);

        System.out.printf("%04d년 %02d월 %02d일 %02d시 %02d분 %02d초\n", yy, mm, dd, hh, mi, ss);

        // 년, 월, 일, 시, 분, 초 >> 12시간제
        yy = cal.get(Calendar.YEAR);
        // 자바에서의 월은 0부터 시작된다
        mm = cal.get(Calendar.MONTH)+1;
        dd = cal.get(Calendar.DAY_OF_MONTH);
        hh = cal.get(Calendar.HOUR);
        mi = cal.get(Calendar.MINUTE);
        ss = cal.get(Calendar.SECOND);

        // 오전(=0), 오후(=1)
        int ampm = cal.get(Calendar.AM_PM);
        String[] apname = {"오전", "오후"};

        System.out.printf("%04d년 %02d월 %02d일 %s %02d시 %02d분 %02d초\n", yy, mm, dd, apname[ampm], hh, mi, ss);

        //현재 날짜 + 시각을 yyyymmddhhmiss 형식으로 출력
        yy = cal.get(Calendar.YEAR);
        mm = cal.get(Calendar.MONTH)+1;
        dd = cal.get(Calendar.DAY_OF_MONTH);
        hh = cal.get(Calendar.HOUR_OF_DAY);
        mi = cal.get(Calendar.MINUTE);
        ss = cal.get(Calendar.SECOND);

        System.out.printf("%04d%02d%02d%02d%02d%02d", yy, mm, dd, hh, mi, ss);
    }
}

// 실행결과
xxxx년 xx월 xx일 xx시 xx분 xx초
xxxx년 xx월 xx일 오전/오후 xx시 xx분 xx초
yyyymmddhhmiss

2) Calendar 클래스의 기타 기능

import java.util.Calendar;

public class Main04 {
    public static void main(String[] args) {
        Calendar cal = Calendar.getInstance();

        // 요일에 해당하는 인덱스 (일=1 ~ 토=7)
        int day = cal.get(Calendar.DAY_OF_WEEK);
        System.out.println("요일 인덱스=" + day);

        // 요일 출력하기
        String[] day_name = {"일","월","화","수","목","금","토"};
        System.out.println("요일 = " + day_name[day-1]);

        // 이번 달은 몇 주로 되어 있는가?
        int week_count = cal.getActualMaximum(Calendar.WEEK_OF_MONTH);
        System.out.println("이번 달은 " + week_count + "주로 되어있다.");

        // 이번달은 몇 일까지 있는가?
        int day_count = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        System.out.println("이번달은 " + day_count + "일까지 있다.");                
    }
}

// 실행결과
요일 인덱스 = 1
요일 = 일
이번달은 x주로 되어 있다.
이번 달의 시작 요일 인덱스 = (해당 월의 시작 요일 인덱스)
이번 달의 시작 요일 = (해당 월의 시작 요일)

3) 달력 만들기

import java.util.Calendar;

public class Main05 {
    public static void main(String[] args) {
        Calendar cal = Calendar.getInstance();

        // 이번달은 몇 주로 되어 있는가?
        int week_count = cal.getActualMaximum(Calendar.WEEK_OF_MONTH);

        // 이번달은 몇 일 까지 있는가?
        int day_count = cal.getActualMaximum(Calendar.DAY_OF_MONTH);

        // 이번 달은 무슨 요일부터 시작하는가?
        cal.set(Calendar.DAY_OF_MONTH, 1);
        int first_day = cal.get(Calendar.DAY_OF_WEEK);

        // 이번 달은 몇 주 인가?  --> 행
        // 일~토 요일 --> 열
        int[][] data = new int[week_count][7];
        // 출력할 날짜값 --> 이 값이 1씩 증가한다.
        int count = 1;

        /** "주"수 만큼 반복한다. */
        for (int i=0; i<data.length; i++) {
            /** 일~토 요일 까지 반복 */
            for (int j=0; j<data[i].length;j++) {
                if (i==0&& j <first_day -1) {
                    // i가 0 --> 첫 번째주
                    // j의 값은 요일에 대한 체크
                    // --> 이번달 첫 주에서 1일이 시작되는 요일 전까지
                    data[i][j] = 0;
                }
                else if (count > day_count) {
                    // 이번 달의 마지막 날을 초과한 경우
                    data[i][j] = 0;
                }
                else {
                    // 그 외의 경우에는 날짜값을 복사하고, 날짜 값을 1 증가 시킨다.
                    data[i][j] = count++;
                }
            }
        }
                /** 배열 출력을 위한 반복문 */
                for (int i =0; i<data.length; i++) {
                    for (int j=0; j<data[i].length; j++) {
                        if (data[i][j] == 0) {
                            System.out.print("\t");
                        }
                        else {
                            System.out.printf("%2d\t", data[i][j]);
                        }
                    }
                    System.out.println();
                }
    }
}

// 실행결과
입력 당월 달력 출력.

밀리세컨드

밀리세컨드 : 국제표준시각(UTC, GMT) 1970/1/1/0/0/0 으로부터 경과한 시각

import java.util.Calendar;

public class Main06 {
    public static void main(String[] args) {
        // 어떤 처리에 대한 시작 시간을 얻는다ㅏ.
        Calendar cal = Calendar.getInstance();
        // 현재 시각에 대한 TimeStamp를 밀리세컨드 단위로 얻기
        long ms1 = cal.getTimeInMillis();
        System.out.println("파일복사 시작 >> " + ms1);

        // 프로그램을 주어진 시간동안 대기하도록 하는 처리
        try {
            Thread.sleep(5000);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 처리에 대한 종료 시각 얻기
        long ms2 = System.currentTimeMillis();
        System.out.println("파일복사 끝 >> " + ms2);

        // 두 시간의 차이 얻기
        long x = ms2 - ms1;
        System.out.println(x);

        // 1/1000초 이므로, 1000으로 나누면 소요 시간 얻을 수 있음
        long y = x / 1000;
        System.out.println(y + "초 지났음.");
    }

}

// 실행결과

컬렉션 프레임워크(Collection Framework)

  • 다수의 데이터를 쉽게 처리할 수 있는 표준화 된 방법을 제공하는 클래스

컬렉션 프레임워크의 종류

HashMap 클래스 -> 파이썬에서 '딕셔너리'와 같음

  • HashMap 클래스는 Map 인터페이스를 상속받는 '자료 보관소' 이기 때문에, 암묵적 형변환의 규칙에 따라 Map형태로 선언하고 HashMap 형태로 할당.
  • 제너릭스 : 선언과 할당시 HashMap의 이름표로 사용할 데이터 형 (String)과 HashMap에 저장할 데이터형을 클래스의 이름을 명시하는것
  • 제너릭스에 입력하는 데이터형은 반드시 클래스 이름이어야 한다. 기본 자료형을 보관할 경우 Wrapper클래스의 이름 사용.
  • 기존에 저장된 데이터와 이름이 같을때에는 덮어씌운다.
//<제너릭스>
Map<String, 저장할 데이터 클래스이름> data = new HashMap<String, 저장할 데이터의 클래스이름>();

HashMap클래스 사용 예시

import java.util.HashMap;
import java.util.Map;

public class Main01 {
    public static void main(String[] args) {
        // 데이터를 저장할 배열 생성
        // 제너릭 --> <값의 이름, 값의 종류> 
        Map<String, Integer>hm = new HashMap<String, Integer>();

        // 데이터 추가는 put메서드 사용
        // --> 중복을 허용하지 않는다. 중복된 내용은 덮어씌운다.
        hm.put("aaa",111);
        hm.put("bbb",222);
        hm.put("aaa",444);
        hm.put("ccc",333);
        hm.put("ccc",null);  // 객체를 넣는것이므로 Null 사용가능        

        // 저장된 갯수 얻기
        System.out.println("HashMap size : " + hm.size());

        // 데이터 꺼내기
        System.out.println(hm.get("aaa"));
        System.out.println(hm.get("bbb"));
        System.out.println(hm.get("ccc"));
    }

}

// 실행결과
444
222
null

ArrayList -> 무제한 확장 가능한 배열, '고무줄'이라 생각

  • ArrayList는 List 인터페이스를 상속받는 클래스로 데이터를 이름표 없이 무제한으로 보관 가능.
  • ArrayList에 추가되는 데이터는 순차적으로 인덱스 번호를 부여 받음.
  • 상위 인터페이스형으로 선언, ArrayList 클래스로 객체 할당.
  • 선언과 할당시에는 보관하고자 하는 자료형에 대한 제너릭스를 명시
List<저장할 데이터의 클래스이름> 저장할 리스트이름 = new ArrayList<저장할 데이터의 클래스이름>();

ArrayList클래스 사용예시

import java.util.ArrayList;
import java.util.List;

public class Main02 {
    public static void main(String[] args) {
        // 객체 생성시 제너릭스의 사용
        // --> 클래스 이름 오른쪽에 <자료형>의 형식으로 표현한다.
        // 이 때 자료형에는 클래스타입만 가능.
        // 기본 데이터형을 사용하고자 하는 경우에는
        // 해당 데이터형의 WraooerClass를 사용해야 한다.
        List<Integer> numberList = new ArrayList<Integer>();

        // 데이터 추가하기
        numberList.add(10);
        numberList.add(20);
        numberList.add(30);
        numberList.add(40);
        numberList.add(50);
        numberList.add(60);
        numberList.add(70);
        numberList.add(80);
        numberList.add(90);

        // 추가된 데이터의 수량
        int count = numberList.size();
        System.out.println("데이터 크기: " + count);

        // 5번째 요소의 값 얻기
        int value = numberList.get(4);
        System.out.println("5번째 요소의 값: " + value);

        // 5번째 요소 삭제 -> 6번째 요소가 5번째로 당겨짐.
        numberList.remove(4);

        // 하나를 삭제 후, 전체 크기 다시 조회 --> 8개
        count = numberList.size();
        System.out.println("데이터 크기: " + count);

        // 5번째 요소의 값을 다시 얻기
        value = numberList.get(4);
        System.out.println("5번째 요소의 값: " + value);

        // 5번째 자리에 데이터 추가 -> 이전 5번째 요소가 6번째로 밀려남
        numberList.add(4,123);
        value = numberList.get(4);
        System.out.println("5번째 요소의 값: " + value);

        // 전체 삭제
        numberList.clear();
        count = numberList.size();
        System.out.println("데이터 크기: " + count);
    }
}

// 실행결과
데이터 크기: 9
5번째 요소의 값: 50
데이터 크기: 8
5번째 요소의 값: 60
5번째 요소의 값: 123
데이터 크기: 0

List와 Beans를 활용한 데이터리스트 만들기

// Beans 생성

package study.java.model;

/** 주소록 데이터를 표현하기 위한 Java Beans */
public class People {

    private String name;
    private String phoneNo;


    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhoneNo() {
        return phoneNo;
    }
    public void setPhoneNo(String phoneNo) {
        this.phoneNo = phoneNo;
    }

    public People(String name, String phoneNo) {
        super();
        this.name = name;
        this.phoneNo = phoneNo;


    }
    @Override
    public String toString() {
        return "People [name=" + name + ", phoneNo=" + phoneNo + "]";
    }

}


// 데이터 리스트 만들기

import java.util.ArrayList;
import java.util.List;

import study.java.model.People;

public class Main03 {
    public static void main(String[] args) {
        /** List를 사용하는 가장 일반적인 방법은,
         *   사용자 정의 클래스에 대한 객체를 포함 하도록
         *   지정하는 것이다. */

        // 객체를 담기 위한 ArrayList
        List<People> plist = new ArrayList<People>();

        // 10명의 데이터를 임의로 추가함
        for (int i=0; i<10; i++) {
            People p = new People("회원" + i , "010-1234-567" + i);
            plist.add(p);
        }

        // 출력하기
        for (int i=0; i<plist.size(); i++) {
            // List에 저장된 데이터 하나 꺼내면,
            // People 클래스 형의 객체다.
            People item = plist.get(i);
            System.out.println(item.toString());
        }
    }
}

// 실행결과

People [name=회원0, phoneNo=010-1234-5670]
People [name=회원1, phoneNo=010-1234-5671]
People [name=회원2, phoneNo=010-1234-5672]
People [name=회원3, phoneNo=010-1234-5673]
People [name=회원4, phoneNo=010-1234-5674]
People [name=회원5, phoneNo=010-1234-5675]
People [name=회원6, phoneNo=010-1234-5676]
People [name=회원7, phoneNo=010-1234-5677]
People [name=회원8, phoneNo=010-1234-5678]
People [name=회원9, phoneNo=010-1234-5679]

'JAVA' 카테고리의 다른 글

JAVA(MySQL연동, JDBC)  (0) 2020.06.23
JAVA(fileIO, JSONObject)  (0) 2020.06.16
JAVA (Static, 익명클래스)  (0) 2020.06.11
JAVA(추상화, 인터페이스)  (0) 2020.06.10
JAVA(객체형변환, 객체배열)  (0) 2020.06.10

댓글