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 메소드

가져오기, 저장, 저장(property), 저장(xml), 읽어오기, 읽어오기, 읽어오기(xml)

 

 

 

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으로 나뉜다.

 

IOException은 반드시 체크해야하는 예외처리의 종류이다. 즉, Checked 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

+ Recent posts