Skip to main content

[Java] 클래스 변수 vs. 인스턴스 변수 vs. 로컬 변수

·3 mins· loading · loading ·
CS Java
Soeun Uhm
Author
Soeun Uhm
problem-solving engineer, talented in grit.
Table of Contents

변수의 종류
#

변수에는 스태틱변수, 인스턴스변수, 지역변수 3가지가 존재한다. 메서드 내부에서 선언된 변수가 지역변수인데, 그 변수는 그 메서드의 중괄호{} 내에서만 유효하다.

class Variables{
    int iv; //인스턴스 변수
    static int cv; // 클래스변수(static 변수)

    void method(){
        int lv = 0; //지역변수 
    }
}

인스턴스 변수(instance variable)
#

클래스 영역에 선언되고, 새로운 인스턴스가 만들어질 때 생성된다. 그래서 인스턴스 변수의 값을 읽어오기 위해서는 새로운 인스턴스를 만들어야 한다. 위의 예시에서 iv 에 접근하려면, 아래 방식처럼 접근해야 한다.

Variables myVariable = new Vairiable();
System.out.println(myVariable.iv);

인스턴스는 독립적인 저장공간을 가지므로, 서로 다른 값을 가질 수 있다. 인스턴스마다 다른 값을 가지는 변수를 인스턴스 변수로 선언한다.

클래스 변수(static variable)
#

클래스변수는 새로운 인스턴스를 만들어도, 모든 인스턴스가 공통된 변수를 사용한다. 한 클래스로 만들어진 모든 인스턴스들이 공통적인 클래스 변수 값을 가진다. 클래스 변수는 인스턴스를 생성하지 않아도 접근가능하다. 클래스이름.클래스변수 식으로 접근가능하다.

System.out.println(Variables.cv);

클래스가 메모리에 로딩될 때 생성되어 프로그램이 종료될 때까지 유지되며, public 을 붙이면 같은 프로그램 내 어디에서나 접근가능하다.

지역 변수(local variable)
#

메서드 내에서 선언되며, 그 메서드 안에서만 사용가능하다. 메서드가 종료되면 소멸되어서 사용이 불가능해진다.

예시
#

public class Application{
    public static void main(String[] args){
        Calculator teacher = new Calculator();
        System.out.println(teacher.add(1,2));
        System.out.println(teacher.result); // 3
        System.out.println(teacher.sharedResult); // 3


        Calculator student = new Calculator();
        System.out.println(student.add(3,4)) // 7
        System.out.println(student.result); // 7
        System.out.println(student.sharedResult); // 7

        System.out.println(teacher.sharedResult); // 7 
        
        System.out.println(Calculator.MADE_DATE); // 1223
    }
}
public class Calculator{
    public static int sharedResult = 0; //클래스 변수
    public int result; // 인스턴스 변수
    public static int final MADE_DATE = 1223; // 상수

    public int add(int input1, int input2){
        result = input1 + input2;
        sharedResult = result;
        return result;
    }
}

위의 코드를 보았을 때, Calculator 클래스 내에 result , sharedResult 변수 2개가 있다. 위의 Application 클래스를 실행시켰을 때, teacher.result 는 3이 나오고, 와 student.result 는 7이 나온다. 같은 result 변수여도, 이것은 인스턴스 변수여서 Calculation 클래스의 인스턴스들이 생길 때마다 새롭게 생겨난다.

그러나 아래 teacher.sharedResult 는 맨 마지막 줄에서 7이 나온다. 왜냐하면 sharedResult 변수는 모든 인스턴스에서 공유하는 변수이기 때문이다. 따라서 student.sharedResult 가 7로 변하면, 인스턴스에 상관없이 Calculator 의 sharedResult 값은 7이 된다. 그 후에 다른 인스턴스가 접근하거나, 혹은 그냥 Calculator.sharedResult 로 값이 변경될 수 있다. 그래서 클래스 변수는 인스턴스.클래스변수 로 접근하는 의미가 없다. 그냥 클래스이름.클래스변수 로 접근하면 된다.

그러면 만약에, 변수가 모든 인스턴스에서 공유할 수 있지만(=클래스 변수), 값은 변경할 수 없게 하려면 ? final 을 사용하면 된다. 이것은 여전히 클래스 변수이므로 클래스이름을 통해 접근가능하지만, 값은 수정할 수 없다. 이것을 상수 라고 한다.

변수의 초기화
#

멤버변수를 초기화 하는 방법은 3가지가 있다.

  1. 명시적 초기화 선언과 동시에 초기화 하는 방법이다. int width = 4; 이렇게 작성한다.
  2. 생성자
  3. 초기화 블럭 복잡한 초기화를 할 때 사용한다.

멤버변수의 초기화 시기와 순서
#

  • 클래스 변수의 초기화 시점 : 클래스가 처음 로딩될 때 단 한번 초기화 된다.
  • 인스턴스 변수의 초기화 시점 : 인스턴스가 생성될 때마다 각 인스턴스 별로 초기화가 이루어진다.
  • 클래스 변수의 초기화 순서 : 기본값 -> 명시적 초기화 -> 클래스 초기화 블럭
  • 인스턴스 변수의 초기화 순서 : 기본값 -> 명시적 초기화 -> 인스턴스 초기화 블럭 -> 생성자

Reference
#

  • Java 의 정석, 3rd Edition
  • 우테코 1주차 피드백

Related

[Java] Enum
·3 mins· loading · loading
CS Java
관련된 상수의 집합인 Enum
[Java] HashSet vs. Arrays contains() 의 시간복잡도 비교
·2 mins· loading · loading
CS Java 자료구조
많이 쓰는 contains() 메서드
[Java] Maven으로 build 하기
·3 mins· loading · loading
CS Java
Maven 에 대해 알아보자