Welcome to Wesley & Harry's Traveling & Programming

IT Program/Java Basic

자바(java) 클래스변수, 인스턴스변수, 지역변수 예시 및 이해

Wesley & Harry 2022. 3. 7. 16:58
반응형

이번 포스팅에선 변수에 대해서 다뤄보도록 하겠습니다.

 

변수

변수에는 세종류가 있습니다. 클래스변수, 인스턴스변수, 지역변수

변수의 종류를 나누는 기준은 변수의 선언된 위치입니다.

  • 지역변수(local variable) : 멤버변수를 제외한 나머지 변수
  • 클래스변수(class variable) : 멤버변수 중 static이 붙은 것
  • 인스턴스변수(instance vatiable) : 멤버변수 중 static이 붙지 않은 것.

우선 아래 코드를 통해 종류를 구분하는 위치를 알아보도록 하겠습니다.

public class javaBasicTheory {
	int wesley;
	static int harry;
	void method() {
		int tistory = 1;
	}

}

int wesley : 인스턴스 변수

static int harry : 클래스변수(static 변수)

int tistroy : 지역변수(메서드 내에 선언)


인스턴스 변수 / 클래스변수 / 지역변수

1. 인스턴스 변수

  • 인스턴스 변수란 클래스 영역에 선언되며, 클래스의 인스턴스를 생성할 때 만들어집니다.
  • 인스턴스 변수의 값을 읽어 오거나 저장하기 위해선 먼저 인스턴스를 생성해야합니다.
  • 인스턴스는 독립적인 공간을 가지므로 서로 다른값을 가질 수 있습니다.

2. 클래스 변수

  • 클래스 변수란 인스턴스변수 앞에 static이 붙은 구조를 말합니다.
  • 인스턴스마다 독립적인 저장공간을 갖는 인스턴스변수와 다르게 클래스 변수는 모든 인스턴스가 공통된 저장공간을 공유하게 됩니다.
  • 한 클래스의 모든 인스턴스들이 공통적인 값을 유지해야 할 경우 클래스변수로 선언해야합니다.
  • 클래스 변수는 인스턴스변수와 달리 인스턴스를 생성하지 않고도 언제라도 바로 사용할 수 있다는 특징이 있으며, '클래스이름.클래스변수'와 같은 형식으로 사용합니다.

3. 지역변수

  • 메서드 내에 선언되어 메서드 내에서만 사용 가능하며, 메서드가 종료되면 소멸되어 사용할 수 없게 된다.
  • for문 while문의 블럭 내에 선언된 지역변수는 지역변수가 선언된 블럭 내에서만 사용 가능하며, 벗어날 시 소멸되어 사용할 수 없다.

표를 통해 정리해보겠습니다. 

변수의 종류 선언위치 생성시기
클래스변수 클래스영역 클래스가 메모리에 올라갈 때
인스턴스변수 인스턴스가 생성되었을 때
지역변수 클래스 영역 이외의 영역 변수 선언문이 수행되었을때

 

아래 코드를 통해 확인해보겠습니다.

package wesley.java.practice.basic;

public class javaBasicTheory {
	public static void main(String[] args) {
		anotherClassName.wesley = 1;
		anotherClassName.harry = 1;
		anotherClassName.tistory = 1;
		System.out.println(anotherClassName.harry);
		anotherClassName kim = new anotherClassName();
		kim.wesley = 1;
		kim.harry = 2;
		kim.tistory = 1;
		kim.method();
	}

	
}
class anotherClassName{
	int wesley; //인스턴스 변수
	static int harry; //클래스 변수
	void method() {
		
		int tistory = 1; //지역변수
		System.out.println("print wesley = " + wesley + " harry" + harry + " tistory" + tistory);
	}
}

해당 코드를 따라치게 되면 많은 오류가 보이는 것을 확인할 수 있습니다.

anotherClassName 클래스에 있는 wesley, tistory는

anotherClassName.wesley / anotherClassName.tistory 로 접근이 불가하다. 인스턴스 변수와 지역변수이기 때문이다.

anotherClassName.harry 는 클래스 변수이기 때문에 이와같은 형태로 접근이 가능하다.

anotherClassName kim = new anotherClassName(); new 연산자를 통해 인스턴스를 생성한다.

kim이라는 명을 통해 접근이 가능해진다.

kim.wesley / kim.harry 는 접근이 가능하다

kim.tistory는 지역변수이기 때문에 접근이 불가능하다.

kim.method()를 통해 지역변수값 1을 선언하고 print 해본다.

 

우선 접근이 불가능한 코드들을 지워보도록 한다.

package wesley.java.practice.basic;

public class javaBasicTheory {
	public static void main(String[] args) {
		anotherClassName.harry = 1;
		System.out.println(anotherClassName.harry);
		anotherClassName kim = new anotherClassName();
		kim.wesley = 1;
		kim.harry = 2;
		kim.method();
	}

	
}
class anotherClassName{
	int wesley; //인스턴스 변수
	static int harry; //클래스 변수
	void method() {
		
		int tistory = 1; //지역변수
		System.out.println("print wesley = " + wesley + " harry" + harry + " tistory" + tistory);
	}
}

해당 코드를 넣어보면 kim.harry = 2; 이곳에 노란줄이 그어져있는것을 확인할 수 있다.

해당 오류를 보면 이렇다

The static field anotherClassName.harry should be accessed in a static way

왜뜨는 것일까. 

그이유는 anotherClassName에 있는 static harry를 클래스 변수인데 인스턴스 변수처럼 사용하였기 때문에 나는 오류입니다.

한마디로 static 변수를 클래스이름을 통한 접근을 한것이 아닌 인스턴스 생성 후 인스턴스를 통해 접근을 했기 때문입니다.

해당 코드를

anotherClassName.harry = 2; 로 바꿔주게 되면 알맞은 표현이 되겠습니다.

최종 정돈된 코드와 결과값을 비교해보며 마치도록 하겟습니다.

차이점을 잘 살펴보도록 합시다.

 

package wesley.java.practice.basic;

public class javaBasicTheory {
	public static void main(String[] args) {
		anotherClassName.harry = 1;
		anotherClassName kim = new anotherClassName(); // kim 인스턴스생성
		anotherClassName kim2 = new anotherClassName(); // kim2 인스턴스생성
		
		// kim.harry는 잘못된 접근방식 / 클래스명.harry 식으로 접근해야함
		// kim.tistory는 접근 불가 tistory는 method()내의 지역변수임
		kim.wesley = 1;
		kim.method();
		// kim.wesley와 kim2.wesley는 다른 인스턴스이므로 서로 다른 독립적 저장공간을 가지며
		// 서로 다른값을 가질 수 있다. 인스턴스변수의 특징.
		kim2.wesley = 10; 
		kim2.method();
		
		//해당 아래 코드는 anotherClassName.harry를 통해 바꾸지 않고 kim.harry를 통해 static 값을 변경해주었다.
		//static harry의 값이 kim인스턴스와 kim2인스턴스의 값에 동일하게 들어간다는 것을 보여주기 위함이다.
		kim.harry = 2;
		
		System.out.println("--------------------------");
		System.out.println("kim.wesley = " + kim.wesley);
		System.out.println("kim.harry = " + kim.harry);
		System.out.println("kim2.wesley = " + kim2.wesley);
		System.out.println("kim2.harry = " + kim2.harry);
	}
}

class anotherClassName{
	int wesley; //인스턴스 변수
	static int harry; //클래스 변수 (static 변수라고도 한다)
	void method() {
		int tistory = 1; //method()의 지역변수
		System.out.println("print wesley = " + wesley + " harry" + harry + " tistory" + tistory);
	}
}

해당 결과값입니다.

변수의 종류와 쓰임새에 대해 많은 도움이 되셨길 바라며 포스팅을 마치도록 하겠습니다.

 

인스턴스 변수는 인스턴스가 생성될 때 마다 생성되므로 인스턴스마다 각기 다른 값을 유지할 수 있지만, 클래스 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로, 항상 공통된 값을 가짐.

해당 코드와 같이 kim.harry의 형태로 쓸수는 있지만 클래스 변수를 인스턴스변수로 오해하기 쉽기 때문에 사용을 왠만하면 하지 않도록 합시다.

반응형