Abstract Class, Interface, Exception, Stream

labbiel·2025년 5월 3일

자바

목록 보기
8/9
post-thumbnail

목차
1. Exception
2. 추상 클래스와 인터페이스
3. Stream


1. 예외(Exception) 처리

예외(Exception)는 프로그램 실행 중 발생할 수 있는 예기치 않은 사건이나 상황을 말합니다.

예외 종류

  1. 컴파일 예외(Compile-time Exception)
  • 컴파일 시점에서 발생할 수 있는 예외로, 반드시 처리해주어야 합니다.
  • IOException, FileNotFoundException 등이 있습니다.
  1. 런타임 예외(Runtime Exception)
  • 프로그램 실행 중에 발생할 수 있는 예외로, 컴파일러는 처리 여부를 강제하지 않습니다.
  • NullPointerException, ArrayIndexOutOfBoundsException 등이 있습니다.
  1. 예외 처리 방식
  • Java에서 예외를 처리하는 방법은 try-catch-finally 구문을 사용합니다.
try {
    // 예외가 발생할 수 있는 코드
} catch (ExceptionType e) {
    // 예외 처리 코드
} finally {
    // 예외가 발생하든 안 하든 반드시 실행되는 코드
}

예외 처리 예시 (FileReader 사용)

package com.edu.exception.test3;

import java.io.FileReader;
import java.io.IOException;

class FileService4 {
    public void readFile(String fileName) throws IOException {
        System.out.println("2. FileReader Creating...");
        
        try (FileReader fr = new FileReader(fileName)) { // try-with-resources 구문 사용
            System.out.println("3. 파일을 성공적으로 찾았습니다.");
            int data;
            while ((data = fr.read()) != -1)
                System.out.print((char) data);
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
}

public class CompileExceptionTest4 {
    public static void main(String[] args) {
        System.out.println("1. readFile() calling...");
        FileService4 service = new FileService4();
        try {
            service.readFile("text.txt");
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
}
  • try-with-resources 구문을 사용하여 파일을 열고, 작업을 마친 후 자원을 자동으로 반납합니다. try-with-resources는 자원을 자동으로 닫아주므로 반드시 자원 반환을 구현해야 하는 경우 유용합니다.


2. 추상 클래스(Abstract Class)와 인터페이스(Interface)

추상 클래스(Abstract Class)는 완전한 구현을 제공할 수 있는 클래스와 완전한 추상화를 제공하는 클래스의 중간 형태입니다. 추상 클래스는 추상 메소드(구현이 없는 메소드)를 포함할 수 있고, 이 메소드들은 하위 클래스에서 구현해야 합니다.

추상 클래스의 특징

  • 추상 메소드를 포함할 수 있다.
  • 완전한 메소드 구현도 포함할 수 있다.
  • 생성자를 가질 수 있다.
  • 상속을 통해 하위 클래스에서 확장할 수 있다.

예시: 추상 클래스 사용

abstract class Animal {
    String name;
    
    // 추상 메소드
    abstract void sound();
    
    // 일반 메소드
    void sleep() {
        System.out.println(name + " is sleeping");
    }
}

class Dog extends Animal {
    Dog(String name) {
        this.name = name;
    }
    
    @Override
    void sound() {
        System.out.println(name + " barks");
    }
}

인터페이스(Interface)

인터페이스(Interface)는 모든 메소드가 추상 메소드인 특수한 종류의 클래스입니다. 인터페이스는 클래스가 구현해야 할 메소드의 시그니처를 제공하고, 해당 메소드들의 구현을 강제합니다.

인터페이스의 특징

  • 모든 메소드가 기본적으로 추상 메소드이다.
  • 다중 상속을 지원한다.
  • 상수(필드)는 public static final로 선언된다.
  • 추상화 정도가 높다.
interface Animal {
    void sound();
    void sleep();
}

class Dog implements Animal {
    @Override
    public void sound() {
        System.out.println("Dog barks");
    }
    
    @Override
    public void sleep() {
        System.out.println("Dog sleeps");
    }
}

Interface vs Abstract Class

항목InterfaceAbstract Class
추상화 수준100% 추상부분 구현 가능
다중 상속 지원가능불가능
생성자없음있음
상속 형태implementsextends
사용 목적동작 규약 정의공통 로직 + 추상화


3. Stream (데이터 흐름)

Stream은 데이터를 처리하는 일련의 연산을 수행하는 흐름을 의미합니다. Java에서는 Stream API를 통해 데이터를 처리하는 방법을 제공합니다. Stream은 주로 데이터를 필터링, 변환, 집계 등의 작업을 할 때 사용됩니다.

Stream의 흐름
Source (데이터 근원지)에서 데이터를 읽어옵니다.
List, Set, Array

  1. Intermediate Operation (중간 연산): 데이터를 가공하거나 필터링하는 연산입니다.
  • filter(), map(), distinct()
  1. Terminal Operation (최종 연산): 데이터를 최종적으로 처리하거나 집계하는 연산입니다.
  • collect(), forEach(), reduce()
  1. Stream 연산의 특징
  • Lazy Evaluation: 중간 연산은 실제로 필요한 시점까지 실행되지 않습니다.
  • parallelStream()을 사용하여 병렬 처리할 수 있습니다.
List<String> list = Arrays.asList("a", "b", "c");

list.stream()          // Stream 생성
    .filter(s -> s.equals("a"))  // 중간 연산: 필터링
    .forEach(System.out::println);  // 최종 연산: 출력

Stream은 데이터를 병렬로 처리할 수 있는 기능을 제공합니다. 예를 들어, 다음과 같이 parallelStream()을 사용하여 데이터를 병렬로 처리할 수 있습니다.

list.parallelStream()
    .filter(s -> s.length() > 0)
    .forEach(System.out::println);

대규모 데이터나 시간 소모가 큰 연산에서 유용하게 사용할 수 있습니다.

import java.io.FileReader;
import java.io.IOException;
import java.util.stream.Stream;

public class FileService {
    public void readFile(String fileName) throws IOException {
        try (FileReader fr = new FileReader(fileName)) {
            Stream.generate(() -> fr.read())  // Stream을 생성하고 파일을 읽음
                .takeWhile(c -> c != -1)    // 데이터가 없을 때까지 읽음
                .mapToObj(c -> (char) c)    // 문자로 변환
                .forEach(System.out::print);
        }
    }
}

0개의 댓글