TIL/Java

[Java] 인스턴스 변수 vs 클래스 변수

야리니 2022. 1. 7. 22:19
728x90
반응형

클래스 변수란?

지금까지는 인스턴스에 해당되는 '인스턴스 변수'와 '인스턴스 메소드'를 사용했습니다.

 

Person p1 = new Person("문종모", 25, 50000);
BankAccount a1 = new BankAccount(100000);

a1.setOwner(p1);      // a1에 대한 인스턴스 메소드
a1.withdraw(20000);   // a1에 대한 인스턴스 메소드

 

하지만, 인스턴스에 해당되지 않고, 클래스에 해당되는 '클래스 변수'도 존재합니다. 이 둘의 차이점을 정확히 이해해야, 좋은 객체 지향 코드를 작성할 수 있습니다. '클래스 변수'가 무엇인지, '인스턴스 변수'와는 어떻게 다른지, 같은 기능을 두 가지 방식으로 구현해 보면서 알아봅시다.

 

인스턴스 변수 버전

현재는 Person 클래스에 count라는 인스턴스 변수가 있습니다. count는 현재 총 몇 개의 Person 인스턴스가 있는지 보관합니다.

public class Person {
    int count;
}

 

그런데 새로운 Person 인스턴스를 생성할 때마다 각 인스턴스의 count 변수를 바꿔줘야 하는 굉장히 번거로운 작업을 해야합니다.

 

public static void main(String[] args) {
    Person p1 = new Person();
    p1.count++;

    Person p2 = new Person();
    p1.count++;
    p2.count = p1.count;

    Person p3 = new Person();
    p1.count++;
    p2.count++;
    p3.count = p2.count;

    Person p4 = new Person();
    p1.count++;
    p2.count++;
    p3.count++;
    p4.count = p3.count;

    System.out.println(p1.count);
    System.out.println(p2.count);
    System.out.println(p3.count);
    System.out.println(p4.count);
}

 

 

4
4
4
4

 

클래스 변수 버전

이런 문제를 해결할 수 있는 게 바로 클래스 변수입니다. 클래스 변수를 정의하기 위해서는 static이라는 키워드를 붙여주면 됩니다.

public class Person {
    static int count;
}

 

이제 count는 특정 인스턴스에 해당되는 게 아니라, Person 클래스 전체에 해당되는 것입니다. 따라서 count를 부를 때는 대문자로 쓴 클래스 이름을 사용해서 Person.count를 써주면 됩니다.

 

public static void main(String[] args) {
    Person p1 = new Person();
    Person.count++;

    Person p2 = new Person();
    Person.count++;

    Person p3 = new Person();
    Person.count++;

    Person p4 = new Person();
    Person.count++;

    System.out.println(Person.count);
}

 

4

 

그런데 아직도 반복적인 코드가 많습니다. Person.count++를 매번 해줘야 한다는 것인데요. 반복적인 코드는 안 좋은 것이기 때문에 개선시킬 방법이 필요합니다. 새로운 인스턴스를 생성할 때마다 Person.count를 1씩 늘려주고 있습니다. 그러면 아예 생성자에 이 줄을 넣으면 됩니다.

 

public class Person {
    static int count;

    public Person() {
        count++;
    }
}

 

public static void main(String[] args) {
    Person p1 = new Person();
    Person p2 = new Person();
    Person p3 = new Person();
    Person p4 = new Person();

    System.out.println(Person.count);
}

 

4

 

이런 식으로 변수가 클래스 자체에 해당될 때에는 static을 써서 클래스 변수로 만들어주면 된다. 

 

+ 클래스 변수의 용도(22.01.16)

  • 인스턴스에 따라서 변하지 않는 값이 필요한 경우(ex. pi > 이런 경우 final을 이용해서 상수로 선언하는 것이 바람직하다)
  • 인스턴스를 생성할 필요가 없는 값을 클래스에 저장하고 싶은 경우
  • 값의 변경 사항을 모든 인스턴스가 공유해야 하는 경우

 

상수

final을 공부할 때 상수를 보긴 했지만, 상수를 더 상수답게 쓰려면 static과 함께 쓰는 것이 좋다. 상수는 인스턴스에 해당되는 것이 아니며, 여러 복사본 대신 한 값만 저장해두는 것이 맞기 때문입니다.

상수 이름은 보통 모두 대문자로 쓰고, 단어가 여러 개인 경우 _로 구분 짓습니다.

 

public class CodeitConstants {
    public static final double PI = 3.141592653589793;
    public static final double EULERS_NUMBER = 2.718281828459045;
    public static final String THIS_IS_HOW_TO_NAME_CONSTANT_VARIABLE = "Hello";

    public static void main(String[] args) {
        System.out.println(CodeitConstants.PI + CodeitConstants.EULERS_NUMBER);
    }
}

 

5.859874482048838
728x90
반응형