본문 바로가기
도전기/PE

java 결과 해석

by Qookoo 2025. 4. 13.
반응형



# Java 코드의 출력 결과 및 상세 분석

이 코드의 출력 결과는 **30**입니다. 아래에서 왜 그런지 상세히 분석해 보겠습니다.

## 코드 구조 분석

제시된 Java 코드는 변수의 스코프(scope)와 `this` 키워드의 동작을 잘 보여주는 예제입니다. 코드는 `Test` 클래스, 그 안의 `runIt()` 메소드, 그리고 익명 `Runnable` 객체로 구성되어 있으며, 각 레벨에서 동일한 이름 `a`를 가진 변수들이 정의되어 있습니다.

### 변수 a의 다양한 정의

코드에서 변수 `a`는 여러 레벨에서 서로 다른 값으로 정의되어 있습니다:

1. `Test` 클래스 레벨: `public final int a = 10;`
2. `runIt()` 메소드 내부: `int a = 20;`
3. 익명 `Runnable` 클래스 내부: `public final int a = 30;`
4. `run()` 메소드 내부: `int a = 40;`

### 실행 흐름 분석

코드의 실행 흐름을 단계별로 설명하겠습니다:

1. `main()` 메소드에서 `Test` 클래스의 인스턴스 `c`를 생성합니다.
2. `c.runIt()`을 호출하여 `runIt()` 메소드를 실행합니다.
3. `runIt()` 메소드 내에서:
   - 지역 변수 `a`에 20을 할당합니다.
   - `Runnable` 인터페이스를 구현하는 익명 클래스의 객체 `b`를 생성합니다.
   - 이 익명 클래스는 자체적으로 필드 `a`를 30으로 정의합니다.
   - `b.run()`을 호출하여 익명 객체의 `run()` 메소드를 실행합니다.
4. `run()` 메소드 내에서:
   - 지역 변수 `a`에 40을 할당합니다.
   - `System.out.println(this.a)`를 실행합니다.

## this 키워드의 의미

`System.out.println(this.a)`에서 `this`는 현재 객체, 즉 익명 `Runnable` 객체를 가리킵니다. 따라서 `this.a`는 익명 클래스에 정의된 필드 `a`의 값인 30을 참조합니다.

### 중첩된 스코프와 변수 접근

Java에서 변수는 가장 가까운 스코프부터 검색합니다. `run()` 메소드 내부에서:

1. 단순히 `a`를 참조하면 가장 가까운 지역 변수 `a`(값 40)를 사용합니다.
2. `this.a`를 참조하면 현재 객체(익명 Runnable)의 필드 `a`(값 30)를 사용합니다.
3. 외부 클래스(`Test`)의 필드 `a`(값 10)에 접근하려면 별도의 참조 방식이 필요합니다.

## 변수 섀도잉(Variable Shadowing)

이 코드는 변수 섀도잉의 좋은 예입니다. 동일한 이름의 변수가 다른 스코프에 존재할 때, 내부 스코프의 변수가 외부 스코프의 변수를 '가린다'(shadow)고 합니다. 이로 인해 변수를 참조할 때 어떤 스코프의 변수를 참조하는지 명확하게 지정해야 할 수 있습니다.

## 결론

결론적으로, 코드 실행 시 출력되는 값은 익명 `Runnable` 클래스에 정의된 필드 `a`의 값인 **30**입니다. 이는 `this.a` 표현식이 현재 실행 컨텍스트인 익명 `Runnable` 객체의 필드 `a`를 참조하기 때문입니다. 이 예제는 Java에서 변수의 스코프, 변수 섀도잉, 그리고 `this` 키워드의 동작 방식을 이해하는 데 중요한 개념을 보여줍니다.


외부 클래스(Test)의 필드 a(값 10)에 접근하려면 별도의 참조 방식은?

# 내부 클래스에서 외부 클래스(Test)의 필드 접근 방법

외부 클래스(Test)의 필드 a(값 10)에 접근하기 위해서는 **`Test.this.a`** 형태로 참조해야 합니다. 이 방식은 Java에서 내부 클래스가 외부 클래스의 멤버에 접근할 때 사용하는 표준적인 방법입니다.

## 변수 섀도잉(Variable Shadowing)과 스코프 이해

주어진 코드에서 같은 이름 'a'를 가진 변수가, 서로 다른 스코프에 여러 개 존재합니다:

1. Test 클래스 레벨: `public final int a = 10;`
2. runIt() 메소드 내부: `int a = 20;`
3. 익명 Runnable 클래스 내부: `public final int a = 30;`
4. run() 메소드 내부: `int a = 40;`

이처럼 동일한 이름의 변수가 다른 스코프에 존재할 때 내부 스코프의 변수가 외부 스코프의 변수를 '가린다'(shadow)고 합니다[2]. 이로 인해 단순히 변수명만으로는 어떤 스코프의 변수를 참조하는지 명확하게 지정할 수 없습니다.

## 외부 클래스 참조 메커니즘

내부 클래스에서는 다음과 같은 방식으로 변수에 접근합니다:

1. 단순히 `a`를 사용할 경우 - 가장 가까운 스코프의 변수(run() 메소드의 지역 변수, 값 40)를 참조
2. `this.a`를 사용할 경우 - 현재 객체(익명 Runnable 클래스)의 필드(값 30)를 참조
3. `Test.this.a`를 사용할 경우 - 외부 클래스 Test의 필드(값 10)를 참조[2]

이처럼 `외부클래스명.this.필드명` 형태로 외부 클래스의 인스턴스 참조를 명시적으로 지정함으로써 내부 클래스에서 외부 클래스의 멤버에 접근할 수 있습니다[5].

### 코드 예시

예를 들어, 주어진 코드에서 익명 Runnable 클래스의 run() 메소드에서 외부 클래스 Test의 필드 a에 접근하려면 다음과 같이 수정해야 합니다:

```java
public void run() {
    int a = 40;
    System.out.println(Test.this.a); // 외부 클래스 Test의 필드 a(값 10)에 접근
}
```

## 내부 클래스와 외부 클래스 간의 관계

Java의 내부 클래스는 외부 클래스의 모든 멤버(private 멤버 포함)에 접근할 수 있는 특권을 가집니다[7]. 이는 코드의 캡슐화를 유지하면서도 관련 클래스 간의 긴밀한 상호작용을 가능하게 합니다.

내부 클래스의 인스턴스는 항상 외부 클래스의 인스턴스와 연결되어 있으며, 이 연결을 통해 내부 클래스가 외부 클래스의 멤버에 접근할 수 있는 것입니다[2][9].

## 결론

내부 클래스(또는 익명 클래스)에서 외부 클래스의 필드에 접근하기 위해서는 `외부클래스명.this.필드명` 구문을 사용합니다. 따라서 주어진 예제에서는 `Test.this.a`를 사용하여 Test 클래스의 필드 a(값 10)에 접근할 수 있습니다[2][5][9].



반응형

'도전기 > PE' 카테고리의 다른 글

ER다이어그램을 관계모델로  (0) 2025.03.13
java코드 해석  (0) 2025.03.12
파이썬코드 출력 결과  (1) 2025.03.10
ITIL4.0 7대 원칙  (0) 2025.03.10
코드 리팩토링 유형  (0) 2025.03.07