ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java의 Nested Classes
    JAVA 2024. 8. 5. 23:37

    자바 프로그래밍 언어에서는 클래스 안에 또 다른 클래스를 정의할 수 있는데, 이를 중첩 클래스라고 합니다. 중첩 클래스는 두 가지로 나뉩니다: 비정적 중첩 클래스(내부 클래스)와 정적 중첩 클래스입니다. 내부 클래스는 외부 클래스의 인스턴스와 관련되어 있으며, 외부 클래스의 멤버에 직접 접근할 수 있습니다. 반면에 정적 중첩 클래스는 외부 클래스의 인스턴스 멤버에 직접 접근할 수 없습니다.

    중첩 클래스를 사용하는 이유는 다음과 같습니다:

    1. 특정 클래스에서만 사용되는 클래스들을 논리적으로 그룹화하여 코드의 가독성과 유지보수성을 높입니다.
    2. 캡슐화를 증가시킵니다. 외부 클래스의 멤버를 private으로 선언하면서 내부 클래스에서는 접근할 수 있게 할 수 있습니다.
    3. 코드의 가독성과 유지보수성을 높입니다.

    다음은 중첩 클래스의 예제입니다:

    public class OuterClass {
        String outerField = "Outer field";
        static String staticOuterField = "Static outer field";
    
        class InnerClass {
            void accessMembers() {
                System.out.println(outerField);
                System.out.println(staticOuterField);
            }
        }
    
        static class StaticNestedClass {
            void accessMembers(OuterClass outer) {
                System.out.println(outer.outerField);
                System.out.println(staticOuterField);
            }
        }
    
        public static void main(String[] args) {
            OuterClass outerObject = new OuterClass();
            OuterClass.InnerClass innerObject = outerObject.new InnerClass();
            innerObject.accessMembers();
    
            StaticNestedClass staticNestedObject = new StaticNestedClass();
            staticNestedObject.accessMembers(outerObject);
        }
    }

    위 예제에서는 OuterClass 안에 InnerClass와 StaticNestedClass를 정의하였습니다. InnerClass는 외부 클래스의 멤버에 직접 접근할 수 있지만, StaticNestedClass는 외부 클래스의 인스턴스 멤버에 접근하기 위해 객체 참조를 사용해야 합니다.

    이 예제는 중첩 클래스의 구조와 사용 방법을 보여줍니다. 중첩 클래스를 사용하면 관련 있는 코드를 한 곳에 모아 두어 가독성과 유지보수성을 높일 수 있습니다.

    로컬 클래스

    로컬 클래스는 메서드, for 루프, 또는 if 문과 같은 블록 안에 정의된 클래스를 의미합니다. 로컬 클래스는 외부 클래스의 멤버와 메서드 내의 지역 변수에 접근할 수 있습니다. 하지만, 이러한 변수들은 final 또는 effectively final이어야 합니다. Java SE 8 이후로, 로컬 클래스는 메서드의 매개변수에도 접근할 수 있게 되었습니다.

    로컬 클래스의 예제를 살펴보겠습니다

    public class LocalClassExample {
        static String regularExpression = "[^0-9]";
    
        public static void validatePhoneNumber(String phoneNumber1, String phoneNumber2) {
            final int numberLength = 10;
    
            class PhoneNumber {
                String formattedPhoneNumber = null;
    
                PhoneNumber(String phoneNumber) {
                    String currentNumber = phoneNumber.replaceAll(regularExpression, "");
                    if (currentNumber.length() == numberLength) {
                        formattedPhoneNumber = currentNumber;
                    } else {
                        formattedPhoneNumber = null;
                    }
                }
    
                public String getNumber() {
                    return formattedPhoneNumber;
                }
            }
    
            PhoneNumber myNumber1 = new PhoneNumber(phoneNumber1);
            PhoneNumber myNumber2 = new PhoneNumber(phoneNumber2);
    
            if (myNumber1.getNumber() == null) {
                System.out.println("First number is invalid");
            } else {
                System.out.println("First number is " + myNumber1.getNumber());
            }
            if (myNumber2.getNumber() == null) {
                System.out.println("Second number is invalid");
            } else {
                System.out.println("Second number is " + myNumber2.getNumber());
            }
        }
    
        public static void main(String... args) {
            validatePhoneNumber("123-456-7890", "456-7890");
        }
    }

    이 예제에서는 validatePhoneNumber 메서드 내에 PhoneNumber라는 로컬 클래스를 정의하여 전화번호를 검증합니다. 이 클래스는 입력된 전화번호에서 숫자만을 추출하고, 길이가 10자리인지 확인합니다.

    익명 클래스

    익명 클래스는 콜백 메서드나 이벤트 핸들러에서 많이 사용됩니다. 이번에는 자바의 Runnable 인터페이스를 사용하여 익명 클래스를 예제로 보여드리겠습니다. Runnable 인터페이스는 스레드에서 실행할 코드를 정의하는데 사용됩니다.

    public class AnonymousClassRunnableExample {
        public static void main(String[] args) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 5; i++) {
                        System.out.println("Hello from anonymous class thread!");
                        try {
                            Thread.sleep(1000); // 1초 대기
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
            thread.start();
        }
    }

    위 예제에서는 Runnable 인터페이스를 구현하는 익명 클래스를 사용하여 새로운 스레드를 생성하고 시작합니다. 이 스레드는 "Hello from anonymous class thread!" 메시지를 1초 간격으로 5번 출력합니다.

    이러한 방식으로 익명 클래스를 사용하면 코드의 가독성을 높이고, 간단한 작업을 쉽게 정의할 수 있습니다.

    'JAVA' 카테고리의 다른 글

    Java Virtual Thread 이론  (0) 2024.04.24
    ObjectMapper와 MapStruct의 성능차이  (0) 2024.04.02
    Java volatile 키워드  (1) 2023.01.05
    AsyncRestTemplate PATCH 메서드 유효하지 않은 요청  (0) 2022.12.30
    Memory leak - Thread dump 활용  (0) 2022.07.10

    댓글

Designed by Tistory.