스코프 연습(람다 대부분,지역 클래스 변수 변경),int =가 불변인건 다른 메서드에서 사용할시 불변이고 같은 클래스의 메서드내는 수정 ok

류한선·2025년 6월 19일

실기연습-2

목록 보기
7/95

좋아! 바로 디버깅 형식으로 한 줄도 빠짐없이 해설해줄게.
우선은 너가 헷갈릴 수 있는 포인트인 스코프, 값 변화, z 변수의 중복 선언을 중심으로 뜯어보자.


📌 전체 코드 다시 보기

public class TrapExample {
    public static void main(String[] args) {
        int x = 10;
        int y = 5;

        {
            int z = x + y;
            x = z * 2;
        }

        int z = x - y;
        System.out.println("x: " + x);
        System.out.println("y: " + y);
        System.out.println("z: " + z);
    }
}

🔍 한 줄씩 흐름 따라가며 해설 (디버깅 모드)


public class TrapExample {

  • 클래스 정의: TrapExample이라는 이름의 클래스를 선언함.
  • 클래스는 Java 프로그램의 기본 단위로, 모든 코드는 클래스 안에서 실행됨.

public static void main(String[] args) {

  • 메인 메서드 진입점: 자바 프로그램의 시작 지점.
  • JVM은 이 main 메서드부터 실행을 시작함.

int x = 10;

  • 변수 선언 및 초기화

    • 정수형 변수 x10을 할당.
  • 현재 상태:

    x = 10

int y = 5;

  • 또 다른 정수형 변수 선언 및 초기화

    • y = 5
  • 현재 상태:

    x = 10
    y = 5

{

  • 새로운 블록 시작

    • 이 블록은 지역 스코프를 형성함.
    • 이 블록 내부에서 선언한 변수는 밖에서 안 보임 (즉, 바깥 스코프에 영향 안 줌)

int z = x + y;

  • 새로 선언된 z블록 내부 지역 변수임.
  • x + y = 10 + 5 = 15
  • 따라서 z = 15

z는 블록 안에서만 존재하고, 블록 밖에서 선언된 z와는 아무런 관련이 없음.


x = z * 2;

  • z = 15z * 2 = 30x = 30
  • 변수 x는 바깥에서 선언된 것이므로 영향 받음.

현재 상태:

x = 30
y = 5
(이 블록 내부의 z = 15 → 이제 곧 사라짐)

}

  • 블록 종료
  • 이 시점에서 int z = x + y;로 선언했던 z는 스코프가 끝나서 소멸됨

int z = x - y;

  • 여기가 중요함!!!
  • 완전히 새로운 z 변수 선언 (바깥 스코프에)
  • x = 30, y = 5 → 30 - 5 = 25
  • 따라서 z = 25

현재 상태:

x = 30
y = 5
z = 25

System.out.println("x: " + x);

  • 출력: x: 30

System.out.println("y: " + y);

  • 출력: y: 5

System.out.println("z: " + z);

  • 출력: z: 25

✅ 최종 출력 결과:

x: 30  
y: 5  
z: 25

🎯 정답: A


✏️ 요약 정리

포인트설명
z 스코프블록 {} 안에서 선언된 z는 블록 밖에서 안 보임.
변수 x블록 안에서 값을 변경해도 바깥 스코프의 x에 직접 영향을 줌.
변수 z 중복 선언블록 안의 z와 블록 밖의 z는 서로 다른 변수임. 이름만 같음.
최종 출력x=30, y=5, z=25

좋아! 바로 이 코드:

public class ScopeTrap {
    static int num = 100;

    public static void main(String[] args) {
        int num = 50;

        if (true) {
            int result = num + ScopeTrap.num;
            System.out.println("result: " + result);
        }

        int result = num * 2;
        System.out.println("num: " + num);
        System.out.println("result: " + result);
    }
}

이걸 한 줄도 빠짐없이, 예제 값이 어떻게 흘러가는지 시각적으로 따라가면서 완전 해부해서 설명할게.


📌 디버깅 해설 시작


public class ScopeTrap {

  • 클래스 이름이 ScopeTrap.
  • 이 안에서 static 변수도 선언되어 있음.

static int num = 100;

  • 이건 클래스 변수(static 필드).
  • ScopeTrap.num으로 언제든 접근 가능.
  • 이 변수는 main 메서드가 시작되기 이전부터 존재함.

현재 상태:

ScopeTrap.num = 100

public static void main(String[] args) {

  • main() 시작 → 자바 프로그램의 시작점

int num = 50;

  • 이건 main 메서드의 지역 변수
  • 이름이 같지만 이 변수는 static 변수(num = 100)를 가림(변수 shadowing)
  • 이제부터 num이라고만 쓰면 → 50이 참조됨

현재 상태:

ScopeTrap.num = 100  ← static 변수 (클래스 전역)
num = 50             ← main 메서드 안의 지역 변수

if (true) {

  • 항상 참이므로 if 블록 안으로 진입

int result = num + ScopeTrap.num;

  • 여기서 핵심은 두 num의 정체를 파악하는 것!
변수설명
num50지역 변수
ScopeTrap.num100클래스(static) 변수

→ 계산: result = 50 + 100 = 150

resultif 블록 안에서만 살아 있는 지역 변수


System.out.println("result: " + result);

  • 출력:
result: 150

🔸 이건 if 블록 안의 result


}

  • if 블록 끝나면서 result (블록 안에 선언된) 사라짐

int result = num * 2;

  • 완전히 새로운 result를 선언함 (바깥에서)
  • num = 50 (지역 변수 그대로) → 50 * 2 = 100

현재 상태:

num = 50
result = 100
(ScopeTrap.num = 100은 여전히 static 변수로 존재)

System.out.println("num: " + num);

  • 출력:
num: 50

System.out.println("result: " + result);

  • 출력:
result: 100

✅ 최종 출력 결과:

result: 150  
num: 50  
result: 100

🎯 정답: C


🧠 요약 정리

포인트설명
static int num = 100클래스 변수. ScopeTrap.num으로 접근
int num = 50지역 변수. static 변수와 이름 같지만 가려짐 (shadowing)
if 블록 안의 result블록 전용 변수
블록 밖의 result별개의 지역 변수

좋아! 이 문제는 정보처리기사 실기에서 충분히 나올 수 있는 수준이고, 자바 문법 중에서도 초보자들이 정말 많이 틀리는 대표적인 주제인:

로컬 클래스에서 외부 지역변수를 사용할 때 발생하는 제한사항 (final 또는 effectively final)

이 부분을 노린 함정 문제야. 지금부터 한 줄도 빠짐없이 완전 해부해서 설명해줄게.


📌 다시 문제 코드 확인 (체크)

public class FinalTrap {
    public static void main(String[] args) {
        int x = 10;
        final int y = 20;

        class Calculator {
            void printSum() {
                System.out.println("x + y = " + (x + y));
            }
        }

        x = 30;

        Calculator calc = new Calculator();
        calc.printSum();
    }
}

지역 클래스(Local Class)나 람다(Lambda)는, 바깥 메서드의 지역 변수를 “읽을 수는 있지만 바꾸면 안 된다.”

  • 일반 메서드에서 가져다 사용하는게 아니라 다른 클래스에서 가져다 쓰는 경우라 문제됨.

✅ 우선 결론: 이 코드는 컴파일 에러가 발생한다.

정답은: C

이제 그 이유를 한 줄씩 디버깅 해설 방식으로 설명해볼게.


🔍 한 줄씩 흐름 따라 해설


public class FinalTrap {

  • FinalTrap이라는 클래스 선언.

public static void main(String[] args) {

  • 자바 프로그램의 시작점. main() 메서드 안에서 모든 실행이 이루어짐.

int x = 10;

  • 지역 변수 x 선언.

  • 현재 상태:

    x = 10

final int y = 20;

  • yfinal 지역 변수로 선언.

  • 즉, 값이 변경 불가하고, Local Class에서 참조 가능

  • 현재 상태:

    y = 20 (final)

class Calculator { ... }

  • Local Class 선언 (지역 클래스)
    → 메서드 안에서 정의되는 클래스는 외부 지역 변수에 접근할 수 있음
    단, 조건이 있음!!

🔥 조건: 지역 클래스(Local Class) 안에서 접근하는 지역 변수는 final 또는 effectively final(값이 변경되지 않은 변수)이어야 함


void printSum() {

  • 클래스 내부 메서드 정의.

System.out.println("x + y = " + (x + y));

  • 문제의 핵심이 여기에 있음!
  • 여기서 xy에 접근하려고 함.

🔸 y: final int y = 20; → OK ✅
🔸 x: int x = 10; → 초기에는 effectively final로 간주될 수 있음
→ 하지만 아래에서 x = 30;으로 값이 바뀐다!

❗ 그러면 x는 이제 effectively final이 아님 → 지역 클래스에서 사용 불가 ❌
컴파일 에러 발생


x = 30;

  • x 값을 변경.
  • 이 시점에서 컴파일러는 이전에 사용된 x를 검사해서 "이거는 final도 아니고 변경도 되었으니까 에러!"라고 판단함.

Calculator calc = new Calculator();

  • 지역 클래스 인스턴스를 생성하는 시도.
  • 그런데 이미 위에서 컴파일 에러로 잡혀서 실행조차 못 감.

calc.printSum();

  • 이 줄은 도달하지도 못함 (컴파일 안 됨)

💥 에러 내용 (실제로 컴파일하면 나오는 에러 메시지 예시)

Local variable x defined in an enclosing scope must be final or effectively final

✅ 최종 결론

출력은 없음 ❌

컴파일 에러 발생 💥


🎯 정답: C


✏️ 요약 정리

항목설명
final int y = 20Local Class에서 접근 OK
int x = 10x = 30값이 변경되었기 때문에 Local Class 안에서 참조 불가
Local Class 규칙외부 지역 변수 참조 시 반드시 final 혹은 변경되지 않아야 함
결과컴파일 에러 발생

🧠 참고: effectively final이란?

자바 8부터는 변수에 명시적으로 final 키워드를 안 써도,
"값을 바꾸지 않으면" → 컴파일러가 `final처럼 간주해줌. 이걸 effectively final이라고 해.

하지만 한 번이라도 값을 바꾸면 → 더 이상 effectively final 아님 → 지역 클래스/람다에서 사용 금지됨.


좋아! 이 문제는 지금까지 우리가 배운 내용을 총정리한 매우 훌륭한 함정 문제야.
이제 바로 디버깅 모드로 한 줄씩 흐름을 따라가며 완전히 해부해서 설명해줄게.


✅ 먼저 결론부터 말하자면:

정답은 A.

staticValue: 100  
instanceValue: 200  
localValue: 10

✔️ 이 코드는 컴파일 에러 없이 정상 실행되고,
✔️ 람다 내부에서 모든 변수에 정상적으로 접근 가능한 상태야.


📌 다시 문제 코드

public class LambdaTrap {
    static int staticValue = 100;
    int instanceValue = 200;

    public void calculate() {
        int localValue = 10;

        Runnable r = () -> {
            System.out.println("staticValue: " + staticValue);
            System.out.println("instanceValue: " + instanceValue);
            System.out.println("localValue: " + localValue);
        };

        // localValue = 20; // (주의: 이 줄은 주석 상태)

        r.run();
    }

    public static void main(String[] args) {
        new LambdaTrap().calculate();
    }
}

🔍 한 줄씩 완전 해설


public class LambdaTrap {

  • 클래스 선언. 이름은 LambdaTrap.

static int staticValue = 100;

  • 클래스(static) 변수 → 클래스 전체에서 공유됨.
  • 어디서든 staticValue로 접근 가능.
  • Runnable 안의 람다식도 이 static 변수에 제약 없이 접근 가능함.

현재:

staticValue = 100

int instanceValue = 200;

  • 이건 인스턴스 변수 (객체가 생성될 때마다 따로 존재)
  • 객체가 생성되면 그 객체 내부에 존재하며, 람다식 안에서도 자유롭게 참조 가능

public void calculate() {

  • calculate() 메서드 실행 시작.

int localValue = 10;

  • 이건 calculate() 메서드 안의 지역 변수
  • 자바에서는 람다식 내부에서 지역 변수를 참조할 수 있지만, 조건이 있음:

🔥 람다 내부에서 참조되는 지역 변수는 final 또는 effectively final이어야 함.

✔️ 여기서는 localValue가 한 번만 할당되고, 이후 절대 변경되지 않으므로 → effectively final
→ 람다에서 참조 가능 ✅


Runnable r = () -> { ... };

  • Runnable은 함수형 인터페이스 → 람다식 정의 가능
  • 이 람다식 내부에서 세 개의 변수에 접근 시도함:

System.out.println("staticValue: " + staticValue);

  • staticValue는 클래스 변수 → 자유롭게 접근 가능 → 문제 없음 ✅
    출력:
staticValue: 100

System.out.println("instanceValue: " + instanceValue);

  • instanceValue는 이 클래스의 인스턴스 변수 → 람다가 그 인스턴스 안에서 실행되므로 접근 가능 ✅
    출력:
instanceValue: 200

System.out.println("localValue: " + localValue);

  • 이건 지역 변수인데,
  • 조건: final이거나 effectively final이면 가능
  • 여기서 localValue = 10; 이후 절대 값이 변경되지 않음 → effectively final으로 인정됨
    → 접근 가능 ✅

출력:

localValue: 10

// localValue = 20; ← 이 줄이 핵심 포인트!

  • 지금은 주석 처리되어 있어서 localValue는 값을 바꾸지 않음.
  • 따라서 effectively final 유지 → 람다 내부 접근 OK

💥 하지만 이 주석을 풀면?

localValue = 20;  // ❌ 값이 바뀌니까 → effectively final 아님 → 컴파일 에러 발생

✔️ 주석이기 때문에 지금은 정상 작동함


r.run();

  • 이제 람다식 실행
  • 위에서 출력한 3줄이 그대로 콘솔에 찍힘

public static void main(String[] args) {

  • main() 실행 시 new LambdaTrap().calculate(); 호출 → 위 모든 흐름이 실행됨

✅ 최종 출력 결과

staticValue: 100  
instanceValue: 200  
localValue: 10

🎯 정답: A


✏️ 요약 정리표

변수 종류변수명접근 가능 여부이유
클래스 변수staticValue✅ 가능static 변수는 어디서든 참조 가능
인스턴스 변수instanceValue✅ 가능람다는 this에 접근 가능
지역 변수localValue✅ 가능값이 안 바뀌어서 effectively final
지역 변수 (값 바꾸면)localValue = 20;❌ 컴파일 에러값이 바뀌면 final 아님

좋아! 이 문제는 자바에서 아주 중요한 개념인 람다식(lambda) vs **익명 내부 클래스(anonymous class)**의 스코프 처리 차이를 다루는 실기 함정 문제야.
이건 진짜 실무에서도 종종 실수하는 부분이라, 이번 기회에 확실히 디버깅 해설 모드로 완전히 이해시켜줄게.


✅ 문제 다시 보기

public class ShadowTrap {
    interface Printer {
        void print();
    }

    public static void main(String[] args) {
        String message = "Outer";

        Printer lambdaPrinter = () -> {
            // String message = "Inner"; // ❌ (1)
            System.out.println("Lambda: " + message);
        };

        Printer anonPrinter = new Printer() {
            // String message = "Inner"; // ✅ (2)
            public void print() {
                String message = "Inner";
                System.out.println("Anonymous: " + message);
            }
        };

        lambdaPrinter.print();
        anonPrinter.print();
    }
}

🧠 핵심 요점 요약 먼저

비교 항목람다식익명 클래스
외부 지역 변수 사용가능 (단, final 또는 effectively final일 때만)가능
같은 이름으로 변수 다시 선언❌ 불가능 (shadowing 안 됨)✅ 가능 (shadowing 허용됨)
내부에서 스코프 분리 여부❌ 외부 메서드와 같은 스코프✅ 완전히 새로운 스코프

🔍 한 줄씩 완전 해설


String message = "Outer";

  • main 메서드의 지역 변수 message 선언
  • 값: "Outer"

람다식 내부:

Printer lambdaPrinter = () -> {
    // String message = "Inner"; // ❌ (1)
    System.out.println("Lambda: " + message);
};

🔹 () -> { ... }람다식

  • 이 람다식 내부에서 message에 접근함
  • 이건 외부의 "Outer" 변수를 참조하는 것임 → OK ✅

📛 그런데 주석 처리된 줄을 보면:

String message = "Inner"; // ❌ 변수 재선언 시도
  • 이 줄이 주석이 아니라면 → 컴파일 에러 발생!

  • 이유:

    • 람다식은 main 메서드와 같은 스코프로 간주됨
    • 즉, message라는 이름을 또 선언하는 건 불가능
    • 이걸 shadowing 금지라고 해

🧠 요약:
람다 안에서는 바깥의 지역 변수 이름과 같은 이름의 변수를 선언할 수 없다

✔️ 하지만 주석 처리돼 있으니 현재 상태에서는 문제 없음

→ 출력:

Lambda: Outer

익명 클래스 내부:

Printer anonPrinter = new Printer() {
    public void print() {
        String message = "Inner";  // ✅ 가능
        System.out.println("Anonymous: " + message);
    }
};
  • 이건 익명 내부 클래스
  • message라는 지역 변수를 print() 안에서 새로 선언

✔️ 이건 전혀 문제 없음
✔️ 왜냐면 익명 클래스는 자체 스코프를 가지기 때문

→ 바깥의 message = "Outer"와는 완전히 별개로 동작함

→ 출력:

Anonymous: Inner

✅ 최종 출력 결과:

Lambda: Outer  
Anonymous: Inner

🎯 정답: A


✏️ 요약 정리

항목설명
람다식 내부에서 message 선언 ❌람다는 외부 메서드와 같은 스코프이므로 중복 선언 불가
람다에서 바깥의 message 사용 ✅effectively final이므로 접근 가능
익명 클래스에서 message 다시 선언 ✅별도 스코프를 가지므로 가능
최종 출력Lambda: Outer, Anonymous: Inner

💡 보너스 퀴즈 (도전할래?)

만약 람다식 안에서 이렇게 선언했다면 어떻게 될까?

String message = "Inner";  // 이 줄이 주석 해제된다면?

정답: ❌ 컴파일 에러 발생!

이유: message는 이미 같은 스코프(main 메서드)에서 존재하므로, 같은 이름으로 재선언 불가!


좋아! 이 문제는 자바에서 람다, 익명 클래스, 변수 캡처의 작동 방식이 실제 스레드(Thread)와 함께 어떻게 움직이는지를 테스트하는 실기 스타일 고급 문제야.

📌 핵심 테마는:

  • 람다식 vs 익명 클래스의 지역 변수 접근 규칙
  • 스레드에서 실행될 때 어떤 값이 캡처되는가
  • 변수가 final 또는 effectively final인지 판단하는 시점
  • 컴파일 에러가 나는 조건

✅ 문제 다시 보기

public class ThreadScopeTrap {
    public static void main(String[] args) {
        int count = 5;

        Runnable r1 = new Runnable() {
            public void run() {
                System.out.println("Anonymous: " + count);
            }
        };

        Runnable r2 = () -> {
            System.out.println("Lambda: " + count);
        };

        // count++; // (주석 처리된 상태)

        new Thread(r1).start();
        new Thread(r2).start();
    }
}

🧠 결론부터 말하자면:

정답은 A 또는 B
(둘 다 맞음. 출력 순서는 스레드 실행 타이밍에 따라 달라지므로 순서는 정해져 있지 않음)

Anonymous: 5  
Lambda: 5

또는

Lambda: 5  
Anonymous: 5

✅ 한 줄씩 완전 디버깅 해설


int count = 5;

  • 지역 변수 count 선언 및 초기화.

  • 현재 상태:

    count = 5
  • count바로 아래 두 Runnable 안에서 참조됨


Runnable r1 = new Runnable() { ... };

  • 익명 내부 클래스(anonymous class) 정의
  • 내부 메서드 run() 안에서 외부 지역 변수 count 사용

익명 클래스는 외부 지역 변수에 접근 가능, 단 조건:

  • 해당 변수는 final 또는 effectively final이어야 함
  • 현재 count는 변경되지 않았으므로 → effectively final 상태 → OK

Runnable r2 = () -> { ... };

  • 람다식 정의
  • 람다 안에서도 count를 참조

✅ 람다도 외부 지역 변수에 접근할 수 있음, 단:

  • 반드시 final 또는 effectively final일 것
  • 현재 count는 값을 바꾸지 않았으므로 → 역시 OK

// count++; // 주석 처리된 상태

  • 주석 처리되어 있기 때문에 count는 변경되지 않음 → effectively final 유지됨
  • 따라서 익명 클래스와 람다 모두 컴파일 에러 없이 동작함

❗ 이 줄을 주석 해제하면 → 아래 참고


new Thread(r1).start();

new Thread(r2).start();

  • 두 Runnable을 각각 Thread로 실행
  • 두 스레드는 병렬로 실행되기 때문에 어떤 출력이 먼저 나올지는 예측할 수 없음

✅ 최종 출력 예시 (순서는 랜덤)

  • 가능성 1:
Anonymous: 5  
Lambda: 5
  • 가능성 2:
Lambda: 5  
Anonymous: 5

✔️ 둘 다 정답 → A, B 모두 맞음


❗ 만약 count++ 주석을 해제한다면?

count++;  // ❌ 지역 변수 값을 변경

이 경우 → count는 더 이상 effectively final이 아님
→ 익명 클래스와 람다 모두에서 사용 불가컴파일 에러 발생!

🔴 컴파일러가 다음과 같은 에러 메시지를 출력:

Local variable count defined in an enclosing scope must be final or effectively final

❌ 둘 다 못 씀 → 정답은: C


✅ 요약 정리표

항목설명
count = 5지역 변수, 변경되지 않음 → effectively final
익명 클래스에서 count 사용✅ 가능
람다식에서 count 사용✅ 가능
출력 순서병렬 스레드 → 순서 보장 X
count++ 주석 해제 시❌ 컴파일 에러 발생 (람다 & 익명 클래스 둘 다)

🎯 정답 정리

상황정답
주석 상태일 때 (count++ 없음)A 또는 B (둘 다 맞음)
주석 해제할 경우 (count++ 있음)C (컴파일 에러)

💡 너가 확실히 알아야 할 핵심 정리

람다와 익명 클래스에서 지역 변수 접근 규칙:

  • 조건: 해당 지역 변수가 final 또는 effectively final일 것
  • ✔️ 읽기만 하는 건 OK
  • ❌ 값을 바꾸면 → 더 이상 "고정된 값"이 아니므로 → 컴파일 에러 발생

좋아! 이 문제는 자바에서 정말 많이 헷갈리는 개념이야.
바로 람다식(lambda)과 익명 클래스(anonymous class)에서의 this가 가리키는 객체가 다르다는 걸 묻는 문제지.


✅ 결론부터 말하자면

정답은: C

Lambda this: ThisTrap  
Anonymous this: ThisTrap$1

이제 그 이유를 한 줄씩 디버깅 해설 방식으로 완전히 해부해서 설명할게.


🔍 코드 구조 다시 보기

public class ThisTrap {
    interface Printer {
        void print();
    }

    public void runTest() {
        Printer lambdaPrinter = () -> {
            System.out.println("Lambda this: " + this.getClass().getSimpleName());
        };

        Printer anonPrinter = new Printer() {
            public void print() {
                System.out.println("Anonymous this: " + this.getClass().getSimpleName());
            }
        };

        lambdaPrinter.print();
        anonPrinter.print();
    }

    public static void main(String[] args) {
        new ThisTrap().runTest();
    }
}

✅ 한 줄씩 완전 해설


public class ThisTrap {

  • 외부 클래스: ThisTrap
  • 이 클래스 안에서 모든 동작이 이루어짐

interface Printer { void print(); }

  • 함수형 인터페이스 선언
  • 람다식과 익명 클래스에서 구현할 대상

public void runTest() {

  • 실행 흐름은 main()runTest()로 이어짐

🔹 람다식 정의

Printer lambdaPrinter = () -> {
    System.out.println("Lambda this: " + this.getClass().getSimpleName());
};
  • this는 과연 누구인가?

💡 람다에서의 this는 enclosing 클래스의 인스턴스 (즉, 바깥 클래스인 ThisTrap)를 가리킨다

  • 이유: 람다는 익명 클래스와는 달리 새로운 클래스 객체를 만들지 않음
  • 따라서 this는 바깥 클래스인 ThisTrap의 인스턴스를 그대로 가리킴

✔️ 결과:

Lambda this: ThisTrap

🔹 익명 클래스 정의

Printer anonPrinter = new Printer() {
    public void print() {
        System.out.println("Anonymous this: " + this.getClass().getSimpleName());
    }
};
  • this는 누구인가?

💡 익명 클래스는 새로운 클래스 객체를 생성한다
→ 즉, ThisTrap$1이라는 이름의 새로운 내부 클래스를 만들고 그 인스턴스를 가짐

  • 따라서 여기서의 this는 익명 클래스 자기 자신을 가리킴
    → 클래스 이름은 컴파일 시 다음과 같이 자동 생성됨:
ThisTrap$1

✔️ 결과:

Anonymous this: ThisTrap$1

✅ 최종 출력 결과

Lambda this: ThisTrap  
Anonymous this: ThisTrap$1

📌 정답: C


✏️ 요약 정리

항목람다식익명 클래스
this가 가리키는 대상바깥 클래스 (ThisTrap)익명 클래스 자신 (ThisTrap$1)
getClass().getSimpleName() 결과"ThisTrap""ThisTrap$1"
클래스 생성 방식바깥 클래스 내부의 코드별도 내부 클래스 객체 생성

💡 한줄 정리:

람다 안의 this는 바깥 클래스
익명 클래스 안의 this는 익명 클래스 자기 자신


🔥 보너스! 한 단계 더 나가자면?

람다에서 thisThisTrap을 가리키니까,
this.runTest()도 가능하고, 바깥의 모든 멤버 변수와 메서드 접근이 자유롭지만,

익명 클래스에서는 this가 자기 자신을 가리켜서
ThisTrap 클래스의 멤버에 접근하려면 ThisTrap.this.someMethod() 이런 식으로 써야 해.


0개의 댓글