public class Main {
public static void main(String[] args) {
int[] arr = new int[5];
for (int i = 0; i <= arr.length; i++) {
arr[i] = i * 2;
}
System.out.println("arr[3] = " + arr[3]);
}
}
int[] arr = new int[5];길이가 5인 int 배열을 생성한다.
인덱스는 0~4까지 사용 가능.
현재 상태:
arr = [0, 0, 0, 0, 0]
for (int i = 0; i <= arr.length; i++)반복문 시작: 조건이 i <= arr.length다.
arr.length == 5이므로,
i는 0부터 5까지 총 6번 실행됨
i = 0, 1, 2, 3, 4, 5
arr[5]는 존재하지 않는다 (0~4까지 있음)i == 5일 때 arr[5] = 10; 이런 식으로 접근하면 ArrayIndexOutOfBoundsException 발생Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
public class Main {
public static void main(String[] args) {
int x = 10;
if (x > 5)
System.out.println("크다");
System.out.println("조건문 끝");
System.out.println("끝");
}
}
int x = 10;if (x > 5)x > 5 → 10 > 5 → trueSystem.out.println("크다");if 바로 아래 한 줄만 조건문에 포함됨{} 없으므로 크다만 조건문에 속함System.out.println("조건문 끝");System.out.println("끝");크다
조건문 끝
끝
💡 오답을 유도하는 핵심:
if 조건문에{}이 없을 때는 딱 한 줄만 조건에 들어감.
실수로 아래 줄도 조건문 안으로 생각하는 경우가 많음.
public class Main {
public static void main(String[] args) {
int num = 20;
{
int num2 = 10;
num = num2 + 5;
}
System.out.println(num2);
}
}
int num = 20;num은 main 함수 전체에서 사용 가능{ int num2 = 10; ... }이 중괄호 블록은 지역 블록이므로, 여기 안에서 선언된 num2는 밖에서 못 씀
num2는 이 블록 내부에서만 유효함
System.out.println(num2);num2를 접근하려고 함num2는 위 블록 안에서 선언되어 스코프 밖컴파일 오류:
Cannot find symbol - variable num2
변수가 선언된 위치에 따라, 어디까지 그 변수를 사용할 수 있는지를 말해.
| 종류 | 설명 | 예시 사용 가능 위치 |
|---|---|---|
| 클래스 스코프 | 클래스 전체에서 접근 가능 (static 제외) | 모든 메서드 내부 |
| 메서드 스코프 | 해당 메서드 내부에서만 사용 가능 | 지역 변수 등 |
| 블록 스코프 | {} 블록 안에서 선언된 변수 (for, if 등) | 해당 블록 내부 |
public class Main {
public static void main(String[] args) {
if (true) {
int a = 10;
System.out.println(a); // OK
}
System.out.println(a); // ❌ 컴파일 오류 (a는 if블록 안에서만 유효)
}
}
int a = 10; → if 블록 내부 변수System.out.println(a); (if 밖) → a는 이 위치에서 없음public class Main {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
System.out.println(i); // OK
}
System.out.println(i); // ❌ 오류: i는 for문 안에서만 존재
}
}
int i = 0은 for문의 초기식에서 선언됨 → for문의 블록 안에서만 유효public class Main {
static int x = 5;
public static void main(String[] args) {
int x = 10;
System.out.println(x); // 출력값은?
}
}
10
main 안에서 새로 선언된 int x = 10;이static int x = 5;를 가려버림(shadowing)public class Main {
public static void printSum(int a) {
int b = 5;
int a = 3; // ❌ 오류: 변수 a는 이미 파라미터로 존재
System.out.println(a + b);
}
}
a는 이미 파라미터로 선언됨 → 같은 이름의 로컬 변수 선언 불가public class Main {
public static void main(String[] args) {
int sum = 0;
for (int i = 0; i < 3; i++) {
int temp = i * 2;
sum += temp;
}
System.out.println(temp); // ❌ temp는 for문 안에서만 사용 가능
}
}
public class Main {
public static void main(String[] args) {
int a = 5;
{
int a = 10; // ❌ 같은 블록 내에서 변수 이름 중복 선언 불가
}
}
}
public class Main {
public static void main(String[] args) {
int outer = 100;
{
int inner = outer + 50; // OK: 외부 스코프 변수 사용 가능
System.out.println(inner); // 150
}
System.out.println(inner); // ❌ inner는 블록 밖에서 사용 불가
}
}
| 사례 | 변수 접근 가능 여부 |
|---|---|
| 바깥 변수 → 안쪽 블록 | 가능 ✅ |
| 안쪽 변수 → 바깥 블록 | 불가능 ❌ |
| 중첩 블록 안에서 이름 중복 | 불가능 ❌ (같은 스코프 내) |
| 메서드 파라미터와 중복 | 불가능 ❌ |
스코프 문제는 대부분 컴파일 오류 유도 문제
자주 출제되는 패턴:
좋아! 그럼 지금부터 위의 스코프 연습문제 10문제에 대해
하나하나 디버깅 수준으로 상세하게 해설해줄게.
각 줄에서 무슨 일이 일어나는지, 어떤 변수들이 어떤 범위에서 유효한지 모두 설명할게!
public class Main {
public static void main(String[] args) {
int x = 5;
{
int x = 10;
System.out.println(x);
}
}
}
int x = 5; → main() 안에서 x라는 이름의 변수를 선언함 (메서드 스코프)
{ int x = 10; ... } → 같은 스코프 내에 다시 x를 선언하려 함
x가 유효한 상태이므로, 컴파일 에러 발생!❗ 이유:
variable x is already defined in method main(String[])
public class Main {
public static void main(String[] args) {
{
int a = 3;
}
System.out.println(a);
}
}
{ int a = 3; } → a는 이 블록 안에서만 살아있는 블록 스코프 변수System.out.println(a); → 이 줄은 a가 선언된 블록 바깥 → 접근 불가❗ 이유:
a cannot be resolved to a variable
public class Main {
static int value = 100;
public static void main(String[] args) {
int value = 50;
System.out.println(value);
}
}
static int value = 100;main() 안에서 int value = 50;을 새로 선언함50public class Main {
public static void main(String[] args) {
int x = 1;
if (x < 10) {
int y = 5;
}
System.out.println(y);
}
}
int y = 5;는 if 블록 안에서 선언됨 → 블록 스코프System.out.println(y);는 if 밖 → y 접근 불가❗ 이유:
y cannot be resolved to a variable
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
int sum = i * 2;
System.out.println(sum);
}
System.out.println(sum);
}
}
int sum = ... 은 for 블록 안에서 선언됨 → for문 안에서만 유효sum을 출력하려고 하므로 → 접근 불가❗ 이유:
sum cannot be resolved to a variable
public class Main {
public static void main(String[] args) {
int a = 1;
{
int b = 2;
{
int c = 3;
System.out.println(a + b + c);
}
System.out.println(c);
}
}
}
c는 가장 안쪽 블록에서만 유효함System.out.println(c);는 c가 선언된 블록 바깥 → 접근 불가❗ 오류 줄:
System.out.println(c);
❗ 이유:c cannot be resolved to a variable
public class Main {
public static void print(int num) {
int num = 10;
System.out.println(num);
}
}
int num이 이미 선언되어 있음❗ 이유:
variable num is already defined in method print(int)
public class Main {
static int x = 20;
public static void test() {
System.out.println(x);
}
public static void main(String[] args) {
int x = 10;
test();
}
}
main 안의 x = 10은 지역 변수test()는 자신의 지역 x가 없으므로 클래스의 static int x = 20 사용20public class Main {
public static void main(String[] args) {
int a = 1;
int a = 2;
System.out.println(a);
}
}
❗ 이유:
variable a is already defined in method main(String[])
public class Main {
static int x = 10;
public static void main(String[] args) {
x = x + 5; // 클래스 변수 x = 15
{
int x = 3; // 이 x는 지역 변수, 클래스 x를 가림
x = x + 1; // 지역 변수 x = 4
}
System.out.println(x); // 출력되는 것은 클래스 변수 x = 15
}
}
15| 문제 | 정답 | 이유 요약 |
|---|---|---|
| 1 | 컴파일 오류 | 같은 스코프 내에서 변수 이름 중복 선언 |
| 2 | 컴파일 오류 | 블록 밖에서 지역 변수 접근 |
| 3 | 50 | 지역 변수가 클래스 변수 shadowing |
| 4 | 컴파일 오류 | if 블록 바깥에서 y 접근 |
| 5 | 컴파일 오류 | for 블록 바깥에서 sum 접근 |
| 6 | 컴파일 오류 | 중첩 블록 안의 c는 바깥에서 접근 불가 |
| 7 | 컴파일 오류 | 파라미터와 같은 이름 변수 재선언 |
| 8 | 20 | test()는 클래스 변수 x 사용 |
| 9 | 컴파일 오류 | 같은 스코프에서 변수 중복 선언 |
| 10 | 15 | 지역변수 x는 블록 안에서만 유효, 바깥은 클래스 변수 |