자바 기본 배우기 -변수에 대해-

1. 변수 종류

 

1-1) 클래스 변수(class variable)

 

클래스 영역에 선언

 

static 키워드를 사용해야함

 

클래스 영역은 어디인데..?

 

class Person {

<클래스 영역>

static int person_count;

}

 

Person 클래스가 메모리에 올라갔을 때 static으로 선언된 클래스 변수인 person_count가 생성

 

현재 위 예시에서 person_count를 초기화하지 않았는데.. 어떤 값으로 초기화될까?

 

자료형의 기본값으로 초기화됨

 

여기서 int형이니까 0으로 초기화됨

 

static int person_count = 0;과 동일함

 

참고로 클래스 변수의 소멸시기는 프로그램 종료시이다.

 

접근 방법은?

 

객체 생성과는 무관하게 (클래스 이름).person_count 식으로 접근

 

>>> 모든 인스턴스가 공유하게 됨

 

 

 

1-2) 인스턴스 변수(instance variable)

 

클래스 영역에 선언

 

클래스 변수와는 다르게 static 키워드를 사용하지 않는다

 

class Person {

<클래스 영역>

//클래스 변수
static int person_count;

//인스턴스 변수
int age;
String name;

}

 

생성 시기는? new라는 키워드에 의해 인스턴스가 생성되었을때

 

당연히 초기화 자동으로 진행

 

int인 age는 0으로 초기화, String인 name은 null로 초기화

 

그리고 인스턴스 별로 생성되는 변수이다. 그래서  내가 생성한 인스턴스마다 변수값이 다르다

 

Yun이라는 인스턴스의 이름과 나이

 

Jeong라는 인스턴스의 이름과 나이는 서로 다른 것처럼

 

하지만 두 클래스의 person_count값은 동일하다

 

소멸시기는, 더 이상 인스턴스를 가리키거나 참조하는 곳이 없을때 GC가 자동으로 제거함

 

 

1-3) 지역변수(local variable)

 

클래스 영역 이외(메소드, 생성자, ... 등등)에 선언된 변수

 

사용하기 전에 초기화가 반드시 필요하다

 

해당 영역이 아닌 외부에서 접근 불가능

 

선언되었을때 생성되며, 해당 선언된 영역을 프로그램이 벗어나는 순간 소멸

 

package com.ssafy.class02;

public class Person {
    //인스턴스 변수
	String name;
	int age;
	String hobby;
	
	public void info() {
		System.out.println("나의 이름은 "+name+"입니다.");
		System.out.println("나이는 "+age+"세, 취미는 "+hobby+"입니다.");
	}
}

 

String name; int age; String hobby;로 선언된 변수들은 인스턴스 변수

 

static이 없으니까

 

package com.ssafy.class02;

public class PersonTest {
	public static void main(String[] args) {
		Person p1;
		System.out.println(p1);
	}
}

 

위 코드는 수행하면 에러가 난다

 

main 메소드 안에 생성된 지역변수 p1은 반드시 초기화하고 사용해야함

 

 

 

null로 초기화하면...

 

 

이러면 메모리 공간은 다음과 같다

 

 

만약 new Person()으로 인스턴스 생성을 한다면?

 

 

Person에 인스턴스 변수인 String name, int age, String hobby 등이 있는데.. 어떻게 접근할까?

 

(인스턴스 이름).(인스턴스 변수) 이런식으로 접근 가능

 

package com.ssafy.class02;

public class PersonTest {
	public static void main(String[] args) {
		Person p1 = new Person();
		
		p1.name = "Yun";
		p1.age = 45;
		p1.hobby = "Programming";
		
		Person p2 = new Person();
		
		p2.name = "Jeong";
		p2.age = 25;
		p2.hobby = "Golf";
		
		System.out.println(p1);
	}
}

 

 

각각 생성된 인스턴스 p1, p2는 자기들만의 고유한 상태를 가진다

 

 

실제로 잘 들어갔는지 확인하고 싶으면 Person에 만들어둔 info() 메소드를 이용

 

메소드 이용 방법은 뭐 (인스턴스 이름).(메소드 이름)이겠지 뭐

 

 

 

2. 클래스 메모리(메소드 메모리)

 

메모리 공간을 크게 stack과 heap으로 나누었지만 사실 더 있다

 

클래스 메모리라는 공간은 클래스로 작성한 코드가 기록되는 공간

 

 

Public class Person { ~ }이라고 작성하면 그 정보가 클래스 메모리에 올라옴

 

instance 변수 name, age, hobby야 인스턴스 생성될때마다 서로 다른 값을 가지니 생성해주겠지만

 

info() 메소드는 인스턴스가 생성될때마다 생성되는 것은 아니다

 

동일한 메소드인데 메모리 낭비겠지

 

클래스 메모리에서 관리해서, 메소드가 필요하면 가져다가 쓴다

 

그래서 메소드 메모리인가보네

 

그리고 static이라고 붙은 클래스 변수도 이 클래스 메모리에 생성된다

 

 

만약 인스턴스를 생성하지 않고도 personCount를 접근해보고 싶다면?

 

System.out.println(personCount);? 당연히 안돼

 

personCount가 뭔데

 

System.out.println(new Person().personCount);? 가능은 하지만...

 

new Person()이라는 인스턴스를 생성하고 나서, 그 인스턴스에서 personCount라는 변수에 접근하게 됨

 

클래스 변수는 인스턴스가 있든 없든간에 이미 클래스 메모리라는 메모리에 올라가 있는 상태이므로, 

 

인스턴스 생성하지 않고도 쓸 수 있어야함

 

System.out.println(Person.personCount);로 (클래스이름).(클래스 변수 이름)으로 접근 가능

 

 

참고로 인스턴스에서 클래스 변수에 접근하면 경고함

 

가능은 하지만 static 방법으로 접근하라고 추천해주는

 

 

 

그리고 클래스 변수의 특징은 모든 인스턴스가 공유한다는 점이다

 

중간에 p1.personCount++하면 어떻게 될까?

 

이 문장을 실행할때는 0을 출력하지만 그 후에 1을 증가시키고, 다시 p2.personCount를 출력하면 1이 된다

 

그리고 p1.personCount를 출력해보면 1이 나올 것이다

 

 

그리고 p1,p2는 메소드 안에서 생성한 지역변수이므로

 

해당 메소드 블록을 벗어나는 순간 p1, p2는 사용 불가능하다

 

 

 

TAGS.

Comments