[JAVA]유효범위

김주현·2021년 4월 1일
1

유효범위

자바의 변수에는 사용할 수 있는 범위(scope)가 있습니다.
코드를 작성하는 곳이 어디냐에 따라 사용할 수 있는 변수가 달라집니다.

자바에는 다음 세 종류의 변수가 있으며 각자 유효범위가 다릅니다.

  • 지역변수(local variable) : 해당 메소드 안에서만 유효한 변수
  • 전역변수(class variable) : 클래스 전역에 접근할 수 있는 변수
  • 멤버변수(instance variable)

다양한 유효범위들

지역변수 int i를 선언하게 되면 해당 메소드 안에서만 사용할 수 있는 변수가 되기 때문에 for문에 있는 a메소드의 i값은 적용되지 않습니다.

public class ScopeDemo {
	
	static void a() {
		//지역변수 i선언
		//a메소드안에 i값은 해당 메소드 안에서만 사용할 수 있다.
		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

아래 예제를 보면 a메소드안에 i값은 아무것도 선언이 안되어있기 때문에 밖에도 영향을 미칩니다. 따라서 for문에 값이 할당되기 때문에 계속 0이 출력되면서 무한루프에 빠지게 됩니다.

package org.scope;

public class ScopeDemo2 {
	//전역변수 i선언
	static int i;
	
	static void a() {
		//i를 선언하진 않고 할당만했음
		 i=0;
	}
	public static void main(String[] args) {
		//선언은 하지 않고 i라는 값만 할당만했음
		for(i=0; i<5; i++) {
			a();
			System.out.println(i);
		}
	}

}

아래 예제에서는 a메소드에 전역변수를 선언하면서 정상적인 값을 호출하게 됩니다.
지역적인 것이 전역적인 것보다 우선순위가 높습니다.


public class ScopeDemo2 {
	//전역변수 i선언
	static int i;
	
	static void a() {
		//지역변수 i선언
		int i=0;
	}
	public static void main(String[] args) {
		//지역변수 i할당됨
		for(i=0; i<5; i++) {
			a();
			System.out.println(i);
		}
	}

}

결과 :
0
1
2
3
4

아래 예제에서는 b라는 메소드의 지역변수 i=30 값이 출력됩니다.
(만약 지역변수 i=30이 없다면 전역변수 static int i=5가 출력)

public class ScopeDemo6 {
	static int i=5; //전역변수
	
	static void a() {
		int i=10;  //지역변수
		b();
	}
	
	static void b() {
		int i=30;
		//b라는 메소드의 지역변수 i의 값 30호출
		System.out.println(i);
	}	
	public static void main(String[] args) {
		int i=1;
		a();
	}
}

결과:
30

인스턴스의 유효범위

메소드 m에서 전역변수와 이름이 같은 지역변수를 선언하고나서 v를 그대로 출력하면 우선순위가 높은 지역변수가 호출됩니다. 지역변수가 아닌 전역변수를 호출하고 싶으면 뒤에 this를 붙입니다. this가 붙으면 그 객체에 대한 전역 유효범위를 의미합니다.

class C{
	int v=10;
	void m() {
		int v=20;
		//지역변수 v=20 값이 호출됨
		System.out.println(v);
		//전역변수 v=10값이 호출됨
		System.out.println(this.v);
	}
}



public class ScopeDemo7 {

	public static void main(String[] args) {
		//C라는 클래스의 인스턴스를 c1이라는 변수에 담겠다.
		C c1=new C();
		c1.m();
	}

}

this를 이용해 전역변수 접근

class Calculator{
	static double PI=3.14;
	int left,right;
	
	public void setOperands(int left,int right) {
		//this.변수는 전역변수를 나타내며 오른쪽의 left는 지역변수를 나타냅니다.
		this.left=left;
		this.right=right;
	}
	public void sum() {
		System.out.println(this.left+this.right);
	}
}

public class CalculatorDemo1 {
	public static void main(String[] args) {
		Calculator c1=new Calculator();
		System.out.println(c1.PI);
		
		Calculator c2=new Calculator();
		System.out.println(c2.PI);
		
		System.out.println(Calculator.PI);
	}

}

결과:
3.14
3.14
3.14

this. 없어도 표현가능

뒤에 this없이도 자바에서는 전역변수 left,right가 있는지 없는지 찾아내서 사용합니다.

class Calculator{
	static double PI=3.14;
	int left,right;
	
	public void setOperands(int _left,int _right) {
		//this.변수는 전역변수를 나타내며 오른쪽의 left는 지역변수를 나타냅니다.
		//뒤에 this안붙여도 자바에서 전역변수의 left와 right가 있는지 찾아내기 때문에 아래방법도 옳바른표현이다.
		left=_left;
		right=_right;
	}
	public void sum() {
		System.out.println(this.left+this.right);
	}
}

public class CalculatorDemo1 {
	public static void main(String[] args) {
		Calculator c1=new Calculator();
		System.out.println(c1.PI);
		
		Calculator c2=new Calculator();
		System.out.println(c2.PI);
		
		System.out.println(Calculator.PI);
	}

}

1개의 댓글

comment-user-thumbnail
2021년 5월 24일

1) public static main 함수에서 사용되는 변수는 static형 전역변수만 가능한 걸까요?
아니면, dynamic형 전역변수도 this를 이용해서 접근 할 수 있을지 궁금하네요.

2) static이 붙지 않은 함수는 static이 붙던 안붙던 전역변수는 다 건들 수 있을까요?

3) this 생략 가능한 경우는, 함수 내에 전역변수와 같은 이름의 지역변수를 사용하지 않을 때. 하지만, 코드의 가독성을 위해 this는 반드시 쓰는게 좋겠습니다.

답글 달기