Map
Map인스턴스란?
- 키(key/구분값)와 값(value)으로 구성되어 있으며, 키와 값은 모두 인스턴스이다.
- 키는 중복 저장을 허용하지 않고(Set방식), 값은 중복 저장 가능(List방식)
- 키가 중복되는 경우, 기존에 있는 키에 해당하는 값을 덮어 씀
- 키와 값을 합친 덩어리를 Entry라 부른다.
- 구현 클래스 : HashMap, HashTable(HashMap의 이전버전), LinkedHashMap, Properties, TreeMap
Map 계열 주요 메소드
Application1
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Application1 {
public static void main(String[] args) {
/* Map 인터페이스의 특징 */
/* Collection 인터페이스와는 다른 저장 방식을 가진다.
* 키(key)와 값(value)을 하나의 쌍으로 저장하는 방식을 사용한다.
*
* 키(key)란?
* 값(value)을 찾기 위한 이름 역할을 하는 객체를 의미한다.
*
* 1. 요소의 저장 순서를 유지하지 않는다.
* 2. 키는 중복을 허용하지 않지만, 키가 다르면 중복 되는 값은 저장 가능하다.
*
*
* HashMap, HashTable, TreeMap 등의 대표적인 클래스가 있다.
* HashMap이 가장 많이 사용 되며 HashTable은 jdk 1.0부터 제공되며
* HashMap과 동일하게 동작 된다. 하위 호환을 위해 남겨놓았기 때문에
* 가급적이면 HashMap을 사용하는 것이 좋다.
*
* */
/* HashMap 인스턴스 생성 */
HashMap hmap = new HashMap();
// Map hmap2 = new HashMap();;
/* 키와 값 쌍으로 저장한다.
* 키와 값 둘다 반드시 객체여야 한다.
* */
hmap.put("one", new Date());
hmap.put(12, "red apple");
hmap.put(33, 123);
/* 기본자료형은 오토박싱 처리된다. : int => Integer */
/* 저장 순서 유지하지 않음 */
System.out.println("hmap : " + hmap);
// hmap : {33=123, one=Tue Jan 11 09:25:59 KST 2022, 12=red apple}
/* 키는 중복 저장 되지 않음 (set방식) : 최근 값으로 덮어쓰기 */
hmap.put(12, "yellow banana");
System.out.println("hmap : " + hmap);
// hmap : {33=123, one=Tue Jan 11 09:25:59 KST 2022, 12=yellow banana}
/* 키가 다르면 값 객체 저장은 중복으로 가능함 */
hmap.put(11, "yellow banana");
System.out.println("hmap : " + hmap);
// hmap : {33=123, one=Tue Jan 11 09:26:24 KST 2022, 11=yellow banana, 12=yellow banana}
/* 값 객체의 내용을 가져올 때 */
System.out.println("키 11에 대한 객체 : " + hmap.get(11));
// 키값을 전달시 value값을 리턴한다.
// 키 11에 대한 객체 : yellow banana
/* 키 값을 가지고 삭제를 처리할 때 */
hmap.remove(11);
System.out.println("hmap : " + hmap);
// hmap : {33=123, one=Tue Jan 11 09:28:43 KST 2022, 12=yellow banana}
/* 저장 된 객체 수를 확인할 때 */
System.out.println("hmap에 저장된 객체 수 : " + hmap.size());
// hmap에 저장된 객체 수 : 3
/* 노란줄이 생기는 이유? 제네릭을 사용하지 않았기 때문 */
/* 제네릭 설정한 HashMap 인스턴스 생성 */
HashMap<String, String> hmap2 = new HashMap<>();
hmap2.put("one", "java");
hmap2.put("two", "oracle");
hmap2.put("three", "jdbc");
hmap2.put("four", "html");
hmap2.put("five", "css");
/* 방법 1. ketset()을 이용해서 키만 따로 set 으로 만들고,
* iterator()로 키에 대한 목록을 만든다.
* */
// Set<String> keys = hmap2.keySet();
// Iterator<String> keyIter = key.iterator();
// ㄴ 한줄로 만들기
Iterator<String> keyIter = hmap2.keySet().iterator();
while(keyIter.hasNext()) {
String key = keyIter.next();
String value = hmap2.get(key);
System.out.println(key + " = " + value);
// four = html
// one = java
// two = oracle
// three = jdbc
// five = css
}
/* 방법2. 저장 된 value 객체들만 values()로 Collection으로 만든다. */
Collection<String> values = hmap2.values();
/* 2-1. iterator()로 목록 만들어서 처리 */
Iterator<String> valueIter = values.iterator();
while(valueIter.hasNext()) {
System.out.println(valueIter.next());
}
/* 2.2 배열로 만들어서 처리 */
Object[] valueArr = values.toArray();
for (int i = 0; i < valueArr.length; i++) {
System.out.println(i + " : " + valueArr[i]);
// 0 : html
// 1 : java
// 2 : oracle
// 3 : jdbc
// 4 : css
}
/* 방법3. Map의 내부 클래스인 EntrySet을 이용 : entrySet */
Set<Map.Entry<String, String>> set = hmap2.entrySet();
Iterator<Map.Entry<String, String>> entryIter = set.iterator();
while(entryIter.hasNext()) {
Map.Entry<String, String> entry = entryIter.next();
System.out.println(entry.getKey() + " : " + entry.getValue());
// four : html
// one : java
// two : oracle
// three : jdbc
// five : css
}
}
}
Properties
- 키와 값을 String 타입으로 제한한 Map 컬렉션 - 문자열로만 받음
- 주로 Properties는 프로퍼티(*.properties)파일을 읽어 들일 때 주로 사용
프로퍼티(*.properties)파일
- 옵션정보, 데이터베이스 연결정보, 국제화(다국어)정보를 기록하여 텍스트 파일로 활용
- 애플리케이션에서 주로 변경이 잦은 문자열을 저장하여 관리하기 때문에 유지보수를 편리하게 만들어 줌
- 키와 값이 ‘=‘기호로 연결되어 있는 텍스트 파일로 ISO 8859-1 문자셋으로 저장되고, 한글은 유니코드(Unicode)로 변환되어 저장
Properties 메소드
Application2
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class Application2 {
public static void main(String[] args) {
/* Properties */
/* 설정 파일의 값을 읽어서 어플리케이션에 적용할 때 사용한다. */
Properties prop = new Properties();
prop.setProperty("driver", "oracle.jdbc.driver.OracleDriver");
prop.setProperty("url", "jsbc:oracle:this:@127.0.0.1:1521:xe");
prop.setProperty("user", "student");
prop.setProperty("password", "student");
System.out.println(prop);
// {password=student, driver=oracle.jdbc.driver.OracleDriver, user=student, url=jsbc:oracle:this:@127.0.0.1:1521:xe}
/* prop -> 문서화 하겠다 */
try {
prop.store(new FileOutputStream("driver.dat"), "jdbc driver");
prop.store(new FileWriter("driver.txt"), "jdbc driver");
prop.storeToXML(new FileOutputStream("driver.xml"), "jdbc driver");
} catch (IOException e) {
e.printStackTrace();
}
/* 파일로부터 읽어와서 Properties에 기록한다. */
Properties prop2 = new Properties();
// prop2.load(new FileInputStream("driver.dat"));
try {
// prop2.load(new FileInputStream("driver.dat"));
// prop2.load(new FileReader("driver.txt"));
prop2.loadFromXML(new FileInputStream("driver.xml"));
/* Properties의 모든 키 값 목록을 대상 스트림에 내보내기 한다. */
prop2.list(System.out);
System.out.println(prop2.getProperty("driver"));
System.out.println(prop2.getProperty("url"));
System.out.println(prop2.getProperty("user"));
System.out.println(prop2.getProperty("password"));
// oracle.jdbc.driver.OracleDriver
// jsbc:oracle:this:@127.0.0.1:1521:xe
// student
// student
} catch (IOException e) {
e.printStackTrace();
}
}
}
예외처리
오류와 에러
시스템 상에서 프로그램에 심각한 문제가 발행해서 실행중인 프로그램이 영향을 받는 것은 오류와 예외로
구분할 수 있음
오류(Error)
- 시스템 상에서(물리적) 프로그램에 심각한 문제를 발생하여 실행중인 프로그램이 종료되는 것
예외(Exception)
- 오류와 마찬가지로 비정상적으로 종료시키지만 미리 예측하고 처리할 수 있는 미약한 오류
- 소프트웨어 개발자로서의 관심영역은 예외쪽에 있다.
예외 클래스 계층 구조
- Exception과 Error 클래스 모두 Throwable클래스의 자손이다.
- 예외 클래스들의 최상위 클래스는 Exception 클래스이다.
- 예외처리를 해야하는 Checked Exception과 해주지 않아도 되는 Unchecked Exception으로 나뉜다.
예외처리
예외는 예외처리를 통해 코드의 흐름을 컨트롤 가능
예외 처리 방법
- 1. thorws로 위임 (Exception 처리를 호출한 메소드에게 위임)
메소드 선언 시 throws ExceptionName문을 추가하여 호출한 상위 메소드에게 처리를 위임
- 2. try-catch로 처리 (Exception이 발생한 곳에서 직접 처리)
- try : exception 발생할 가능성이 있는 코드를 안에 기술
- catch : try 구문에서 exception 발생 시 해당하는 exceptio에 대한 처리 기술
여러 개의 exception처리가 가능하나 exception간의 상속 관계 고려
- finally : exception 발생 여부와 관계없이 꼭 처리해야 하는 로직 기술
중간에 return문을 만나도 finally구문은 실행되지만
System.exit();를 만나면 무조건 프로그램 종료
주로 java.io나 java.sql 패키지의 메소드 처리 시 이용
Throws로 예외 던지기
try~cathch로 예외 처리
Application1
public class Application1 {
public static void main(String[] args) throws Exception {
/* 예외처리
*
* 오류(Error)
* 시스템 상에서 프로그램에 심각한 문제를 발생하여 실행중인 프로그램이
* 종료되는 것을 말한다.
* 이러한 오류는 개발자가 미리 예측하여 처리하는 것이 불가능하며,
* 오류에 대한 처리는 할 수 없다.
*
* 예외(Exceptrion)
* 오류와 마찬가지로 실행 중인 프로그램을 비정상적으로 종료시키지만
* 발생할 수 있는 상황을 미리 예측하고 처리할 수 있는 미약한 오류를 말한다.
* 개발자는 이러한 예외에 대해 예외 처리를 통해 예외상황을 적절히 처리하여
* 코드의 흐름을 컨트롤 할 수 있다.
*
*
* */
/* 예외처리 방법
*
* 1. throws로 위임 : 나를 호출한 상위클래스로 던짐
* 2. try-catch로 처리 : 그자리에서 바로 처리
* */
/* 1. throws로 위임 */
ExceptionTest et = new ExceptionTest();
// et.checkEnoughMoney(10000, 50000);
// 빨간줄의 원인? : 호출시 반드시 예외처리 해주어야 하기 때문
// 1. throw, 2. try-catch
/* 상품가격 10000원, 가진돈 50000원 -> 정상수행 */
et.checkEnoughMoney(10000, 50000);
// throws 선택시 메소드 위로 오류가 위임된다, 동시에 정상동작확인
// 가지고 계신 돈은 50000원 입니다.
// 상품을 구입하기 위한 금액이 충분합니다.
// 즐거운 쇼핑 하세요~
/* 상품가격 50000원, 가진돈 10000원 -> 정상수행 */
et.checkEnoughMoney(50000, 10000);
/* 에러 발생 구문 이하 구문은 동작하지 않고 되돌아온다.
* 메인 메소드 또한 예외를 처리하지 않고 위임했다.
* 따라서 프로그램은 비정상적으로 종료되고 아래 구문은 출력되지않음 */
System.out.println("프로그램을 종료합니다.");
/* 예외 발생시 두번째 구문은 발동되지않음, 게다가 위임한 코드조차
* 예외에 대처하고 있지않으므로 에러 구문을 출력시킨다. */
}
}
Application2
public class Application2 {
public static void main(String[] args) {
/* 2. try-catch 를 이용한 방법 (예외 발생하지 않음) */
ExceptionTest et = new ExceptionTest();
/* 상품 가격 10000원, 가진 돈 50000원 */
// et.checkEnoughMoney(10000, 50000);
// 호출시 무조건 핸들링하라고 하는 오류가 발생한다.
try {
/* 예외 발생 가능성이있는 메소드는 try블럭안에서 호출한다. */
/* 상품 가격 10000원, 가진 돈 50000원 */
//et.checkEnoughMoney(10000, 50000);
/* 상품 가격 50000원, 가진 돈 10000원 */
et.checkEnoughMoney(50000, 10000);
System.out.println("=======상품 구입 가능=======");
} catch (Exception e) {
/* Exception이 발생했을경우 catch 블럭쪽 코드가 실행된다.
* 예외발생없이 정상출력될 경우 catch 블럭쪽 코드는 실행되지않는다.
* 즉 위의 메소드 호출시 예외가 발생한 경우 catch블럭코드를 실행한다.
* 이때 예외 발생한 위치의 하단 코드는 동작하지않는다. */
System.out.println("=======상품 구입 불가=======");
}
/* 프로그램 종료 확인 */
System.out.println("프로그램을 종료합니다.");
/* 예외 발생하지않을시 콘솔출력 - try */
// 가지고 계신 돈은 50000원 입니다.
// 상품을 구입하기 위한 금액이 충분합니다.
// 즐거운 쇼핑 하세요~
// =======상품 구입 가능=======
// 프로그램을 종료합니다.
/* 예외 발생시 콘솔출력 - catch */
// 가지고 계신 돈은 10000원 입니다.
// =======상품 구입 불가=======
// 프로그램을 종료합니다.
}
}
ExceptionTest
public class ExceptionTest {
/* 예외를 발생시키는 메소드를 하나 작성한다. */
public void checkEnoughMoney(int price, int money) throws Exception {
System.out.println("가지고 계신 돈은 " + money + "원 입니다.");
if (money >= price) {
System.out.println("상품을 구입하기 위한 금액이 충분합니다.");
} else {
/* 강제로 예외 발생
* 예외가 발생한다는것 = 어딘가에 해당 객체가 생성된다는 것
* 예외를 발생시킨 뒤 헤드에 throws 구문을 추가한다.
* 예외를 발생시킨 쪽에서는 throws로 예외에 대한 책임을
* 위임해서 해당 예외에 대한 처리를 강제화 시킨다.
* */
throw new Exception(); // throw = 발생한다로 해석
// Unhandled exception type Exception
// add throws Exception 클릭시 상위메소드에 처리를 넘김
}
/* 예외가 발생하지 않는 경우에만 실행한다. */
System.out.println("즐거운 쇼핑 하세요~");
}
}
사용자 정의 예외
- Exception 클래스를 상속받아 예외 클래스를 작성하는 것
RuntimeException 후손 클래스
예외처리가 강제화 되어있지않다.
후손 클래스 | 설명 |
ArithmeticException | 0으로 나누는 경우 발생 if문으로 나누는 수가 0인지 검사 |
NullPointerException | Null인 참조 변수로 객체 멤버 시도 시 발생 객체 사용 전에 참조 변수가 null인지 확인 |
NegativeArraySizeException | 배열 크기를 음수로 지정한 경우 발생 배열 크기를 0보다 크게 지정 |
ArrayIndexOutOfBoundsException | 배열의 index범위를 넘어서 참조하는 경우 배열명.length를 사용하여 배열의 범위 확인 |
Class CastException | Cast연산자 사용 시 타입 오류 instanceof연산자로 객체 타입 확인 후 cast연산 |
예외처리 방법
finally로 예외 처리
- 예외 처리 구문과 상관 없이 반드시 수행해야 하는 경우 작성 (보통 사용한 자원을 반납할 목적)
NegativeException extends Exception
public class NegativeException extends Exception {
/* 사용자 정의 예외를 만드려면 Exception을 상속받아야 함 */
/* 기본 생성자 */
public NegativeException() {}
/* 매개변수 생성자 */
public NegativeException(String message) {
super(message);
}
}
NotEnoughMoneyException extends Exception
public class NotEnoughMoneyException extends Exception {
/* 사용자 정의 예외 클래스를 만들기 위해서는 Exception 클래스를
* 상속 받으면 된다. Exception 클래스는 Throwable 클래스를 상속받아
* 구현되어 있다.
*
* Throwable은 Error 와 Exception 두 가지를 추상화 해서 만들었다.
* 예외처리는 Exception을 가장 최상휘 클래스로 여긴다.
* */
/* 기본생성자 */
public NotEnoughMoneyException () {}
/* 문자열을 부모 생성자 쪽으로 전달하며 초기화 하는 생성자 */
public NotEnoughMoneyException (String message) {
/* 예외 인스턴스 생성 시점에 예외 메세지를 부모 생성자 쪽으로
* 전잘해서 인스턴스를 생성한다. */
super(message);
}
/* money와 price가 각각 음수로 입력되는 경우 일반적인 상식에서 벗어나는
* 프로그램이 된다. 만약 각각 음수로 입력 되는 경우 발생시킬 예외를
* NegativeException 으로 정의한다.
*
* 그리고 이를 상속받는 PriceNegativeException과
* MoneyNegativeException을 정의한다.
* */
}
MoneyNegativeException extends NegativeException
public class MoneyNegativeException extends NegativeException{
/* 앞서 정의한 사용자 정의 예외처리 클래스를 상속받게 한다.
* Throwable - Exception - NegativeException - MoneyNegativeException
* 의 상속관계가 된다. */
/* 기본 생성자 */
public MoneyNegativeException () {}
/* 매개변수 생성자 */
public MoneyNegativeException (String message) {
super(message);
}
}
PriceNegativeException extends NegativeException
public class PriceNegativeException extends NegativeException {
/* 앞서 정의한 사용자 정의 예외처리 클래스를 상속받게 한다.
* Throwable - Exception - NegativeException
* - MoneyNegativeException & PriceNegativeException
* 의 상속관계가 된다. */
/* 기본 생성자 */
public PriceNegativeException () {}
/* 매개변수 생성자 */
public PriceNegativeException (String message) {
super(message);
}
}
Application1
import com.greedy.section02.userexception.exception.MoneyNegativeException;
import com.greedy.section02.userexception.exception.NotEnoughMoneyException;
import com.greedy.section02.userexception.exception.PriceNegativeException;
public class Application1 {
public static void main(String[] args) /*throws PriceNegativeException, MoneyNegativeException, NotEnoughMoneyException*/ {
/* 사전에 정의 되어 있는 Exception의 종류는 굉장히 많이 있다.
* 하지만 RuntimeException의 후손 대부분은 예외처리를 강제화 하지 않는다.
* 간단한 조건문 등으로 처리가 가능하기 때문에 따로 강제화 하지않는다. */
/* 사전에 정의 된 예외 클래스 외에 개발자가 우너하는 명칭의
* 예외 클래스를 작성하는 것이 가능하다.
* extends Exception 으로 예외처리 클래스를 상속받아 더 구체적인
* 예외 이름을 정의하는 것이다.
*
* */
ExceptionTest et = new ExceptionTest();
/* 상품가격보다 가진 돈이 적은 경우 */
//et.checkEnoughMoney(50000, 30000);
/* 실행시 오류가 발생한다. 실행한 오류의 내용은 다음과 같다.
* 직접 설정한 오류가 출력됨을 확인할 수 있다.
*
* com.greedy.section02.userexception.
* exception.NotEnoughMoneyException:
* 가진 돈 보다 상품 가격이 더 비쌉니다.*/
/* try-catch 블럭으로 확인하기 */
/* 정상적인 프로그램의 흐름을 만들기 위해서는 try-catch 블럭을 작성하는게 좋다. */
try {
/* 상품 가격보다 가진 돈이 적을 경우 (에러가 발생할 가능성있는 메소드를 넣는다.)*/
/* 실행해보면 예외 종류와 에러 메세지가 출력된다. */
// et.checkEnoughMoney(50000, 30000);
// 출력 : NotEnoughMoneyException: 가진 돈 보다 상품 가격이 더 비쌉니다.
/* 상품가격을 음수로 입력한 경우 */
// et.checkEnoughMoney(-50000, 50000);
// 출력 : PriceNegativeException: 상품가격은 음수일 수 없습니다.
/* 가진 돈을 음수로 입력한 경우 */
// et.checkEnoughMoney(50000, -50000);
// 출력 : MoneyNegativeException: 가지고 있는 돈은 음수일 수 없습니다.
/* 정상적으로 구매가 가능한 돈을 가진 경우 */
/* 위의 코드들을 주석하지 않으면 이 코드는 동작하지 않는다.
* catch 블록으로 가는 것이다. */
et.checkEnoughMoney(30000, 50000);
// 출력 : 가진 돈이 충분합니다. 즐거운 쇼핑하세요~
} catch (Exception e) { // 다형성을 이용해 상위개념 Exception으로 받음
e.printStackTrace();
}
/* exception이 발생한 경우 catch 블록에 잡히기 때문에 if문 하위의 출력문은 출력되지 않는다. */
}
}
ExceptionTest
import com.greedy.section02.userexception.exception.MoneyNegativeException;
import com.greedy.section02.userexception.exception.NotEnoughMoneyException;
import com.greedy.section02.userexception.exception.PriceNegativeException;
public class ExceptionTest {
public void checkEnoughMoney(int price, int money)
throws PriceNegativeException, MoneyNegativeException, NotEnoughMoneyException{
// throws Exception {
/* 3개의 예외 클래스는 모두 Exception 클래스의 후손이다.
* (throws의 공통된 조상은 Exception이다.)
* 그러므로 Exception만으로도 처리할 수 있다. */
/* 아까는 Exception으로 예외를 발생시켰지만, 그건 그냥 '예외'
* 라는 의미이다. 예외 클래스의 이름만으로 어떠한 예외가 발생했는지
* 알 수 있도록 하기 위해서는 명명이 중요하다.
* 사용자 정의 예외 클래스를 추가할 것이다.
* */
/* 먼저 상품 가격이 음수인지 확인하고, 음수인 경우 예외를 발생시킨다. */
if (price < 0) {
throw new PriceNegativeException("상품가격은 음수일 수 없습니다.");
}
/* 가진 돈도 음수인지 확인하고, 음수인 경우 예외를 발생시킨다. */
if(money < 0) {
throw new MoneyNegativeException("가지고 있는 돈은 음수일 수 없습니다.");
/* PriceNegativeException, MoneyNegativeException
* 둘 중 하나를 발생시킬 수 있는 메소드가 됨 */
}
/* 위의 두 값이 정상 입력 되었더라도 상품 가격이 가진 돈보다 큰 경우 예외 발생 */
if (money < price) {
throw new NotEnoughMoneyException ("가진 돈 보다 상품 가격이 더 비쌉니다.");
}
/* 모든 조건을 만족하는 경우 정상적으로 물건 구입 가능 */
System.out.println("가진 돈이 충분합니다. 즐거운 쇼핑하세요~");
}
}
Application2
import com.greedy.section02.userexception.exception.MoneyNegativeException;
import com.greedy.section02.userexception.exception.NotEnoughMoneyException;
import com.greedy.section02.userexception.exception.PriceNegativeException;
public class Application2 {
public static void main(String[] args) {
ExceptionTest et = new ExceptionTest();
/* 이 메소드를 입력시 컴파일 에러가 뜨고 해결책을 누르면 아래와같이 뜬다. */
// et.checkEnoughMoney(20000, 30000);
try {
/* 예외 발생 가능성이있는 메소드 호출 */
et.checkEnoughMoney(30000, 50000);
/* 예외 발생별로 catch 블럭을 따로 작성해서 처리할 수 있다. */
} catch (PriceNegativeException e) {
/* 예외 인스턴스 생성 시 전달한 메세지를 getMessage()로 가져올 수 있다. */
System.out.println("PriceNegativeException 발생!");
System.out.println(e.getMessage());
} catch (MoneyNegativeException e) {
System.out.println("MoneyNegativeException 발생!");
System.out.println(e.getMessage());
} catch (NotEnoughMoneyException e) {
System.out.println("NotEnoughMoneyException 발생!");
System.out.println(e.getMessage());
} finally {
/* 예외 발생 여부와 상관없이 실행할 내용 */
/* finally 블록은 무조건 동작한다. */
System.out.println("finally 블럭의 내용이 동작함");
}
/* 프로그램을 종료하는지 확인 */
System.out.println("프로그램을 종료합니다.");
/* 다음과 같이 예외사항이 처리됨을 확인할 수 있다. */
// et.checkEnoughMoney(-20000, 30000); 인 경우
// PriceNegativeException 발생!
// 상품가격은 음수일 수 없습니다.
// et.checkEnoughMoney(20000, -30000);
// MoneyNegativeException 발생!
// 가지고 있는 돈은 음수일 수 없습니다.
// et.checkEnoughMoney(50000, 30000);
// NotEnoughMoneyException 발생!
// 가진 돈 보다 상품 가격이 더 비쌉니다.
// et.checkEnoughMoney(30000, 50000);
// 가진 돈이 충분합니다. 즐거운 쇼핑하세요~
/* finally 블럭 삽입시 다음과 같이 실행된다. */
// et.checkEnoughMoney(-30000, 50000);
// PriceNegativeException 발생!
// 상품가격은 음수일 수 없습니다.
// finally 블럭의 내용이 동작함
// 프로그램을 종료합니다.
// et.checkEnoughMoney(30000, 50000);
// 가진 돈이 충분합니다. 즐거운 쇼핑하세요~
// finally 블럭의 내용이 동작함
// 프로그램을 종료합니다.
}
}
Application3
import com.greedy.section02.userexception.exception.MoneyNegativeException;
import com.greedy.section02.userexception.exception.NotEnoughMoneyException;
import com.greedy.section02.userexception.exception.PriceNegativeException;
public class Application3 {
public static void main(String[] args) {
/* multi-catch */
/* jdk 1.7에서 추가된 구문으로
* 동일한 레벨의 다른 타입의 예외를 하나의 catch 블럭으로 다룰 수 있다.
* */
ExceptionTest et = new ExceptionTest();
/* 예외 발생 가능성이 있는 메소드 호출 */
/* et.checkEnoughMoney(20000, 10000); 입력 후 multi-catch 클릭 */
try {
et.checkEnoughMoney(20000, 10000);
}
/* catch 블럭을 나열하는 경우 각 Exception의 상속관계를 고려해서 나열한다.
* Exception은 모든 타입의 Exception의 부모이기 때문에 먼저 동작하면 아래 catch 블록은
* 동작하지 않는다.
* */
catch (PriceNegativeException | MoneyNegativeException | NotEnoughMoneyException e) {
/* 예외 클래스명, 예외 발생 위치, 예외 메세지 등을
* stack 호출 역순으로 빨간색 글씨를 이용해서
* 로그 형태로 출력해주는 기능 */
e.printStackTrace();
System.out.println(e.getClass() + "발생!");
System.out.println(e.getMessage());
} catch(Exception e) { // 모든 타입의 Exception 의 부모
System.out.println("모든 종류의 Exception 발생!");
/*PriceNegativeException , MoneyNegativeException
* , NotEnoughMoneyException 외에서 발생한 예외를 처리하는 catch 블록이다.
* 이상태에서 문제가 없지만 만약 첫번째 catch 블럭 위로 올라가게 된다면
* 컴파일 에러가 발생한다.
*
* 순서가 바뀔경우 다형성에 의해서 첫번째 캐치구문만 검사하고
* 아래 블럭은 검사하지 않는다. -> 컴파일 에러
* 즉, catch 블럭은 여러개 나열될 수 있지만 가장 맨 위에 와야하는 것은
* 자식 catch 블럭이다.
*
* */
}
finally {
System.out.println("finally 블럭의 내용이 동작함");
}
System.out.println("프로그램을 종료합니다.");
/* 다음과같이 에러메세지가 콘솔창에 출력된다. */
// NotEnoughMoneyException: 가진 돈 보다 상품 가격이 더 비쌉니다.
// class com.greedy.section02.userexception.exception.NotEnoughMoneyException발생!
// 가진 돈 보다 상품 가격이 더 비쌉니다.
// finally 블럭의 내용이 동작함
// 프로그램을 종료합니다.
}
}
'Programming > JAVA' 카테고리의 다른 글
입출력 (I/O) 2 (0) | 2022.01.14 |
---|---|
입출력 (I/O) (0) | 2022.01.12 |
컬렉션 (0) | 2022.01.10 |
제네릭과 컬렉션 (0) | 2022.01.07 |
자바 API (0) | 2022.01.06 |