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

정보구니·2021년 12월 27일
0

Java

목록 보기
25/39
post-thumbnail

클래스 변수


  • 인스턴스 생성과 상관없이 메모리 공간에 딱 하나만 존재하는 변수이다.
  • 클래스 내에 선언된 변수 앞에 static 선언을 붙이면 클래스 변수가 된다.
  • 변수가 선언된 클래스의 모든 인스턴스가 공유한다.

class StaticExam00 {
	static int instNum = 0;  // 클래스변수 (static변수)
	
	// 생성자
	StaticExam00 () {
		instNum++;  // 모든 인스턴스가 공유
		System.out.println("인스턴스 생성: " + instNum);
	}
}


public class StaticExam {
	public static void main(String[] args) {
		StaticExam00 ex1 = new StaticExam00();
		StaticExam00 ex2 = new StaticExam00();
		StaticExam00 ex3 = new StaticExam00();
	}
}


// 출력 결과
인스턴스 생성: 1
인스턴스 생성: 2
인스턴스 생성: 3



🔎 클래스 변수 언제 사용할까?

  • 인스턴스 별로 가지고 있을 필요가 없는 변수일 경우 메모리 효율을 위해 클래스 변수로 지정
    - 값의 참조가 목적인 변수
    - 값의 공유가 목적인 변수

    - 예) static double PI = 3.14;






클래스 변수의 접근방법

클래스 변수도 접근 수준 지시자의 규칙을 그대로 적용 받는다.
이때 접근 영역(클래스 내부, 외부)을 기준으로 접근 방법이 크게 두가지로 나뉜다.


🔎 클래스 내부접근

  • 클래스 변수가 선언된 클래스 내에서는 이름만으로 직접 접근이 가능

🔎 클래스 외부접근

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

외부접근의 경우 인스턴스 이름을 통해 접근하는 방법보다, 클래스의 이름을 통해 접근하는 것을 추천한다 !
클래스 이름을 통한 접근의 경우 한눈에 클래스 변수임을 구분 할 수 있기 때문이다.


class StaticExam00 {
	static int num = 0;  // 클래스변수 (static변수)
	
	// 생성자
	StaticExam00 () {
		inside();		
	}
	
	void inside() {
		num++;  // 클래스 내부에서 이름을 통한 접근
		System.out.println("인스턴스 생성: " + num);
	}
}



public class StaticExam {
	public static void main(String[] args) {
		StaticExam00 ex = new 
		
		ex.num++;  // 클래스 외부에서 인스턴스 이름을 통한 접근
		StaticExam00.num++;  // 클래스 외부에서 클래스 이름을 통한 접근
		System.out.println("num = " + StaticExam00.num);		
	}
}


// 출력 결과
num = 3






클래스 변수의 초기화

  • 클래스 변수는 인스턴스 생성 이전에 메모리 공간에 존재한다.
  • 클래스 변수는 생성자 기반의 초기화를 진행하면 안된다. (이 경우 인스턴스 생성시마다 값이 리셋)

class StaticExam01 {
	static int num = 100;  // 클래스 변수의 적절한 초기화 위치
	
	// 생성자
	StaticExam01() {
		num++;  // 인스턴스 생성시마다 값이 리셋
		System.out.println("인스턴스 생성: " + num);
	}
}


public class StaticExam1 {
	public static void main(String[] args) {
		StaticExam01.num -= 15;  // 인스턴스 생성없이 num(클래스변수)에 접근
		System.out.println(StaticExam01.num);
	}
}


// 출력 결과
85











클래스 메소드


  • 클래스 내에 정의된 메소드 앞에 static 선언을 붙이면 클래스 메소드가 된다.
  • 인스턴스 생성 이전부터 접근이 가능하다.
  • 어느 인스턴스에도 속하지 않는다.

class StaticMethodExam00 {
	private int num = 0;
	
	static void showInt(int n) { System.out.println(n); }        // 클래스 메소드 (static 메소드)
	static void showDouble(double n) { System.out.println(n); }  // 클래스 메소드
	
	void setNum(int n) { num = n; }   // 인스턴스 메소드
	void showNum() {  // 인스턴스 메소드
		showInt(num);   // 클래스 내부에서 클래스 메소드 호출
	}
}


public class StaticMethodExam {
	public static void main(String[] args) {
		StaticMethodExam00.showInt(20);  // 클래스 외부에서 인스턴스 이름을 통한 클래스 메소드 호출
		
		StaticMethodExam00 np = new StaticMethodExam00();  // 인스턴스 생성
		np.showDouble(3.15);  // 클래스 외부에서 인스턴스 이름을 통한 클래스 메소드 호출
		np.setNum(75);
		np.showNum();	
	}
}


//  출력 결과
20
3.15
75



🔎 클래스 메소드 언제 사용할까?

  • 외부에 기능을 제공하기 위한 메소드일 경우
  • 인스턴스 변수의 값을 참조하거나 수정하지 않는 메소드일 경우

🔎 클래스 메소드에서 인스턴스 변수에 접근이 가능할까?

  • 클래스 메소드는 인스턴스에 속하지 않으므로 인스턴스 변수에 접근이 불가능하다.
  • 클래스 메소드는 인스턴스 메소드의 호출 또한 불가능하다.

class AA {
    int num = 0;  // 인스턴스 변수
    
    static void addNum(int n) {  // 클래스 메소드
        num += n;  // 이 문장이 유효할까? ➡ 불가능!
    }
}

접근 불가능한 이유를 아는것이 중요하다 !

만약 접근이 가능하다는 가정을 하고 생각해보자.
인스턴스를 3개 만들면 3개의 num이 만들어질 것이다.
이때 addNum 메소드를 호출하면, 어떤 인스턴스의 num값이 증가하는 것일까?
결국 말이 안되는 것임을 알 수 있다.






참고
열혈 자바 ch10 클래스변수
열혈 자바 ch10 클래스 메소드

0개의 댓글