Java 유효범위

별의개발자커비·2023년 2월 10일
0

Java

목록 보기
21/66
post-thumbnail

1. 유효범위

(1) "프로그램이 커지면 여러 가지 이유로 이름이 충돌하게 된다. 이를 해결하기 위해서 고안된 것이 유효범위라는 개념이다. 흔히 스코프(Scope)라고도 부른다."

package org.opentutorials.javatutorials.scope;
 
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
  • 반복문이 호출될 때마다 변수 i의 값이 0이 되기 때문에 이 반복문은 무한 반복에 빠지게 될까?
  • NO!
  • 내부 변수의 값이 그 외부에 영향을 미치지 않는다. a()에 의해 i=0이 되지 않고 원래대로 for 반복문이 i가 1씩 커지며 진행된다.

2. 전역변수, 지역변수

전역변수로 된 코드

package org.opentutorials.javatutorials.scope;
 
public class ScopeDemo2 {
    static int i;
     
    static void a() {
        i = 0;
    }
 
    public static void main(String[] args) {
        for (i = 0; i < 5; i++) {
            a();
            System.out.println(i);
        }
    }
 
}

전역변수(global variables)

static int i; // 선언 -> 클래스 내 모든 메소드, for문 즉, 모든 {} 안에서 접근할 수 있는 전역변수가 되는 것
static void a(){ 
	i=0; // 선언 아닌, 할당만 즉, i는 메소드 a() 안에서 생성된 변수가 아니니 메소드 밖에서도 작동함
}

지역변수(local variables)

static void a() { 
	int i = 0; // int i 라는 변수는 메소드 a()안에서 생성된 변수니까 이 메소드 안에서만 작동하는 것 -> 해당 중괄호 안에서만 작동함
}

* 전역변수인 이 경우는 왜 i=0이 작동할까?

static void a(){
i=0;

* 여기에 int 붙여주는 경우들도 i=0 작동 안하게 할 수 있음

package org.opentutorials.javatutorials.scope;
 
public class ScopeDemo2 {
    static int i;
     
    static void a() { // i에 int 붙여준다는 건 i가 for문 {} 안에서만 유효한 지역변수가 된다는 뜻
        i = 0;
    }
 
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) { // i에 int 붙여준다는 건 i가 for문 {} 안에서만 유효한 지역변수가 된다는 뜻 -> 밖에서는 작동 안 함
            a();
            System.out.println(i);
        }
    }
 
}

3. 다양한 유효범위

package org.opentutorials.javatutorials.scope;
 
public class ScopeDemo4 {
    static void a(){
        String title = "coding everybody";
    }
    public static void main(String[] args) {
        a();
        System.out.println(title);
    }
}
  • 위 코드는 오류가 발생할 것이다. title은 메소드 a에서만 유효하기 때문이다.
package org.opentutorials.javatutorials.scope;
 
public class ScopeDemo6 {
    static int i = 5;
 
    static void a() {
        int i = 10;
        b();
    }
 
    static void b() {
        System.out.println(i);
    }
 
    public static void main(String[] args) {
        a();
    }
}
  • 위의 예제는
    메소드 a가 메소드 b를 호출하고 있는데
    메소드 b에는 변수 i의 값이 존재하지 않는다.
    이 상태에서 메소드 a를 호출하면 _
  1. 메소드 b에서 System.out.println(i)를 했을 때 클래스 변수가 사용될까?
  2. 메소드 b를 호출한 메소드 a의 지역 변수 i가 사용될까?

답은 1 클래스 변수: 메소드 내(b)에서 지역변수가 존재하지 않는다면 그 메소드가 소속된 클래스의 전역변수를 사용하게 된다.

정리

  1. main 메소드부터 확인한다 -> a 메소드를 호출하고 있다.
  2. a 메소드 확인한다 -> a메소드 지역 내에서 i=10을 할당한다. -> b 메소드를 호출한다.
  3. b 메소드 확인한다 -> i의 값을 출력한다.
  4. 출력값 = "지역변수(b 메소드 내 할당한) i의 값"이거나 "전역변수(static int i = 5) i의 값" 둘 중 한 쪽이다!
  5. "지역변수의 값"과 "전역변수의 값" 모두 존재하는 경우 -> 지역변수의 값이 출력됨.
    "지역변수의 값" O / "전역변수의 값" X -> 지역변수의 값 출력.
    "지역변수의 값" X / "전역변수의 값" O -> 전역변수의 값 출력.
    "지역변수의 값" O / "전역변수의 값" O -> 지역변수의 값 출력.
    둘 다 없으면 -> Error🤗

즉, b 메소드의 유효범위는 "b 자기 자신(b 지역 변수)"이거나 "전역 변수" 둘 중 한 쪽 범위에서 접근이 가능하다!
b 메소드를 누가 호출하든지 상관이 없다.

✓지역변수와 전역변수가 중첩이 될 때의 장점
1. 전역변수는 모든 메소드나 지역변수에서 공통적으로 사용할 수 있는 기본값이 된다.
2. 특정 지역변수 내에서만 선언한 변수(i)의 값을 변경하고 싶을 때 변경이 가능하다.(지역변수 우선순위)
( 출처 유튜브 댓글 https://youtu.be/xqPccJqA8kg 작성자 레이유)

4. 인스턴스의 유효범위 this

package org.opentutorials.javatutorials.scope;
 
class C {
    int v = 10;
 
    void m() {
        int v = 20;
        System.out.println(this.v);
    }
 
public class ScopeDemo7 {
 
    public static void main(String[] args) {
        C c1 = new C();
        c1.m();
    }
}
  • this를 붙이는 이유
    : 변수의 이름이 같을 때 , 전역변수 global varieble 과 지역변수local를 구분하기 위해서
  • this 가 붙어있는 것은 전역변수.
  • 없는 것은 지역 변수.

** 전역변수에 의존한다는 것은 이 메소드가 다른 완제품의 부품으로서 사용될 수 없다는 의미다. 객체지향 덕분에 좀 더 안심하고 전역변수를 사용하게 되었지만, 객체도 크기가 커지면 관리의 이슈가 생겨난다. 객체지향 프로그래밍에서도 가급적이면 전역변수의 사용을 자제하는 것이 좋고, 동시에 단일 객체가 너무 비대해지지 않도록 적절하게 규모를 쪼개는 것도 중요하다.

0개의 댓글