[디버깅 과목평가 대비] JAVA WORKSHOP 7 (COLLECTION & EXCEPTION) (자바 예외 종류와 예외발생, 처리 방법 내용정리)
Book.java
quantity 변수가 추가된 것 이외에는 특별히 어려운 점은 없었다.
package workshop.java07;
public class Book {
String isbn;
String title;
String author;
String publisher;
int price;
String desc;
int quantity;
public Book() {
super();
}
public Book(String isbn, String title, String author, String publisher, int price, String desc, int quantity) {
super();
this.isbn = isbn;
this.title = title;
this.author = author;
this.publisher = publisher;
this.price = price;
this.desc = desc;
this.quantity = quantity;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
@Override
public String toString() {
return isbn + " | " + title + " | " + author + " | " + publisher + " | " + price + " | " + desc + " | " + quantity;
}
}
Magazine.java
앞선 워크숍과 같았다.
다른 점이라면 생성자의 super()에 quantity를 추가해 주었다.
package workshop.java07;
public class Magazine extends Book {
private int year;
private int month;
public Magazine(String isbn, String title, String author, String publisher, int price, String desc, int quantity, int year, int month) {
super(isbn, title, author, publisher, price, desc, quantity);
this.year = year;
this.month = month;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
@Override
public String toString() {
return super.toString() + "|" + year + "|" + month;
}
}
IBookManager.java
명세서에서 요구된 대로 sell 과 buy 메소드를 추가해 주었다.
package workshop.java07;
public interface IBookManager {
public void add(Book book);
public void remove(String isbn);
public Book[] getList();
public Book searchByIsbn(String isbn);
public Book[] searchByTitle(String title);
public Magazine[] getMagazines();
public Book[] getBooks();
public int getTotalPrice();
public double getPriceAvg();
public void sell(String isbn, int quantity) throws ISBNNotFoundException, QuantityException;
public void buy(String isbn, int quantity) throws ISBNNotFoundException;
}
BookManagerImpl.java
도서리스트의 자료구조를 배열에서 ArrayList로 바꿨을 때 더 유용하고 편리한 부분이 많았다.
add나 remove로 리스트 요소를 추가하거나 삭제할 수 있다는 점이 그 중 하나였다.
또한 배열과 다르게 객체에 직접적으로 접근하는 방법을 사용해도 문제되는 점이 크게 없어서 foreach 문을 편하게 사용할 수 있었다.
그리고 리턴타입이 Book[] 객체배열과 같은 메소드의 경우에 ArrayList를 사용하기 전에는 배열의 크기를 알지 못하기 때문에 for문을 두번 사용해서 한번은 객체의 크기를 저장하는 cnt 변수를 사용하고, 다른 한번은 cnt변수만큼 임시 배열을 선언해서 그곳에 차곡차곡 담았는데, ArrayList를 사용하고 나서는 크기를 마음대로 조절할 수 있어서 반복문을 한번만 사용해도 되는 장점이 있었다.
그리고 ArrayList에서 인덱스 접근을 어떻게 해야하지? 라고 생각했는데, .get()이라는 메소드를 사용해서 인덱스에 접근이 가능했다. 인덱스 접근 후 객체가 가지고 있는 메소드도 모두 사용할 수 있었다.
마지막으로 메소드의 리턴타입을 맞춰주기 위해서 ArrayList를 Array로 바꿔주는 작업을 하는 부분이 기억에 남았다. 나는 ArrayList의 size() 만큼 for문을 돌려서 임시배열에 차근차근 넣는 방식을 사용하려고 했는데, 솔루션을 참고해본 결과, 어레이리스트.toArray(배열) 처럼 toArray()라는 유용한 함수를 사용한다는 것을 알게 되었다.
예외처리는 아래쪽에서 정리하겠다.
package workshop.java07;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class BookManagerImpl implements IBookManager {
/*private BookManagerImpl() {}
private static BookManagerImpl instance = new BookManagerImpl();
public static BookManagerImpl getInstance() {
return instance;
}*/
private BookManagerImpl() {}
private static IBookManager instance = new BookManagerImpl();
public static IBookManager getInstance() {
return instance;
}
List<Book> books = new ArrayList<Book>();
@Override
public void add(Book book) {
books.add(book);
}
@Override
public void remove(String isbn) {
for (int i = 0; i < books.size(); i++) {
if (books.get(i).getIsbn().equals(isbn)) { // get(i)
books.remove(i);
}
}
}
@Override
public Book[] getList() {
Book[] result = new Book[books.size()];
return books.toArray(result); // ArrayList.toArray(Array);
/*
int idx = 0;
for (Book book : books) {
temp[idx] = book;
idx++;
}
return temp;*/
}
@Override
public Book searchByIsbn(String isbn) {
for (Book book : books) {
if (book.getIsbn().equals(isbn)) {
return book;
}
}
/*for (int i = 0; i < books.size(); i++) {
if (books.get(i).getIsbn().equals(isbn)) {
return books.get(i);
}
}*/
return null;
}
@Override
public Book[] searchByTitle(String title) {
List<Book> temp = new ArrayList<Book>();
for (Book book : temp) {
if (book.getTitle().contains(title)) {
temp.add(book);
}
}
Book[] result = new Book[temp.size()];
return temp.toArray(result);
}
@Override
public Magazine[] getMagazines() {
List<Book> temp = new ArrayList<Book>();
for (Book book : books) {
if (book instanceof Magazine) {
temp.add(book);
}
}
Magazine[] result = new Magazine[temp.size()];
return temp.toArray(result);
}
@Override
public Book[] getBooks() {
List<Book> temp = new ArrayList<>();
for (Book book : books) {
if (!(book instanceof Magazine)) {
temp.add(book);
}
}
Book[] result = new Book[temp.size()];
return temp.toArray(result);
}
@Override
public int getTotalPrice() {
int total = 0;
for (Book book : books) {
total = total + book.getPrice();
}
return total;
}
@Override
public double getPriceAvg() {
return getTotalPrice()/books.size();
}
@Override
public void sell(String isbn, int quantity) throws ISBNNotFoundException, QuantityException {
/*for (Book book : books) {
if (book.getIsbn().equals(isbn)) {
int stock = book.getQuantity() - quantity;
}
}*/
Book book = searchByIsbn(isbn);
if (book == null) throw new ISBNNotFoundException(isbn);
int stock = book.getQuantity() - quantity;
if(stock < 0) throw new QuantityException();
book.setQuantity(stock);
}
@Override
public void buy(String isbn, int quantity) throws ISBNNotFoundException {
/*for (Book book : books) {
if (book.getIsbn().equals(isbn)) {
int stock = book.getQuantity() + quantity;
}
}*/
Book book = searchByIsbn(isbn);
if(book == null) throw new ISBNNotFoundException(isbn);
int stock = book.getQuantity() + quantity;
book.setQuantity(stock);
}
}
isbn을 찾는 부분은 searchByIsbn() 메소드를 사용해서 중복을 없앤 게 인상적이었다.
그런데! 사용자정의 예외처리는 거의 솔루션을 보고 따라쳤다고 해도 과언이 아닐 것 같다. 내가 작성한 부분은 주석처리된 부분 뿐이였기 때문이다.. ㅎㅎ
예외처리는 우선 if문으로 조건을 검사해서 throw new 키워드를 사용해서 예외를 던지는 부분과 메소드 선언부 옆에 throws 키워드로 던지는 예외들을 써주는 부분으로 나눌 수 있는 것 같다.
메소드 안에서 예외처리를 할 때 try~catch 를 쓰는.. 무식한(?) 오류를 범하면 안될 것 같다!
메소드에서 사용자정의 예외처리를 해줄 때에는 if문으로 조건비교를 한 후 예외를 던지면 된다!
1) 메소드 구현부 옆에 throws 예외1, 예외2 {
2) 메소드 안에 if() throw new 예외();
try~catch문은 메소드를 호출하는 main함수에서 해주는 거다!
ISBNNotFoundException.java
이 부분은 isbn을 생성자에서 받아서 isbn 변수를 선언도 해야되고 isbn이 private라 getter도 만들어야되는..
그런 사용자정의 예외처리 클래스였다.
package workshop.java07;
public class ISBNNotFoundException extends Exception {
private String isbn;
public ISBNNotFoundException(String isbn) {
super("고유번호는 존재하지 않습니다.");
this.isbn = isbn;
}
public String getIsbn() {
return isbn;
}
}
QuantityException.java
아무튼 사용자정의 예외처리를 해 줄 때에는
1) Exception 상속
2) 생성자 안에서 super(하고싶은말);
package workshop.java07;
public class QuantityException extends Exception {
public QuantityException() {
super("수량이 부족합니다.");
}
}
BookTest.java
예외처리를 해주는 메소드를 호출 할 때에는 무조건 try~catch로 감싸줘야 한다.
try{
호출할함수();
}
catch (예외1 e){
syso(e.getMessage());
}
catch (예외2 e){
syso(e.getMessage());
}
package workshop.java07;
public class BookTest {
public static void main(String[] args) {
/*BookManagerImpl bm = BookManagerImpl.getInstance();*/
IBookManager bm = BookManagerImpl.getInstance();
bm.add(new Book("21424", "Java Pro", "김하나", "jaen.kr", 15000, "Java 기본 문법", 10));
bm.add(new Book("21425", "Java Pro2", "김하나", "jaen.kr", 25000, "Java 응용", 20));
bm.add(new Book("35355", "분석설계","소나무","jaen.kr",30000,"SW 모델링", 30));
bm.add(new Magazine("45678", "월간 알고리즘", "홍길동", "jaen.kr", 10000, "1월 알고리즘", 40, 2021, 1));
System.out.println("\n1. 도서 전체 목록");
for (Book book : bm.getList()) {
System.out.println(book);
}
System.out.println("\n2. 일반 도서 목록");
for (Book book : bm.getBooks()) {
System.out.println(book);
}
System.out.println("\n3. 잡지 목록");
for (Book book : bm.getMagazines()) {
System.out.println(book);
}
System.out.println("\n4. 도서 제목 포함검색 : Java");
for (Book book : bm.searchByTitle("Java")) {
System.out.println(book);
}
System.out.println("\n5. 도서 가격 총합 : " + bm.getTotalPrice());
System.out.println("\n6. 도서 가격 평균 : " + bm.getPriceAvg());
System.out.println("\n도서판매 : 21424, 11개");
try {
bm.sell("21424", 11);
}catch (ISBNNotFoundException e) {
System.out.println(e.getMessage());
}catch (QuantityException e) {
System.out.println(e.getMessage());
}
for (Book book : bm.getList()) {
System.out.println(book);
}
System.out.println("\n도서구매 : 21424, 10개");
try {
bm.buy("21424", 10);
} catch (ISBNNotFoundException e) {
System.out.println(e.getMessage());
}
for (Book book : bm.getList()) {
System.out.println(book);
}
System.out.println("\n도서판매 : 21424, 11개");
try {
bm.sell("21424", 11);
}
catch (ISBNNotFoundException e) {
System.out.println(e.getMessage());
}
catch (QuantityException e) {
System.out.println(e.getMessage());
}
for (Book book : bm.getList()) {
System.out.println(book);
}
}
}