티스토리 뷰

1.    예외처리코드 ( 다중 catch )

-      예외별로 예외 처리 코드를 다르게 구현한다.

-      Ex. try { } catch ( ArratIndexOutOfBoundsException e ) { 예외처리 1 } catch ( NumberFormatException e ) { 예외처리 2 }

-      Catch의 순서는 예외 클래스에서 부모 타입을 아래로 자식 클래스를 위에 작성해야 한다.

-      Why? 왜냐하면 상위 클래스를 위에 작성하면 밑에 하위 클래스를 작성하지 않아도 예외를 위에서 다 잡아버리기에 특정 예외별로 다른 코드를 작성하려면 자식타입을 먼저 작성해야 한다.

 

2.    예외처리코드 ( 멀티 catch )

-      자바 7부터는 하나의 catch 블록 내에서 여러 개의 예외처리가 가능하다.

-      동일하게 예외처리를 하고 싶을 때에는 예외를 |로 연결하면 된다.

-      Ex. catch( ArratIndexOutOfBoundsException | NumberFormatException e ) { 예외처리

 

3.    제네릭 ( Generic )

-      제네릭 ( generic ) : 일반적인, 보편적인

-      (1) 제네릭은 기본타입을 대상으로 하지 않고, 참조타입을 대상으로 하는 타입이다.

-      제네릭 타입이란? :

-      컴파일 단계에서 잘못된 타입이 사용될 수 있는 문제를 제거할 수 있다.

-      타입을 파라미터(매개변수)로 가지는 클래스와 인터페이스

-      , 제네릭 타입은 매개변수로 참조타입을 준다.

-      이때 타입은 int가 아닌 integer와 같은 Wrapper type을 사용한다.

-      제네릭 타입은 선언 시 클래스 또는 인터페이스 이름 뒤에 < 매개변수의 이름 >를 붙인다.

-      이때 “ < > “ 사이에 들어가는 것을 타입 파라미터(매개변수)”라고 부른다.

-      타입 파라미터는 일반적으로 대문자 알파벳 1글자로 표현한다.

-      개발코드에서는 타입 파라미터 자리에 구체적인 타입을 지정해야 한다.

-      제네릭은 참조타입과 더불어 아래의 3군데에서 사용된다.

-      1. 클래스 - > 제네릭 타입의 클래스

-      2. 인터페이스 - > 제네릭 타입의 인터페이스

-      3. 메소드 - > 제네릭 타입의 메소드

-      타입을 파라미터(매개변수)로 가지는 클래스와 인터페이스


01. 다중 catch

 

package multi_catch;

 

public class CatchByExceptionKindExample {

      

       public static void main (String[] args) { // 다중 catch (****)

            

             try {

                   

                    // ArrayIndexOutOfBoundsException 예외가 발생가능한 코드 - 배열에 원소를 지정해 주지 않았다.

                    String data1 = args[0];

                    String data2 = args[1];

                   

//                  ============================================================

                   

                    // NumberFormatException 예외가 발생가능한 코드

                    int value1 = Integer.parseInt(data1);

                    int value2 = Integer.parseInt(data2);

                   

//                  ============================================================

                   

                    // 예외처리 코드는 메소드에 마우스를 올려놓으면 throws뒤에 어떤 예외 코드가 발생할지 적혀있기에 이를 참고하면 된다. (**)

                   

                    int result = value1 + value2;

                    System.out.println(data1 + "+" + data2 + "=" + result);

                   

             } catch ( ArrayIndexOutOfBoundsException e) {  // 예외처리 1

                   

                    System.out.println("실행매개값의 수가 부족합니다.");

                    System.out.println("[실행방법]");

                    System.out.println("java CatchByExceptionKindExample num1 num2");

                   

             } catch ( NumberFormatException e) { // 예외처리 2

                   

                    System.out.println("숫자로 변환할 수 없습니다.");

                   

             } finally { // ( optional ) 항상 실행할 코드 작성

                   

                           System.out.println("다시 실행하세요.");

                          

             } // try - catch - finally

       } // main

} // end class

 

02. 다중 catch - catch의 순서

 

package multi_catch;

 

public class CatchOrderExample {

      

public static void main (String[] args) { // 다중 catch - catch의 순서 (****)

            

             try {

                   

                    // ArrayIndexOutOfBoundsException 예외가 발생가능한 코드 - 배열에 원소를 지정해 주었다. [ 1, a2 ] // OK!

                    String data1 = args[0];

                    String data2 = args[1];

                   

//                  ============================================================

                   

                    // NumberFormatException 예외가 발생가능한 코드

                    int value1 = Integer.parseInt(data1);

                    int value2 = Integer.parseInt(data2);

                   

//                  ============================================================

                   

                    // 예외처리 코드는 메소드에 마우스를 올려놓으면 throws뒤에 어떤 예외 코드가 발생할지 적혀있기에 이를 참고하면 된다. (**)

                   

                    int result = value1 + value2;

                    System.out.println(data1 + "+" + data2 + "=" + result);

                   

             } catch ( ArrayIndexOutOfBoundsException e) {  // 예외처리 1 - 자식타입을 위에 작성하고,

                   

                    System.out.println("실행매개값의 수가 부족합니다.");

                    System.out.println("[실행방법]");

                    System.out.println("java CatchByExceptionKindExample num1 num2");

                   

             } catch ( Exception e) { // 예외처리 2 - 부모타입을 아래에 적어야 한다!!

                   

                    System.out.println("숫자로 변환할 수 없습니다.");

                   

             } finally { // ( optional ) 항상 실행할 코드 작성 - 옵션이기에 작성하지 않아도 괜찮다.

                   

                           System.out.println("다시 실행하세요.");

                          

             } // try - catch - finally

            

             // 출력 결과 :

            

//           숫자로 변환할 수 없습니다.

//           다시 실행하세요.

            

       } // main

      

} // end class

 

03. 멀티 catch

 

package multi_catch;

 

import lombok.NoArgsConstructor;

 

@NoArgsConstructor

public class MultiCatchExample { // 멀티 catch 작성 방법 (*****)

      

       private static void staticMethod() throws Exception { // 메소드에 throws 작성방법 (***)

            

             throw new Exception(); // 예외가 발생하면 throw할 예외객체를 생성해야 한다. (***)

            

       } // staticMethod - throws 뒤에 적는 예외코드의 의미는 예외코드가 발생할 수 있다는 의미이다.

      

       // throw는 실제로 예외코드를 던지는 것이고, throws는 미리 예외코드가 발생할 수 있음을 알려주는 것이다.

      

       public static void main (String[] args) throws Exception { // 멀티 catch (****)

            

             // main도 예외를 위로 던져야 하기 때문에 staticMethod에 작성한 발생할 수 있는 예외 코드를 throws와 같이 작성해야 한다.

            

             try {

                   

                    String data1 = args[0]; // 배열에 원소를 넣어 주지 않았다.

                    String data2 = args[1];

                   

                    int value1 = Integer.parseInt(data1);

                    int value2 = Integer.parseInt(data2);

                   

                    int result = value1 + value2;

                   

                    System.out.println(data1 + "+" + data2 + "=" + result);

                   

                    MultiCatchExample.staticMethod(); // 정적 멤버는 정적멤버답게 사용하자! (**)

                   

             } catch ( ArrayIndexOutOfBoundsException | NumberFormatException e) { // |를 통해서 같은 예외처리코드를 사용할 예외코드를 동시에 작성한다.

                   

                    System.out.println("실행 매개값의 수가 부족하거나 숫자로 변환할 수 없습니다.");

                   

             } catch ( Exception e) { // 예외처리 2 - 부모타입을 아래에 적어야 한다!!

                    System.out.println("알 수 없는 예외 발생!");

             } finally { // ( optional ) 항상 실행할 코드 작성 - 옵션이기에 작성하지 않아도 괜찮다.

                           System.out.println("다시 실행하세요.");

             } // try - multi catch

//          

             // 출력 :

            

//           실행 매개값의 수가 부족하거나 숫자로 변환할 수 없습니다.

//           다시 실행하세요.

            

       } // main

 

} // end class

 

04. 멀티 catch 02

 

package multi_catch;

 

import lombok.NoArgsConstructor;

 

@NoArgsConstructor

public class MultiCatchExample2 {

      

       private static void staticMethod(String name) throws Exception { // 메소드에 throws 작성방법 (***)

            

             throw new IllegalArgumentException(); // 예외가 발생하면 throw할 예외객체를 생성해야 한다. (***)

            

       } // staticMethod - throws 뒤에 적는 예외코드의 의미는 예외코드가 발생할 수 있다는 의미이다.

      

       // throw는 실제로 예외코드를 던지는 것이고, throws는 미리 예외코드가 발생할 수 있음을 알려주는 것이다.

      

       // throws의 다형성 적용 : (*****)

       // throws와 throw에 다른 예외코드를 작성해도 정상작동 되기도 하는데

       // 그때는 throws 뒤에 부모타입 throw 뒤에 자식타입이 올 때 다형성 적용으로 가능해 진다.

      

       public static void main (String[] args) { // 멀티 catch (****)

            

             // main도 예외를 위로 던져야 하기 때문에 staticMethod에 작성한 발생할 수 있는 예외 코드를 throws와 같이 작성해야 한다.

            

//           try {

//                 

//                  String data1 = args[0]; // 배열에 원소를 넣어 주지 않았다.

//                  String data2 = args[1];

//                 

//                  int value1 = Integer.parseInt(data1);

//                  int value2 = Integer.parseInt(data2);

//                 

//                  int result = value1 + value2;

//                 

//                  System.out.println(data1 + "+" + data2 + "=" + result);

                   

                    try {

                           MultiCatchExample2.staticMethod("1000");

                    } catch (Exception e) {

                           e.printStackTrace(); // 오류 뜬 것을 표시해준다.

                    }

                   

//           } catch ( ArrayIndexOutOfBoundsException | NumberFormatException e) { // |를 통해서 같은 예외처리코드를 사용할 예외코드를 동시에 작성한다.

//                 

//                  System.out.println("실행 매개값의 수가 부족하거나 숫자로 변환할 수 없습니다.");

//                 

//           } catch ( Exception e) { // 예외처리 2 - 부모타입을 아래에 적어야 한다!!

//                  System.out.println("알 수 없는 예외 발생!");

//           } finally { // ( optional ) 항상 실행할 코드 작성 - 옵션이기에 작성하지 않아도 괜찮다.

//                         System.out.println("다시 실행하세요.");

//           } // try - multi catch

//          

             // 출력 :

            

//           실행 매개값의 수가 부족하거나 숫자로 변환할 수 없습니다.

//           다시 실행하세요.

            

       } // main

 

} // end class

 

05. 응용

 

package org.zerock.myapp.banking;

 

import lombok.Getter;

import lombok.NoArgsConstructor;

import lombok.Setter;

 

@NoArgsConstructor

public class Account {

      

       // 고유 속성

       String owner;

       String Number;

       String bank;

      

       // 상태 필드

       @Getter @Setter int balance = 0; // 잔고 - 롬복을 활용하여 게터와 세터 생성

       boolean valid = true; // 통장상태 - 계좌의 유효여부

      

      

       public Account(String owner, String Number, String bank) {

             this.owner = owner;

             this.Number = Number;

             this.bank = bank;

       } // constructor 생성자

      

       boolean deposit(int money) { // 입금

            

//           balance = balance + money;

             balance += money; // 누적

             return ( balance >= 0) ? true : false;

            

       } // deposit

      

       boolean withdraw(int money) { // 출금

            

             balance -= money;

             return ( balance >= 0) ? true : false; // 출금 금액 빼주기

            

       } // withdraw

      

       boolean isValid ( ) {

            

             return true;

            

       } // isValid

 

} // end class


package org.zerock.myapp.banking;

 

public class Customer {

      

       String name;

       String ssn;

      

       void requestTransfer() {

            

             // 사용관계

            

             Teller teller = new Teller();

            

             Account sourceAccount = new Account("Yoseph", "1234-5678", "Bank1");

             sourceAccount.setBalance(5000000); // 롬복을 통해 세터 자동생성

             Account targetAccount = new Account("target", "5678-1234", "Bank2");

             targetAccount.setBalance(0);

            

             Money transferMoney = new Money(1000000);

            

             try {

                    boolean isSuccess = teller.processRequest(sourceAccount , targetAccount , transferMoney);

                    if(isSuccess) { // 이체 성공

                           System.out.println("친구야 힘내!!");

                    } // if

             } catch (InvalidAccountException | InsufficentBalanceException e) { // 2가지의 예외를 잡고 있다.

                    System.out.println("친구야 이체가 안된다ㅠㅠ");

                   

                    e.printStackTrace(); // (*****)

             } // try-catch

            

       } // requestTransfer 메소드

 

} // end class


package org.zerock.myapp.banking;

 

import lombok.NoArgsConstructor;

 

//사용자 정의 예외 클래스 선언 - 비지니스 상 예외를 의미한다.

@NoArgsConstructor

public class InsufficentBalanceException extends RuntimeException { // 시시각각 변하는 경우에는 부모로 런타임예외를 사용하는 것이 좋다.

      

       // + checked 예외는 Exception을 상속받는 것이, 실행예외는 RuntimeException을 상속받는 것이 좋다. (***)

      

       InsufficentBalanceException(String message){

            

             super(message); // 부모를 사용

            

       } // InsufficentBalanceException constructor

 

} // end class


package org.zerock.myapp.banking;

 

import lombok.NoArgsConstructor;

 

 

// 사용자 정의 예외 클래스 선언 - 비지니스 상 예외를 의미한다.

@NoArgsConstructor

public class InvalidAccountException extends RuntimeException { // 예외타입 만들기 (****)

      

//     public InvalidAccountException () {} // default constructor < - - 롬복이 대신 생성해 주었다.

      

       public InvalidAccountException(String message) { // 메세지 남기기

            

             super(message); // 부모인 RuntimeException(String) 사용

            

       } //constructor

 

} // end class


package org.zerock.myapp.banking;

 

import lombok.Getter;

 

public class Money {

      

       @Getter int amount; // 얼마인지

      

       public Money(int amount) {

             this.amount = amount;

       } // constructor

 

} // end class


package org.zerock.myapp.banking;

 

import lombok.NoArgsConstructor;

 

@NoArgsConstructor

public class Teller { // 은행원

      

       boolean processRequest(Account source, Account target, Money transfermoney)

       throws InvalidAccountException, InsufficentBalanceException { // 2 개의 예외가 발생할 수 있음을 알려줌

            

             //예외가 발생하면, 발생한다고 메소드 옆에 적어야 한다. (***)

             // 그러나 실행 예외는 컴파일러가 확인하지 못하기에, 실행예외는 메소드 옆에 작성하지 않아도 괜찮다.

             // 하지만, 그렇게 되면 협업하는 동료가 헷갈릴 수 있기에 작성하여 알려주는 것이 좋다.

            

             // 컴파일러 예외는 throws로 작성해주지 않으면, 바로 오류가 발생하게 된다.(***)

            

            

             // 1. 소스계좌와 타겟계좌가 모두 유효한가?

             if( source.isValid() & target.isValid()) { // Happy Path : 이체 수행

                    // 소스계좌와 타겟계좌가 모두 유효해야지 true!

                   

                    int sourceBalance = source.getBalance();

                    int transMoney = transfermoney.getAmount();

                   

                    /// 2. 잔고확인

                    if ( sourceBalance > transMoney) { // 잔고확인

                          

                           if(source.withdraw(transMoney)) { // 소스계좌에서 transferMoney만큼 뺀다. 소스계좌에서 출금이 성공하면...

                                

                                 boolean isSuccess = target.deposit(transMoney);

                                 System.out.println("이체 성공!");

                                

                                 return isSuccess;

                           } // if- else 3

                          

                           return true; // 바깥 if

                          

                    } else { // 잔고 부족 : 2. 예외를 발생시킨다. (*****)

                          

                           throw new InsufficentBalanceException("잔고가 부족합니다.");

                          

                    } //  inner if-else

                   

             } else { // Alternative (계좌가 유효하지 않으면 ) : 1. 예외를 발생시킨다. (*****)

                   

                    throw new InvalidAccountException("계좌가 유효하지 않음");

                   

             } // if-else

            

       } // processRequest

 

} // end class

 

06. 제네릭 타입

 

package generic_type;

 

public class Apple {

      

       ;;

 

} // end class


package generic_type;

 

public class Box {

      

       private Object object;

      

       public void set ( Object object ) { // 이때 Object는 모든 객체의 조상인 그 Object를 의미하기에 뭐든지 들어갈 수 있다.(**)

             this.object = object; // ( Lvalue는 부모객체,  Rvalue는 자식객체이다 )

       } // setter

      

       public Object get () {

             return object;

       } // getter

 

} // end class


package generic_type;

 

public class BoxExample {

      

       public static void main(String[] args) {

            

             Box box = new Box();

            

             box.set("홍길동"); // 다형성1

             String name = (String) box.get(); // object타입을 string타입으로 강제형변환시키고 있다.

            

//           ========================================

            

             box.set(new Apple()); // 다형성1

             Apple apple = (Apple) box.get(); // object타입을 Apple타입으로 강제형변환시키고 있다.

            

       } // main

 

} // end class

 

728x90
댓글
«   2024/11   »
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
최근에 올라온 글
Total
Today
Yesterday
공지사항