Java

자바 예외처리 ~ IO 입출력 내용 정리

최종군 2024. 7. 14. 13:38

 

체크드 예외 (Checked Exceptions)

컴파일 시점에서 반드시 처리되어야하는 예외 

 

IOException : 입출력 작업  중 발생하는 예외 

EOFExeption : 주로 입력 스트림에서 예상치 못한 파일의 끝에 도달했을 떄 발생하는 예외 

SQLException : 데이터베이스 작업 중 발생하는 예외 

ClassNotFoundException: 클래스를 찾을 수 없을 때 발생하는 예외

FileNotFoundException: 파일을 찾을 수 없을 때 발생하는 예외.

InterruptedException: 스레드가 대기, 수면, 또는 다른 작업에서 인터럽트 되었을 때 발생하는 예외.

 

언체크드 예외 (Unchecked Exceptions)

  1. NullPointerException: 객체가 null인데 메서드필드에 접근하려고 할 때 발생.
  2. ArrayIndexOutOfBoundsException: 배열의 인덱스가 범위를 벗어났을 때 발생.
  3. ArithmeticException: 산술 연산에서 오류가 발생할 때 (예: 0으로 나누기).
  4. ClassCastException: 잘못된 클래스 타입으로 캐스팅할 때 발생

class Animal {
    void sound() {
        System.out.println("Some sound...");
    }
}

class Dog extends Animal {
    void sound() {
        System.out.println("Bark");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Animal();
        
        // 잘못된 캐스팅: Animal 객체를 Dog로 캐스팅할 수 없음
        try {
            Dog dog = (Dog) animal;
        } catch (ClassCastException e) {
            System.out.println("잘못된 클래스 타입으로 캐스팅했습니다: " + e.getMessage());
        }
    }

위 코드에서 animal 객체는 Animal클래스를 인스턴스화한 객체이다 

이를 Dog 클래스로 캐스팅을 시도하면 classCastExeption이 발생한다 

 

5.NumberFormatException: 문자열을 숫자로 변환할 때 형식이 맞지 않아서 발생

 

public class Main {
    public static void main(String[] args) {
        String str = "abc";
        
        try {
            int num = Integer.parseInt(str);
        } catch (NumberFormatException e) {
            System.out.println("NumberFormatException 발생: " + e.getMessage());
        }
    }
}

숫자가 아닌 abc 문자열을 정수로 변환 시 발생한다 혹은 

public class Main {
    public static void main(String[] args) {
        String str = "123.45";
        
        try {
            int num = Integer.parseInt(str);
        } catch (NumberFormatException e) {
            System.out.println("NumberFormatException 발생: " + e.getMessage());
        }
    }
}

정수형이 아닌 실수형으로 변환 시에도 발생하며 

마지막 예시로는 

 

public class Main {
    public static void main(String[] args) {
        String str = " 123 ";
        
        try {
            int num = Integer.parseInt(str.trim());
            System.out.println("변환된 숫자: " + num);
        } catch (NumberFormatException e) {
            System.out.println("NumberFormatException 발생: " + e.getMessage());
        }
    }
}

문자열 123에는 공백이 포함되어 있다 이때로 발생하는예외이다 이때 trim을 사용을 하여 공백을 제거하면 예외는 발생하지 않는다 

 

// "101" 이라는 값을 Integer 타입으로 바꾸고자 한다면..?

Integer i4 = new Integer("101"); // "101" -> 101

System.out.println(i4);

int n4 = Integer.parseInt("112");

System.out.println(n4);

 

// 101이라는 값을 String 타입으로 바꾸고자 한다면..?

String n101 = String.valueOf(777);

System.out.println(n101);

}

 


 getter/setter 메소드 : 

 

this. 키워드 : 클래스의 인스턴스 자신을 참조한다 

this 키워드를 사용하면 메소드나 생성자 내에서 클래스의 필드와 

메소드에 접근을 할 수 있다 

메소드나 생성자의 매개변수 이름이 클래스의 필드 이름과 동일할 경우 

필드와 매개변수를 구분을할 수 있다 

 

this 키워드를 사용하지 않으면 클래스의 필드와 메소드의 매개변수가 구분 되지 않아 

필드에 값이 제대로 할당되지 않을 수 있다 - 즉 의도한 대로 프로그램이 작동하지 않을 수 있다 

 

따라서 클래스의 필드와 메소드의 매개변수 이름이 동일할 때는 

this 키워드를 사용하여 명확하게 필드에 접근하는 것이 중요하다. 

 

매개변수 생성자 : (parameterized constructor)

 

클래스의 객체를 생성할 때 객체 초기 상태를 설정하기 위해 

필요한 값을 인자로 받는 생성자이다 

 

기본 생성자는 인자가 없으면 객체를 생성할 떄 

기본값으로 초기화하는 반면, 매개변수 생성자는 객체 생성 시 인자를 통해

원하는 값을 설정할 수 있도록 한다 

 


 

 

 

try {
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName));

    for (Object o : object){
        oos.writeObject(o); // 객체를 출력하는 스트림

    }


// 자원 해제 finally:  finallys 블록은 예외가 발생하더라도 반드시 실행된다 예외 유무 상관없이
//
}catch (IOException e){
    e.printStackTrace();
}

 

 자원을 해제하는 방법 

 

자원을 적절히 해제하는 것이 중요하다 

 

자원을 해제하는 방법 2가지 

 

자원을 해제하는 방법에는 두 가지 방법이 있다

try-with-resources 구문을 사용하게 되면 try블록이 끝나면 

자원들이 자동으로 해제가 된다. 

 

try-with-resources 구문 활용 예 : 

 

 

 

public void objectSave(String fileName,Object[] object){

 
    try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName))){
 
        
        
        
        for (Object o : object){
            oos.writeObject(o); // 객체를 출력하는 스트림

        }
        // 자원 해제 finally:  finallys 블록은 예외가 발생하더라도 반드시 실행된다 예외 유무 상관없이
    }catch (IOException e){
        e.printStackTrace();
    }
        
    


}

 

 

 코드가 매우 간결해지는 장점을 가지고 있다 

 

 

 

 

 

 

 

 

 

(try-with-resources 미사용) :

 잘못된 예 

 

try {
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName));

    for (Object o : object){
        oos.writeObject(o); // 객체를 출력하는 스트림

    }


// 자원 해제 finally:  finallys 블록은 예외가 발생하더라도 반드시 실행된다 예외 유무 상관없이
//
}catch (IOException e){
    e.printStackTrace();
}finally{
    try {
        if(oos != null)oos.close();

    }catch (IOException e){
        e.printStackTrace();
    }
}

 

 

 

 해당 코드 문제점 : 

변수 스코프 문제 : oos 변수가 try 블록 내부에서 선언되어 

finally 블록에서 접근할 수 없다

 

해결 방법 : 

변수 스코프 확장 : oos와 fos변수를 try 블록 외부에서 선언하여 

finally 블록에서도 접근할 수 있도록 해야된다. 

 

ObjectOutputStream oos = null;
FileOutputStream fos = null;
try {
    fos = new FileOutputStream(fileName);
    oos = new ObjectOutputStream(fos);

    for (Object o : object){
        oos.writeObject(o); // 객체를 출력하는 스트림

    }


// 자원 해제 finally:  finallys 블록은 예외가 발생하더라도 반드시 실행된다 예외 유무 상관없이
//
}catch (IOException e){
    e.printStackTrace();
}finally{
    try {
        if(oos != null)oos.close();
        if(fos != null)fos.close();
    }catch (IOException e){
        e.printStackTrace();
    }
}

 

 수정된 예시이다 

여기서 oos에서 close를 하기 때문에 

fos는 clos를 생략을 해도 되지만 명시적인 목적으로 같이 close를 하게 되었다.

 

 

 

 

 public void objectRead(String fileName){

/*
        FileInputStream fis = null;

        ObjectInputStream ois = null;
        ois = new ObjectInputStream(fis);
        fis = new FileInputStream(fileName);
*/
        try{
        try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName))) {


            while (true) {
                System.out.println(ois.readObject());
            }
            // read()는 스트림에서 하나의 바이트를 읽고 이를 int로 반환한다.
            // 객체를 읽는데 사용되는 메서드는 ois.readObject()이다
        }catch (ClassNotFoundException e){
            e.printStackTrace();}
        }catch (EOFException e){
            e.printStackTrace();
        } catch (IOException e){
            e.printStackTrace();
        }

 

위에서 보면 while문은 true이다 

즉 무한 반복을 하게된다 

 

EOFException은 파일 끝에 도달했을 경우 발생되는 예외이다 

EOF문도 

 

ClassNotFoundException은 체크드 exception이기 때문에 

반드시 처리해야된다

ClassNotFoundException은 특정 클래스의 정의를 찾을 수 없을 떄

발생되기도 한다. 

 

 


 

static 키워드의 유무 

static 없이 선언된 멤버변수는 인스턴스 변수이다 이는 클래스의 각 인스턴스마다 별도의 복사본을 가진다 

 

 

 

 

 


public은 접근 제어자 중 하나로 클래스, 메서드, 필드 등이 어디서나 접근 가능하도록 한다

public 클래스는 파일명과 동일한 이름을 가져야하며, 하나의 JAVA파일에 하나의 

public 클래스만 존재할 수 있다. 

 

static 키워드 

static은 클래스의 멤버(변수나 메서드)를 클래스 레벨에서 사용할 수 있도록 한다 

즉 객체의 인스턴스가 아니라 클래스 자체에 속하게 된다 

static은 클래스 내부의 메서드나 변수에 사용할 수 있다 static클래스를 선언할 수 있지만 

이는 중첩 클래스(내부 클래스)에 한정된다 

 

 

 

'Java' 카테고리의 다른 글

자바 헷갈리는 내용 정리  (1) 2024.07.15
내가 잘 모르는 부분들 내용정리 JAVA  (0) 2024.07.15
자바 복습 _2 상속, 다형성  (0) 2024.07.13
자바 Map  (0) 2024.07.12
자바 복습하기 _ 1  (0) 2024.07.11