[JAVA] 클래스 변수와 클래스 메소드

Coastby·2022년 9월 29일
0

LIKELION Back-End School

목록 보기
22/61

변수


변수는 클래스변수, 인스턴스변수, 지역변수 세 종류 있다. 변수의 종류는 변수가 어느 영역에 선언되었는지를 확인하는 것이 중요하다.

멤버변수를 제외한 나머지 변수들은 모두 지역변수이며, 멤버변수 중 static이 붙은 것은 클래스변수, 붙지 않은 것은 인스턴스변수이다.

class Variables {
    int iv;             //인스턴스 변수
    static int ic;      //클래스 변수
    
    void method() {
        int lv = 0;     //지역 변수
    }
    
}

1. 인스턴스변수

클래스 영역에 선언되며, 인스턴스를 생성할 때 만들어진다. 그렇기 때문에 인스턴스 변수의 값을 읽어 오거나 저장하기 위해서는 먼저 인스턴스를 생성해야 한다. 인스턴스는 독립적인 저장공간을 가지므로 서로 다른 값을 가질 수 있다. 인스턴스마다 고유한 상태를 유지해야하는 속성의 경우, 인스턴스 변수로 선언한다.

2. 클래스 변수

클래스 변수는 인스턴스 변수 앞에 static을 붙이기만 하면 된다. 클래스변수는 모든 인스턴스가 공통된 저장공간 (변수)를 공유하게 된다. 한 클래스의 모든 인스턴스들이 공통적인 값을 유지해야하는 속성의 경우, 클래스 변수로 선언해야 한다.

클래스변수는 인스턴스를 생성하지 않고도 언제라도 바로 사용할 수 있다는 특징이 있으며, 클래스이름.클래스변수와 같은 형식으로 사용한다.

클래스가 메모리에 로딩될 때 생성되어 프로그램이 종료될 때까지 유지되며, public을 앞에 붙이면 같은 프로그램 어디서나 접근할 수 있는 전역변수 (global variable)의 성격을 갖는다.

3. 지역 변수

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

Static 변수


💡 static 변수 = 정적변수 = 클래스 변수 = 공용 변수

한 번 메모리에 올려 모든 인스턴스가 공유하는 변수이다.

메모리의 사용

프로그램이 실행되며 클래스와 클래스 멤버들이 method area에 올라간다.

인스턴스가 생성되면서 Heap 영역에 인스턴스가 올라가고 참조변수에 주소값이 대입된다. 인스턴스 변수들도 인스턴스 내에 저장된다.

static 변수의 접근 방법

  • 클래스 내부 접근
    • static 변수가 선언된 클래스 내에서는 이름만으로 직접 접근 가능
  • 클래스 외부 접근
    • private으로 선언되지 않으면 클래스 외부에서도 접근 가능
    • 접근 수준 지시자가 허용하는 범위에서 접근 가능
    • 클래스 또는 인스턴스의 이름을 통해 접근

○ static 변수 활용의 예

(static 변수가 한 번도 쓰이지 않았을 때) 객체가 생성되기 전에 static이 있으면 먼저 메모리를 할당하고 값을 가져온다.

(static 변수가 메모리에 올라와 있다면) 올라온 static 변수를 공유한다.

1. 인스턴트가 몇 개인지 셀 수 있다.

class InstCnt {
    static int instNum;

    InstCnt() {
        instNum++;
        System.out.println("인스턴스 생성  :  " + instNum);
    }
}

public class StaticTest {
    public static void main(String[] args) {
        InstCnt i1 = new InstCnt();
        InstCnt i2 = new InstCnt();
        InstCnt i3 = new InstCnt();
    }
}

//result
인스턴스 생성  :  1
인스턴스 생성  :  2
인스턴스 생성  :  3

2. 인스턴스마다 값이 같은 변수는 static으로 지정하면 메모리를 절약할 수 있다.

class card {
	String kind;  //카드 무늬 - 인스턴스 변수
	int number;  //카드 숫자 - 인스턴스 변수
	static int width = 100;  //카드 폭
	static int height = 250;  //카드 높이
}

3. 인스턴스 별로 가지고 있을 필요가 없는 변수

- 값의 참조가 목적인 변수
- 값의 공유가 목적인 변수
  • 그리고 그 값이 외부에서도 참조하는 값이라면 public으로 선언한다.
class Circle {
	static final double PI = 3.14;
	private double radius;
...
}

Static 메소드


instance methodstatic method (class method)
인스턴스 생성 후, 참조변수.메서드명()으로 호출객체 생성 없이 클래스이름.메서드명()으로 호출
*인스턴스 멤버와 관련된 작업을 하는 메서드인스턴스 멤버와 무관한 작업을 하는 메서드
메서드 내에서 인스턴스 변수 사용이 가능함메서드 내에서 인스턴스 변수 사용이 불가

인스턴스와 관계없는 (인스턴스 변수나 인스턴스 메서드를 사용하지 않는) 메서드를 클래스 메서드 (static method)로 정의한다.
인스턴스 변수를 사용하지 않는다고 해서 반드시 클래스 메서드로 정의해야하는 것은 아니지만 특별한 이유가 없는 한 그렇게 하는 것이 일반적이다.

System.out.println

java.lang.System.out.println(...);
  • System은 java.lang 패키지에 묶여 있는 클래스의 이름
  • 컴파일러가 다음 문장을 삽입해 주므로 java.lang을 생략할 수 있다.
    import java.lang.*;
  • out은 클래스 System의 이름을 통해 접근하므로, 이는 System 클래스의 클래스 변수 이름임을 유추할 수 있다.
  • println은 out이 참조하는 인스턴스의 메소드이다.

main()

public static void main(String[] args) {}
  • main 메서드가 static 인 이유?
    • 인스턴스 생성과 관계없이 프로그램 실행 시 가장 먼저 호출되는 메서드이다.
  • main 메서드가 public인 이유?
    • main 메서드의 호출 명령은 외부로부터 시작되는 명령이다. 단순히 일종의 약속으로 이해해도 괜찮다.

⭐️ 생성자는 static vs non-static?

It's static in the sense that you can invoke it without a callee, but it's non-static in the sense that you have a this reference.
참고 : https://stackoverflow.com/questions/29145700/can-we-say-constructors-are-methods-in-java


정리


  1. 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로사용하는 것에 static을 붙인다.
  2. 클래스 변수는 인스턴스를 생성하지 않아도 사용할 수 있다.
  3. 클래스 메서드는 인스턴스 변수를 사용할 수 없다.
    • 클래스메서드는 인스턴스 생성 없이 호출가능하므로 클래스 메서드가 호출되었을 때 인스턴스가 존재하지 않을 수도 있다.
  4. 메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다.
    • 메서드 호출시간이 짧아지므로 성능이 향상된다. 인스턴스 메서드는 실행 시 호출되어야할 메서드를 찾는 과정이 추가적으로 필요하기 때문에 시간이 더 걸린다.

💡 클래스 변수와 클래스 메서드

  • 클래스의 멤버변수 중 모든 인스턴스에 공통된 값을 유지해야하는 것이 있으면, static을 붙여준다.
  • 작성한 메서드 중에서 인스턴스 변수나 인스턴스 메서드를 사용하지 않는 메서드에 static을 붙일 것을 고려한다.
profile
훈이야 화이팅

0개의 댓글