[Java] static 변수와 메소드

smallcherry's techlog·2022년 3월 19일
0

Java

목록 보기
4/10

1. static 변수와 static 메소드는 무엇일까?

일반적인 멤버변수나 메소드들은 해당 클래스의 생성자가 호출될 때(즉, 인스턴스가 생성될 때,) 힙 영역에 그 메모리를 할당받는다. 하지만 static 변수는 인스턴스가 생성되지 않아도 그 전에 별도의 데이터영역에 메모리를 할당 받는다.

한 클래스 당 한 static변수에 관해 한 번만 메모리가 할당되므로, 각 인스턴스들은 같은 static값을 공유하게 된다.

static 메소드도 static 변수와 같은 방식으로 메모리를 할당받는다.

따라서 static변수와 static메소드들은 인스턴스가 생성되지 않아도 클래스 이름으로 호출할 수 있다. 만약 Student라는 클래스에 serialNum이라는 public static변수가 있으면 Student 클래스 외에서 아래와 같이 사용할 수 있다.

System.out.println(Student.serialNum);
Student student1 = new Student();
Student student2 = new Student();

System.out.println(student1.serialNum + " " + student2.serialNum);

// 출력결과는 셋 모두가 같은 값이 나온다!

또, getSerialNum이라는 public static 메소드가 있으면 Student 클래스 외에서 아래와 같이 사용할 수 있다.

Student student1 = new Student(); // 생략 가능!
System.out.println(Student.getSerialNum);

그래서, static변수와 static 메소드들을 일반적인 클래스의 멤버변수와 메소드들와 구분하기 위해, 클래스 변수, 클래스 메소드라고도 부른다. 이와 대조하기 위해 일반적인 멤버변구와 메소드들을 인스턴스 변수, 인스턴스 메소드라고 부른다.

2. static 변수는 어떻게 활용하는 것일까? - 왜 쓰는 걸까

위에서 말했다시피, static변수는 한번 선언되면 모든 인스턴트들이 할당받은 메모리를 공유하여 해당 static변수에 대해 같은 값을 갖게 된다. -말 그대로 클래스 변수, 인스턴스 각각의 변수가 아닌 '클래스'의 변수인 것이다!-

다 같은 값을 가지게 될건데 왜 굳이 클래스변수를 사용해야 하는걸까?

아래 코드는 학생들에게 학번(인스턴스변수)을 인스턴스가 생성되는 순서대로 부여하고자 하기 위해 작성한 코드이다.

package staticex;

public class Student1 {
	public static int serialNum = 1000; // static 변수
	public int studentID;				// 인스턴스변수 학번은 따로 있음
	public String studentName;
	public int grade;
	public String address;
	
	public Student1() {
		serialNum++;
		studentID = serialNum; 
        // 생성자에 이런식으로 클래스 변수를 사용하면 구현할 수 있겠구나~!
	}
	
	public String getStudentName() {
		return studentName;
	}
	
	public void setStudentName (String name){
		studentName = name;
	}
}
package staticex;

public class StudentTest2 {
	public static void main (String args[]) {
		Student1 studentLee = new Student1();
		studentLee.setStudentName("이지원");
		System.out.println(Student1.serialNum);
		System.out.println(studentLee.studentName +" /학번: "+studentLee.studentID);
		
		Student1 studentSon = new Student1();
		studentSon.setStudentName("손수경");
		System.out.println(Student1.serialNum);
		System.out.println(studentSon.studentName + " /학번: "+studentSon.studentID);
	}
}

<출력 결과>

1001
이지원 /학번: 1001
1002
손수경 /학번: 1002

위와 같은 경우처럼, static변수를 잘 활용하면 굳이 main함수에서 더하기 연산을 할 필요가 없이, 인스턴스가 생성되면서 바로 순번이 학번으로 부여되므로 코드가 간결해질 수 있다는 장점이 있다.

3. 클래스 메소드, 변수와 인스턴스 메소드, 변수와의 관계

그렇다면, 클래스 메소드, 변수와 인스턴스 메소드, 변수와의 관계에 대해 알아보자. 무작정 외우지 않고 잘 생각만 한다면 간단한 것 같다.

일단, 클래스 메소드에서 클래스 변수를 사용하는 것은 가능하다. 둘은 같은 메모리 공간에 할당되고, 생성되고 파기되는 시점도 일치하기 때문이다.

클래스 메소드에서 인스턴스 변수를 사용하는 것은 가능할까? 아니다. 이유는 인스턴스 변수는 인스턴스가 생성되어야 비로소 그 저장공간을 할당받지만 클래스 메소드는 그 전에 이미 메모리가 할당되기 때문에 아직 없는 변수를 사용하려는 것이나 마찬가지이기 때문이다. 에러가 날 수밖에 없다.

인스턴스 메소드에서 클래스 변수와 인스턴스 변수를 사용하는 것은 둘다 된다. 클래스 변수는 인스턴스 변수보다 먼저 메모리를 할당받고(존재하고,), 인스턴스 변수는 인스턴스 메소드가 메모리를 할당받는 동시에 메모리를 할당받기 때문이다.

추가로, 클래스 이름으로 클래스 변수와 메소드를 호출하는 것은 가능하고, 권장한다. 인스턴스 이름으로 클래스 변수와 메소드를 호출하는 것 역시 가능하지만 JVM에서 권장하지 않는다. 클래스 이름으로 인스턴스 변수와 인스턴스 메소드를 호출하는 것은 당연히 불가능하고(각 인스턴스 마다 다른 값을 가지기 때문에), 인스턴스 이름으로 인스턴스 변수와 베소드를 호출하는 것은 당연히 가능하다.

profile
Java Developer

0개의 댓글