Java 코딩의 고급 주제: 코드 블록, 내부 클래스, 함수형 프로그래밍, API 및 GUI

코드 블록

코드 블록은 클래스의 5가지 구성 요소 중 하나입니다. 다른 구성 요소로는 멤버 변수, 생성자, 메서드 및 내부 클래스가 있습니다.

코드 블록에는 두 가지 유형이 있습니다.

  • 정적 코드 블록 (Static Code Block)
    • 구문: static{}
    • 특징: 클래스가 로드될 때 자동으로 실행됩니다. 클래스는 한 번만 로드되므로 정적 코드 블록도 한 번만 실행됩니다.
    • 용도: 클래스 초기화를 수행합니다. 예를 들어, 정적 변수에 초기값을 할당하는 데 사용됩니다.
  • 인스턴스 코드 블록 (Instance Code Block)
    • 구문: {}
    • 특징: 객체가 생성될 때마다 실행되며, 생성자 실행 전에 호출됩니다.
    • 용도: 생성자와 마찬가지로 객체 초기화에 사용됩니다. 예를 들어, 인스턴스 변수에 초기값을 할당하는 데 사용됩니다.

내부 클래스 (Inner Classes)

내부 클래스는 다른 클래스 내부에 정의된 클래스입니다.

멤버 내부 클래스 (Member Inner Class)

외부 클래스의 일반 멤버처럼 취급됩니다.

객체 생성 구문:

외부클래스명.내부클래스명 참조변수 = new 외부클래스().new 내부클래스();

멤버 내부 클래스에서 외부 클래스의 멤버에 접근하는 특징:

  • 외부 클래스의 인스턴스 멤버 및 정적 멤버에 직접 접근할 수 있습니다.
  • 멤버 내부 클래스의 인스턴스 메서드 내에서 외부 클래스 객체에 접근하려면 외부클래스명.this를 사용합니다.

정적 내부 클래스 (Static Inner Class)

static 키워드로修飾된 내부 클래스로, 외부 클래스 자체에 속합니다.

객체 생성 구문:

외부클래스명.내부클래스명 참조변수 = new 외부클래스.내부클래스();

정적 내부 클래스에서 외부 클래스의 멤버에 접근하는 특징:

  • 외부 클래스의 정적 멤버에 직접 접근할 수 있습니다.
  • 외부 클래스의 인스턴스 멤버에는 직접 접근할 수 없습니다.

지역 내부 클래스 (Local Inner Class)

메서드, 코드 블록 또는 생성자와 같은 실행 블록 내부에 정의된 클래스입니다.


public class Example {
    public static void main(String[] args) {
    }
    public static void methodWithLocalClass() {
        class LocalInner {
            // 지역 내부 클래스 내용
        }
        LocalInner innerObj = new LocalInner();
    }
}
  

익명 내부 클래스 (Anonymous Inner Class)

이름이 없는 지역 내부 클래스의 특별한 형태입니다. 컴파일러가 내부적으로 이름을 할당합니다.

구문:

new 클래스또는인터페이스(인수...) {
    // 클래스 본문 (주로 메서드 재정의)
};

예시:


// 인터페이스 정의
interface Printable {
    void print();
}

// 익명 내부 클래스 사용 예시
Printable printer = new Printable() {
    @Override
    public void print() {
        System.out.println("익명 내부 클래스를 통한 출력");
    }
};

printer.print();
  

특징: 익명 내부 클래스는 본질적으로 해당 클래스 또는 인터페이스의 서브클래스이며, 즉시 해당 서브클래스의 객체를 생성합니다.

용도: 서브클래스 객체를 간편하게 생성하는 데 사용됩니다. 주로 메서드에 객체 인수로 전달될 때 유용합니다.


public class AnonymousDemo {
    public static void processAction(Runnable action) {
        System.out.println("액션 처리 시작...");
        action.run();
        System.out.println("액션 처리 완료.");
    }

    public static void main(String[] args) {
        // 익명 내부 클래스를 사용하여 Runnable 구현
        processAction(new Runnable() {
            @Override
            public void run() {
                System.out.println("작업 수행 중...");
            }
        });

        // 람다 표현식 (더 간결한 형태)
        processAction(() -> System.out.println("람다로 작업 수행 중..."));
    }
}
  

타사에서 제공하는 메서드에 특정 기능을 구현해야 할 때, 해당 메서드가 익명 내부 클래스 객체를 인수로 받는 경우 유용하게 사용할 수 있습니다.

함수형 프로그래밍 (Functional Programming)

이 맥락에서 "함수"는 수학적 함수와 유사하게, 동일한 입력에 대해 항상 동일한 출력을 보장하는 동작을 강조합니다.

람다 표현식 (Lambda Expressions)

JDK 8부터 도입된 문법으로, 함수를 표현합니다. 일부 익명 내부 클래스를 대체하여 코드를 더 간결하고 가독성 있게 만들 수 있습니다.

람다 표현식은 함수형 인터페이스의 익명 내부 클래스만 대체할 수 있습니다.

구문:

(매개변수 목록) -> {
    // 메서드 본문 코드
}

함수형 인터페이스 (Functional Interface)

하나의 추상 메서드만 가지는 인터페이스입니다. `@FunctionalInterface` 어노테이션을 사용하여 이 제약을 명시적으로 확인할 수 있습니다.

람다 표현식 축약 규칙

람다 표현식을 더욱 간결하게 작성하기 위한 규칙입니다.

  • 모든 매개변수의 타입은 생략할 수 있습니다.
  • 매개변수가 하나만 있을 경우, 타입과 괄호 ()를 함께 생략할 수 있습니다. 매개변수가 여러 개일 경우 괄호는 생략할 수 없습니다.
  • 람다 표현식의 본문이 한 줄의 코드로만 구성될 경우, 중괄호 {}를 생략할 수 있습니다. 이 경우, 만약 해당 코드가 return 문이라면 return 키워드도 함께 생략해야 합니다.

메서드 참조 (Method References)

기존 메서드를 람다 표현식 대신 참조하는 기능으로, 코드를 더욱 간결하게 만듭니다.

  • 정적 메서드 참조: 클래스명::정적메서드명. 람다 표현식이 단순히 정적 메서드를 호출하고 매개변수가 일치할 때 사용됩니다.
  • 인스턴스 메서드 참조: 객체명::인스턴스메서드명. 람다 표현식이 특정 객체의 인스턴스 메서드를 호출하고 매개변수가 일치할 때 사용됩니다.
  • 특정 클래스의 메서드 참조: 특정클래스명::메서드명. 람다 표현식이 특정 타입의 인스턴스 메서드를 호출하고, 첫 번째 매개변수가 메서드를 호출하는 객체이고 나머지 매개변수가 메서드의 인수가 될 때 사용됩니다.
  • 생성자 참조: 클래스명::new. 람다 표현식이 객체를 생성하고 매개변수가 일치할 때 사용됩니다.

자주 사용되는 API

String 클래스

문자열 데이터를 캡슐화하고 다양한 문자열 처리 메서드를 제공합니다.

  • 생성자:
    • public String(): 빈 문자열 객체 생성
    • public String(String original): 기존 문자열로 객체 생성
    • public String(char[] chars): 문자 배열로 객체 생성
    • public String(byte[] bytes): 바이트 배열로 객체 생성
  • 주요 메서드:
    • length(): 문자열 길이 반환
    • charAt(int index): 지정된 인덱스의 문자 반환
    • toCharArray(): 문자열을 문자 배열로 변환
    • equals(Object anObject): 문자열 내용 비교 (대소문자 구분)
    • equalsIgnoreCase(String anotherString): 문자열 내용 비교 (대소문자 구분 안 함)
    • substring(int beginIndex, int endIndex): 지정된 범위의 부분 문자열 추출 (endIndex 미포함)
    • substring(int beginIndex): 지정된 인덱스부터 끝까지 부분 문자열 추출
    • replace(CharSequence target, CharSequence replacement): 특정 문자열을 다른 문자열로 대체
    • contains(CharSequence s): 특정 문자열 포함 여부 확인
    • startsWith(String prefix): 특정 문자열로 시작하는지 확인
    • split(String regex): 특정 구분자로 문자열 분할 (문자열 배열 반환)

ArrayList 클래스

가변 크기의 리스트를 제공하는 컬렉션입니다.

  • 생성자:
    • public ArrayList(): 빈 ArrayList 객체 생성
  • 주요 메서드:
    • add(E e): 요소를 리스트 끝에 추가
    • add(int index, E element): 지정된 인덱스에 요소 삽입
    • get(int index): 지정된 인덱스의 요소 반환
    • size(): 리스트의 요소 개수 반환
    • remove(int index): 지정된 인덱스의 요소 삭제 (삭제된 요소 반환)
    • remove(Object o): 지정된 객체를 삭제 (삭제 성공 여부 반환)
    • set(int index, E element): 지정된 인덱스의 요소를 새 요소로 변경 (변경된 요소 반환)

GUI 프로그래밍 (Graphical User Interface Programming)

GUI는 그래픽 사용자 인터페이스를 의미하며, 창, 버튼, 텍스트 필드와 같은 그래픽 요소를 통해 사용자와 상호작용하는 방식입니다. CLI(Command Line Interface)보다 직관적이고 사용자 친화적입니다.

Java의 GUI 프로그래밍 관련 API

  • AWT (Abstract Window Toolkit): 네이티브 GUI 컴포넌트를 제공하며 운영체제의 로컬 창 시스템에 의존합니다.
  • Swing: AWT를 기반으로 하며, 더 풍부한 GUI 컴포넌트를 제공하고 로컬 창 시스템에 덜 의존하는 경량 컴포넌트입니다.
  • 주요 Swing 컴포넌트:
    • JFrame: 최상위 창
    • JPanel: 다른 컴포넌트를 담는 컨테이너
    • JButton: 버튼
    • JTextField: 텍스트 입력 필드
    • JTable: 테이블

간단한 GUI 예시:


import javax.swing.*;
import java.awt.*;

public class SimpleGui {
    public static void main(String[] args) {
        JFrame frame = new JFrame("간단한 GUI");
        frame.setSize(400, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JButton button = new JButton("클릭하세요");
        frame.getContentPane().add(button); // FlowLayout이 기본값

        frame.setVisible(true);
    }
}
  

일반적인 레이아웃 관리자

레이아웃 관리자는 컨테이너 내에서 컴포넌트의 배치 방식을 결정하여 GUI 디자인을 단순화합니다.

  • FlowLayout
  • BorderLayout
  • GridLayout
  • BoxLayout

이벤트 처리

GUI 프로그래밍에서 이벤트 처리는 이벤트 리스너(Event Listener)를 통해 이루어집니다.

  • 주요 이벤트 리스너:
    • ActionListener: 클릭 이벤트
    • KeyListener: 키보드 이벤트
    • MouseListener: 마우스 이벤트

태그: java 코드블록 내부클래스 람다표현식 메서드참조

7월 20일 08:56에 게시됨