프로그램이 커지면 여러가지 이유로 이름이 충돌하게 된다. 이를 해결하기 위해 고안된 것이 유효범위이다.
예제) 변수 선언의 다양한 상황에 따라 출력값을 확인하자.
public class ScopeDemo {
static void a() {
int i = 0;
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
a();
System.out.println(i);
}
}
}
// 0 1 2 3 4 5
// i는 for문 int i로 지역 변수 (local variable)로 선언
public class ScopeDemo2 {
static int i;
static void a() {
//1) 얘를 int i = 0;으로 변경하면 메소드가 끝나면 없어지는 i (지역변수)가 되므로
//출력은 양호
i = 0;
}
public static void main(String[] args) {
//2) int i = 0;으로 바꾼다면 for문을 위한 i가 선언 (지역변수)되므로
//출력은 양호
for (i = 0; i < 5; i++) {
a();
System.out.println(i);
}
}
}
//0 무한루프
// i는 static int i로 전역 변수 (global variable)로 선언
우선 메소드만 놓고 봤을 때 메소드 안에서 선언한 변수는 그 메소드가 실행될 때 만들어지고, 그 메소드가 종료되면 삭제된다.
만약 클래스 아래의 변수와 메소드 아래의 변수가 같은 이름을 가지고 있다면 메소드 아래의 변수가 우선하게 된다. 메소드 내의 변수가 존재하지 않을 때 클래스 아래의 변수를 사용하게 되는 것이다.
즉 클래스 아래에서 선언된 변수는 클래스 전역에 영향을 미치지만 메소드 내에서 선언된 변수는 클래스 아래에서 선언된 변수보다 우선순위가 높다고 할 수 있다.
정적인 유효범위 (static/lexical scope): 메소드 내의 지역변수 또는 지역변수가 없다면 전역변수를 사용한다. 사용되는 시점의 유효범위를 사용하는 것이 아니라 정의된 시점의 유효범위를 사용하는 것이다.
동적인 유효범위 (dynamic scope): 메소드를 불러온 메소드 내의 변수를 사용. 자바에서는 사용하지 않지만, 현대적인 언어들은 이를 채택하고 있다.
인스턴스 자신을 의미하는 키워드.
인스턴스 내의 메소드에서 인스턴스 변수에 접근하기 위해 사용한다.
class C3 {
int v = 10;
void m() {
int v = 20;
System.out.println(v);
System.out.println(this.v);
}
}
public class ScopeDemo9 {
public static void main(String[] args) {
C3 c1 = new C3();
c1.m();
}
}
//
20
10