[Java] 자바 파일 입출력 Binary File I/O - 바이너리 스트림 클래스


Binary File I/O - 바이너리 스트림 클래스

 - 바이트 스트림 (byte stream 또는 binary Stream) : 

   중간에 변경없이 바이트 단위 그대로 읽고 쓰는 클래스들.

 

- 상속 계층 구조

   InputStream

1) Data Sink Stream 클래스 (데이터를 직접 읽고/쓰는 클래스)

-> FileInputStream - read(), read(byte[]), read(byte[], offset, length)

-> ByteArrayInputStream

-> PipedInputStream


2) Data Processing Stream 클래스 (중간에서 데이터 가공)

-> BufferedInputStream

-> DataInputStream

-> ObjectInputStream


   OutputStream

1) Data Sink Stream 클래스 (데이터를 직접 읽고/쓰는 클래스)

-> FileOutputSteam - write(int), write(byte[]), write(byte[], offset, length)

-> ByteArrayOuputStream

-> PipedOutputStream


2) Data Processing Stream 클래스 (중간에서 데이터 가공)

-> BufferedOutputStream

-> DataOutputStream

-> ObjectOutputStream

-> PrintStream





1-1. FileOutputSteam 예제 



import java.io.FileOutputStream;
public class Test02_1 {
  public static void main(String[] args) throws Exception {
    // 1) FileOutputStream 객체 생성
    FileOutputStream out = new FileOutputStream("test02_1.data");
   
    // write(int) => 무조건 끝 1바이트만 출력
    out.write(0x66778899);
    out.write(0x77665544);
    out.write(0x12345678);
   
    // 출력 스트림을 다 사용했으면 파일을 닫아라
    // => 파일을 다루기 위해 준비했던 메모리를 해제시킨다.
    // => OS 파일 시스템과의 연결도 끊는다.
    out.close();
   
  }

}


- 실행 결과 : 

root 폴더에 "test02_1.data"파일이 생성된 것을 알 수 있다. 

또한 write()를 호출해 넘겨준 아규먼트 값이 들어간 것을 확인할 수 있다.



1-2. FileInputStream 예제



 public static void main(String[] args) throws Exception {
    // 1) FileOutputStream 객체 생성
    FileInputStream in = new FileInputStream("test02_1.data");
   
    // read(int)
    // => 무조건 끝 1바이트만 읽는다.
    // => 하지만 리턴 타입이 int이기 때문에 int 타입 변수로 값을 받아야 한다.
    int b = in.read();
    System.out.printf("%x ", b);
    b = in.read();
    System.out.printf("%x ", b);
    b = in.read();
    System.out.printf("%x ", b);
  
    // 입력 스트림을 다 사용했으면 파일을 닫아라
    // => 파일을 다루기 위해 준비했던 메모리를 해제시킨다.
    // => OS 파일 시스템과의 연결도 끊는다.
    in.close();
   
  }

}


- 실행 결과 :

99 44 78





2-1. FileOutputSteam 예제 



import java.io.FileOutputStream;


public class Test02_3_out {
  public static void main(String[] args) throws Exception {
    // 1) FileOutputStream 객체 생성
    FileOutputStream out = new FileOutputStream("test02_3.data");
   
    byte[] bytes = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
    out.write(bytes, 2, 3); // 바이트 배열에서 2번 방부터 3개 출력
   
    out.close();
    System.out.println("파일 출력 완료!");
   
  }

}

- 실행 결과 : 

root 폴더에 "test02_3.data"파일이 생성된 것을 알 수 있다. 

또한 write()를 호출해 넘겨준 아규먼트 값이 들어간 것을 확인할 수 있다.




2-2. FileInputSteam 예제 



public class Test02_3_in {

  public static void main(String[] args) throws Exception {
    // 1) FileOutputStream 객체 생성
    FileInputStream in = new FileInputStream("test02_3.data");
   
    // 바이트 배열을 저장할 메모리를 준비한다.
    byte[] bytes = new byte[1024]; // heap에 만들어지는 것은 0으로 자동 초기화된다.
    int len = 0;
   
    // read(배열주소, offset, length)
    // => 배열주소: 데이터를 저장할 배열
    // => offset: 저장할 위치(index: 0부터 ~)
    // => length: '희망'하는 읽기 개수
    // => 리턴값: 실제 읽은 바이트 수
    len = in.read(bytes, 5, 2);
   
    for (int i = 0; i < 10; i++) {
      System.out.printf("%x ", bytes[i]);
    }
    in.close();
  }
}

- 실행 결과 :

0 0 0 0 0 33 44 0 0 0 2




블로그 이미지

필로그래머

,



예외처리 : throws 선언

 - 예외를 발생시키는 코드를 사용할 때 당장 예외 처리를 하고 싶지 않다면,

   메서드 선언부에 그 예외 정보를 적시하면 된다.

   그러면 그 메서드를 호출하는 쪽에서 처리할 것이다.

 - 즉 해당 메서드에서 어떤 예외가 발생하는지 알리는 것이 목적이다.




throws 예외처리 예제 I


public class Test08 {
  public static void main(String[] args)
      throws Exception, IllegalArgumentException, NumberFormatException {
     
      if (args.length < 1)
        throw new IllegalArgumentException("애플리케이션 아규먼트가 없습니다.");
      int age = Integer.parseInt(args[0]);
     
      if (age < 1)
        throw new Exception("나이가 유효하지 않습니다.");
     
      System.out.println(age);
  }

 }



* 참고

   - throws 는 메서드 선언부에 '단수 or 복수 개'의 예외를 던지며

     main()에 써서 예외가 발생했을 경우, 바로 선언부로 돌아가 예외처리를 하고

     프로그램은 종료된다.

   - throw는 예외가 발생했을 때, 하나의 예외 인스턴스를 던질 때 사용한다. 





** 참고 - 다음 예제

    - java.lang.RuntimeException 계열의 예외가 발생할 때는 

      예외를 처리하는 것이 선택사항이다.

      컴파일러가 강제로 요구하지 않는다. 

      => 예외를 처리하는 try ~ catch ~ 을 사용하지 않아도 되고,

           메서드 선언 부에 throws를 적시하지 않아도 된다.

    - 이유 :

       스텔스 모드로 예외를 전달하기 위해 특별히 정한 규칙이다.




throws 예외처리 예제 II - 스텔스 모드


public class Test12 {
 
  static void m1(int v) {
    m2(v);
  }
  static void m2(int v) {
    m3(v);
  }
  static void m3(int v) {
    m4(v); // 자기가 직접 발생시키는 에러가 아니라 m4()가 발생시키는 에러라 할지라도
           // m3()에서 에러를 처리해줘야 한다.
  }
 
  // 예외를 발생시키는 메서드(m4())와 그 메서드를 호출.
  static void m4(int v) {
      if (v < 0)
        throw new RuntimeException("음수는 허용하지 않습니다.");
      System.out.println(v);
  }
 
  public static void main(String[] args) {
    try {
      if (args.length < 1) {
        System.out.println("[사용법] java -cp bin step17.Test11 숫자");
        return;
      }
        m1(Integer.parseInt(args[0]));
    } catch (NumberFormatException e) {
      System.out.println("프로그램 아규먼트는 숫자여야 합니다.");
    } catch (Exception e) {
      e.printStackTrace();
    }
    System.out.println("안녕! 디지몬");
  }
}



*** 참고

예외를 발생시키는 메서드를 사용한다면 반드시 둘 중 하나는 해야 한다.

 1) try ~ catch ~ 로 예외를 정확히 처리하거나,

 2) 이 메서드 안에서 예외가 발생한다고 메서드 '선언부'에 적시하거나.



스텔스 모드를 사용하는 이유는 예외가 발생하더라도, 상위 메서드까지 조용히 

던지기 위함이다. 그렇다고 하더라도 예외는 최소한 main()에서는 개발자가 처리해야

한다. 만약 main()에서까지 예외가 처리되지 않는다면 예외 발생시 JVM에까지 전달될

것이고 그 결과 프로그램이 종료될 것이다.




블로그 이미지

필로그래머

,

[Java] (5) 예외처리 (exception) - 사용자 정의 예외 던지기


예외처리 : 사용자 정의 예외 던지기

 - 예외 상황이 발생했을 때 예외 객체를 만들어 던진다.

 - 예외 객체를 만들기 위해 예외 클래스를 선택해야 하는데,

   그 선택의 기준은 클래스의 이름이다.

   즉 예외 상황을 잘 표현할 수 있는 이름을 가진 클래스를 선택한다.


 - 그런데 예외 상황에 딱 맞는 마땅한 예외 클래스가 없을 경우,

   또는 예외 상황을 좀 더 잘 표현하고 싶을 경우,

   개발자가 직접 예외 클래스를 만들어 던질 수 있다.

 - 이때 그 클래스는 애플리케이션 예외이어야 하기 때문에

   보통 java.lang.Exception을 상속 받아서 만든다.


 - Exception을 상속 받아 뭔가 특별한 기능을 추가한다기 보다,

   예외 상황을 잘 드러내는 이름을 가진 클래스를 만든다는 의미로

   서브 클래스를 작성해야 한다.


- 보통 상속은 기존 클래스의 기능을 확장하는 것에 있지만,

  예외클래스들의 상속은 기능을 더 보태는 개념이 아니다.

  예외 클래스의 상속은 '기능 추가'가 목적이 아니라, 각 예외를 이름 별로

  구분하는 것이 목적이다. 이름


 

사용자 정의 예외 클래스를 만드는 이유 : 

 1) 기능을 확장하기 위한 것이 아니다.

 2) 예외 상황이 발생했을 때, 클래스 이름으로 즉기 그 예외 상황을 파악하려는 것이다.

 3) 그래서 예외 클래스의 상속 관계는 이름으로 예외를 분류하는 데 의미를 두고 있다.

 

 


사용자 정의 예외 클래스의 예제


public class Test07 {

  static class InvalidValueScopeException extends IllegalArgumentException {
    public InvalidValueScopeException() {
      super();
      // TODO Auto-generated constructor stub
    }
    public InvalidValueScopeException(String message, Throwable cause) {
      super(message, cause);
      // TODO Auto-generated constructor stub
    }
    public InvalidValueScopeException(String s) {
      super(s);
      // TODO Auto-generated constructor stub
    }
    public InvalidValueScopeException(Throwable cause) {
      super(cause);
      // TODO Auto-generated constructor stub
    }
   
  }
  public static void main(String[] args) {
    try  { // try 블록 안에 예외를 던질 수 있는 코드를 넣고
      if (args.length < 1)
        throw new IllegalArgumentException("애플리케이션 아규먼트가 없습니다.");
      int age = Integer.parseInt(args[0]);
     
      if (age < 1)
        throw new InvalidValueScopeException("나이가 유효하지 않습니다.");
     
      System.out.println(age);
    } catch (Throwable ex) {
      ex.printStackTrace();
    }
  }
 }


- 실행 결과 :



블로그 이미지

필로그래머

,

[Java] 자바 (4) 예외처리 - catch


예외처리 : catch

 - throw가 전달한 예외 객체를 받는 명령어다.  

   다시 말해, 예외가 발생했을 경우 어떻게 할 것인지를 처리하는 명령어다.

 - 문법

   catch (예외 객체를 받을 변수)

 - 예외 객체의 타입 별로 구분하여 받을 수 있다.

   변수의 타입에 따라 예외를 받을 catch문이 선택된다.


 - 작성 순서

    - 예외를 던지면(예외가 발생하면) 그 예외를 받을 catch 문을 찾는데,

      catch 문이 선언된 순서대로 찾는다.

    - 그래서 작성할 때 순서를 주의해야 한다.

      여러 개의 catch 문이 있을 때, 최하위 클래스를 파라미터로 받는 

       catch 문을 작성해야 한다.


    - 이유 :

       다형성의 다형적 변수 규칙상, 레퍼런스 변수는 하위 타입의

       객체까지 저장할 수 있다. 그래서 상위 타입의 변수가 먼저 있으면,

       하위 타입의 변수를 선언한 catch문은 영원히 실행되지 않는다.

       이런 이유 때문에 자바 컴파일러는 아예 이런 순서를 실행하지 않는다.



catch exception 예외처리 예제


public class Test06 {
  public static void main(String[] args) {
    // 다음과 같이 예외 상황이 발생하면 예외 정보를 던지는 코드를 실행 할때
    // 그 예외를 전달 받을 코드를 작성해야 한다.
    // trh {} catch() {} 문법을 사용하여 처리하라!
    try  { // try 블록 안에 예외를 던질 수 있는 코드를 넣고
      if (args.length < 1)
        throw new Throwable("애플리케이션 아규먼트가 없습니다.");
      int age = Integer.parseInt(args[0]);
     
      if (age < 0)
        throw new Exception("나이가 유효하지 않습니다.");
     
      System.out.println(age);
    } catch (NumberFormatException e) {
      System.out.println("애플리케이션의 아규먼트가 숫자가 아닙니다.");
    } catch (Exception ex) {
      System.out.println("나이 값이 유효하지 않습니다.");
    } catch (Throwable ex) { // catch 블록 안에 예외를 받는 코드를 넣는다.
      // 예외를 처리하는 코드를 둔다.
      System.out.println(ex.getMessage());
    }
  }

 }


- 실행결과




블로그 이미지

필로그래머

,

[Java] 자바 (3) 예외처리 (exception) - throw 명령


예외처리 : throw 명령

 - 예외가 발생했을 때 현재 위치에서 즉시 실행을 멈추고,

   코드를 실행하는 쪽에 예외 정보를 전달하는 명령어이다.

 - 문법

    throw [java.lang.Throwable 타입 객체];



throw 명령의 예제

public class Test04 {

  public static void main(String[] args) {
    // 다음과 같이 예외 상황이 발생하면 예외 정보를 던지는 코드를 실행 할때
    // 그 예외를 전달 받을 코드를 작성해야 한다.
    // trh {} catch() {} 문법을 사용하여 처리하라!
    try  { // try 블록 안에 예외를 던질 수 있는 코드를 넣고
      if (args.length < 1)
        throw new Throwable("애플리케이션 아규먼트가 없습니다.");
      int age = Integer.parseInt(args[0]);
     
      if (age < 0)
        throw new Throwable("나이가 유효하지 않습니다.");
     
      System.out.println(age);
    } catch (Throwable ex) { // catch 블록 안에 예외를 받는 코드를 넣는다.
      // 예외를 처리하는 코드를 둔다.
      System.out.println(ex.getMessage());
    }
  }

 }



- 실행 결과



블로그 이미지

필로그래머

,

ArrayList란 무엇일까?

ArrayList에서 선언된 가장 중요한 함수를 통해 

개념을 이해해볼 것이다.



List - ArrayList

    - null 값을 저장할 수 있다.

    - 값을 중복 저장할 수 없다.

    - 값을 넣는 순서대로 저장한다.

      그래서 값을 꺼낼 때도 넣은 순서대로 꺼낼 수 있다.

    - 값을 꺼낼 때 숫자 인덱스를 사용하여 꺼낸다.



1)

ArraList 1. Object[] 배열 생성 코드를 작성한다.


public class ArrayList_ex1 {

 
  // Object 배열을 생성할 때, 기본적으로 생성해줘야 하는 사이즈(DEFAULT_SIZE)를 지정해준다.
  public static final int DEFAULT_SIZE = 10;
  // Object 배열에 값을 넣어줄 때, 추가로 생성해주고 싶은 사이즈(GROW_SIZE)를 지정해준다.
  public static final int GROW_SIZE = 3;
 
  Object[] list;
 
  // ArrayList_ex1 인스턴스를 생성하자마자, 호출되는 생성자 함수에서
  // 자동적으로 Object 배열의 빈 값을 10개 생성해주도록 한다.
  public ArrayList_ex1() {
   list = new Object[10];
  } 

}



2)

ArrayList 2. new ArrayList_ex1(숫자); 작성시 호출되는 

Object[] 배열 생성자 코드를 작성한다.


 // 기본 사이즈나 추가 사이즈보다 작은 수가 넘어오면 기본 사이즈로 배열을 생성한다.
public ArrayList_ex1(int capacity) {
 if (capacity < DEFAULT_SIZE || capacity < GROW_SIZE) {
   list = new Object[DEFAULT_SIZE];
 } else { // 그 외에는 입력받은 숫자대로 배열을 생성한다.
   list = new Object[capacity];
 }
}




3)

ArrayList 3. 배열의 길이를 증가시키는 increaseList() 

메서드 코드를 작성한다.


// 배열의 길이를 증가시키는 메서드. 내부 메서드이기 때문에 private을 사용한다
private void increaseList() {
  // 생성된 배열의 길이에 GROW_SIZE를 더 한 만큼 배열을 추가로 생성한다.
  Object[] newList = new Object[list.length + GROW_SIZE];
 
  // 반복문을 통해, 새롭게 생성되었던 newList 배열의 각 인덱스 값에 list 배열 값들을 저장한다.
  for (int i = 0; i < list.length; i++) {
   newList[i] = list[i];
  }
 
  // list 변수에 newList 배열의 주소를 할당해주면 된다.
  list = newList;

}




4)

ArrayList 4. 배열에 값을 넣어주는 add() 메서드를 추가한다.


// 배열에 값을 넣어주는 메서드
public void add(Object obj) {
  // add 메서드가 호출될 때마다 length 값을 하나씩 증가시키면서 obj 값을 list 배열에 삽입한다.
  list[length++] = obj;
 
  // length와 배열의 길이가 일치하면 배열의 길이를 증가시킨다.
  if (length == list.length) {
    increaseList();
  }

}




5)

ArrayList 5. 배열에 저장된 값을 꺼내는 get() 메서드를 추가한다.


// 배열에 저장된 값을 꺼내는 get() 메서드를 추가한다.
public Object get(int index) {
 
  // index 값이 배열의 길이보다 많거나 0보다 작다면 에러처리를 해준다.
  if (index < 0 || index >= length) {
    throw new RuntimeException("배열 인덱스의 범위를 벗어났습니다.");
  }
 
  // 그외에는 list 배열에서 해당 인덱스에 저장된 값을 리턴한다
  return list[index];

}




6)

ArrayList 6. 배열에서 특정 인덱스를 제거하는 remove() 메서드를 추가한다.


// 배열에서 특정 인덱스를 제거하는 remove() 메서드를 추가한다.
public void remove(int index) {
 
  //index 값이 배열의 길이보다 많거나 0보다 작다면 에러처리를 해준다.
  if (index < 0 || index >= length) {
    throw new RuntimeException("배열 인덱스의 범위를 벗어났습니다.");
  }
 
  // 입력받은 index 값부터 list 배열에 있는 값들을 하나씩 당겨서 저장한다.
  // (덮어씌어 지면서 기존 값이 지워지는 것)
  for (int i = index; i < list.length - 1; i ++) {
    list[i] = list[i+1];
  }
 
  // 배열의 길이를 하나 줄인다.
  length--;

}






7)

ArrayList 7. 배열에서 특정 인덱스에 값을 저장하는 set() 메서드를 추가한다.


// 배열에서 특정 인덱스에 값을 저장하는 set() 메서드를 추가한다.
public void set(int index, Object obj) {
 
  //index 값이 배열의 길이보다 많거나 0보다 작다면 에러처리를 해준다.
  if (index < 0 || index >= length) {
    throw new RuntimeException("배열 인덱스의 범위를 벗어났습니다.");
  }
 
  // list[index]에 값을 저장시킨다.
  list[index] = obj;

}





main() 메서드 예제


import java.sql.Date;
public class Test_ArrayList{
  public static void main(String[] args) {
   ArrayList_ex1 dateList = new ArrayList_ex1();
   
    dateList.add(Date.valueOf("2017-3-1"));
    dateList.add(Date.valueOf("2017-5-3"));
    dateList.add(Date.valueOf("2017-5-5"));
    dateList.add(Date.valueOf("2017-5-9"));
    dateList.add(Date.valueOf("2017-6-6"));
    for (int i = 0; i < dateList.length(); i++) {
      System.out.println(dateList.get(i));
    }
    System.out.println("-------------------------");   
   
    dateList.remove(3);
    dateList.set(1, Date.valueOf("2017-5-4"));
   
    for (int i = 0; i < dateList.length(); i++) {
      System.out.println(dateList.get(i));
    }
       
  }

}


- 실행 결과 : 

2017-03-01

2017-05-03

2017-05-05

2017-05-09

2017-06-06

-------------------------

2017-03-01

2017-05-04

2017-05-05

2017-06-06




블로그 이미지

필로그래머

,

[Java] 자바 (2) 예외처리 - 1. throw throwable 2. Error 예외와 Exception 예외 비교


예외처리 : 예외 발생 시 그 정보를 전달하고 전달 받는 방법

 - 예외 정보를 호출자에게 전달하는 방법

    throw [Throwable 객체];

     - 예외 정보를 담은 객체란 무엇인가?

        java.lang.Throwable 타입의 객체이다.

        - java.lang.Throwable 클래스 계층 구조

    Throwable           

     | --> Error

     | --> Exception

             | --> RuntimeException

                     | --> NullPointerException

             | --> IOException

               | --> FileNotFoundException

               | --> EOFException

       | -->  SQLException 

                   | -->  그외 (..)


        - 예외 종류

           1) 시스템 예외(Error 타입 예외)

               - JVM이 발생시키는 예외이다.

    - 개발자가 처리하는 예외가 아니다.

    - 개발자가 처리하기엔 치명적인 예외라서 가능한 JVM을 종료해야 한다.

    - 이 예외가 발생했을 때,

       개발자는 JVM이 종료되기 전에 작업 중인 파일을 저장하거나

       예외에 대한 로그를 파일에 쓰거나

       사용자에게 예외 상황을 출력하는 등의 마무리 작업을 하고 

       JVM을 종료한다.


           2) 애플리케이션 예외(Exception 타입 예외)

               - 애플리케이션에서 발생하는 예외이다.

               - 개발자가 처리해야 하는 예외이다.

               - 예외를 처리한 후에 애플리케이션을 계속 실행할 수 있다.


 - 예외 정보를 받는 방법

    try {

예외를 던지는 코드

    } catch (예외를 받을 변수 선언) {

예외를 처리하는 코드

    }




예외처리 예제


public class Test03 {
  // 메서드를 실행하다가 예외를 던질 수 있는 경우
  // => 메서드 선언부에 어떤 예외가 던져질 수 있는지 적어야 한다.
  public static float divide(float a, float b) throws Throwable{
    if (b == 0) {
      // 예외 상황이 발생하면, 호출자에게 그 정보를 전달해야 한다.
      throw new Throwable("0으로 나누지 마세요!");
    }
    return a / b;
  }
 
  public static void main(String[] args) {
    try { // 예외를 던질 수 있는 코드는 try 블록 안에 둔다.
      float result = divide(10, 2);
      System.out.println(result);
      result = divide(10, 0);
      System.out.println(result);
    } catch (Throwable ex) {
      System.out.println(ex.getMessage());
    }
System.out.println("Hello"); // 예외가 발생하든 안하든 실행!
  }

}


 - 실행결과 : 

5.0

0으로 나누지 마세요!



 - 예외 처리 문법의 이점 

    1) 메서드가 리턴하든 안하든, 

       리턴하는 값의 타입이 무엇이든 

       호출자에게 예외 정보를 전달할 수 있다.

    2) 예외를 처리하는 입장에서는 try 블록 안에는 예외 상황이 아닐 때의 

        작업 코드를 두고, catch 블록 안에는 예외를 처리하는 코드를 둠으로써

        정상 작업 코드와 예외 처리 코드를 분리하는 효과가 있다.

         -> 코드의 가독성 ↗

    3) 예외가 발생하더라도 적당한 처리를 한 후

        시스템을 멈추지 않고 계속 실행시킬 수 있다.



블로그 이미지

필로그래머

,

[Java] 자바 (1) 예외처리 - 조건문 사용과 그 문제점


예외처리 : 예외 처리 문법이 없을 경우

- 개인용 프로그램일 때는 에러가 떠도 큰 문제가 없을 수 있지만,  기업에서 운영하는

  웹브라우저가 사용자로부터 요청 받으면 안되는 데이터를 받게 될 경우, 서버가 느려

  지거나 뻗는 문제가 발생할 수 있다.  이런 경우에 사용하게 되는 문법이 예외처리이다.



조건문을 사용하여 예외처리를 하는 경우


public class Test02 {
  public static float divide(float a, float b) {
    if (b == 0) {
      return -121255f;
    }
    return a / b;
  }
 
  public static void main(String[] args) {
    float result = divide(10, 2);
    if (result == -121255f) {
      System.out.println("0으로 나눌 수 없습니다.");
    } else{
      System.out.println(result);
    }
    result = divide(10, 0);
    if (result == -121255f) {
      System.out.println("0으로 나눌 수 없습니다.");
    } else {
      System.out.println(result);
    }
  }
}


- 실행 결과 :

5.0

0으로 나눌 수 없습니다.



문제점

 - 조건문을 사용하여 예외처리를 하는 경우 메서드를 호출할 때마다 그 리턴 값을

   검사해야 한다.

 - 메서드를 사용하는 코드 안에 일을 시키는 코드와 예외처리 코드가 섞여 있어서

   유지보수가 어려워진다.

 - 리턴값이 유효한 값인 경우가 종종 발생할 수 있다. (다음 예제 참고)




위 예제에 다음 코드를 추가해보기


result = divide(121255, -1);
    if (result == -121255f) {
      System.out.println("0으로 나눌 수 없습니다.");
    } else {
      System.out.println(result);

    }

- 실행결과 :

5.0

0으로 나눌 수 없습니다.

0으로 나눌 수 없습니다.


- 0으로 나누지 않았는데도 불구하고 리턴 값이 -121255가 되는 바람에 0으로 나눈

  것으로 처리된다.



블로그 이미지

필로그래머

,