본문 바로가기

JAVA

[ JAVA ] 정적멤버와 static - 고정된 멤버와 메소드

 

 

정적(static)은 '고정된'이라는 의미를 가지고 있다. 정적 멤버는 클래스에 고정된 멤버로서 객체를 생성하지 않고 사용할 수 있는 필드와 메소드를 말한다. 이들을 각각 정정필드, 정적 메소드라고 한다.

 

 

 

정적 멤버 선언 

 

public class 클래스{
	
    // 정적 필드
    static 타입 필드 [ = 초기값];
    
    //정적 메소드
    static 리턴 타입 메소드( 매개변수선언, ... ) { ... }
}

정적 필드와 정적 메소드를 선언하려면 필드와 메소드 선언 시 static 키워드를 추가적으로 붙이면 된다. 

정적 필드와 정적 메소드는 클래스에 고정된 멤버이므로 클래스 로더가 클래스(바이트 코드)를 로딩해서 메소드 메모리 영역에 저장할 때 클래스별로 관리하게 된다.

따라서 클래스의 로딩이 끝나면 바로 사용할 수 있다.

static을 구현할 경우 메모리 영역에 자리를 차지 하게 되므로 속도가 느릴 수 있다.

필드를 선언할 때 객체마다 가지고 잇어야 할 테이터라면 인스턴스 필드로 객체마다 가지고 있을 필요가 없는 공용 데이터라면 정적 필드로 선언하는 것이 좋다.

 

 

 

예시 1 (정적 필드)

 

public class Calculator {
	
    String color;					// 계산기 별 색깔은 다를 수 있다.
    static double pi = 3.14159;		// 계산기에서 사용하는 파이(π) 값은 동일하다.
}

예를 들어 Calculator 클래스에서 원의 넓이나 둘레를 구할 때 필요한 파이(π)는 Calculator 객체마다 가지고 있을 필요가 없는 변하지 않는 공용데이터이므로 정적 필드로 선언하는 것이 좋다. 그러나 Calculator별로 색이 다르다면 color는 인스턴스 필드로 선언해야 한다.

 

 

 

예시 2 (정적 메소드)

 

public class Calculator {
	
    String color;
    
    public void setColor(String color){
    	
        this.color = color;
    }
    
    public static int plus(int x, int y){
    
    	return x + y;
    }
    
    public static minus(int x, int y){
    	
        return x - y;
    }
}

Calculator 클래서의 덧셈, 뺄셈 기능은 인스턴스 필드를 이용하기보다는 외부에서 주어진 매개값들을 가지고 덧셈과 뺄셈을 수행하므로 정적 메소드로 선언하는 것이 좋다. 그러나 인스턴스 필드인 색깔을 변경하는 메소드는 인스턴스 메소드로 선언해야 한다.

 

 

 

정적 멤버 사용

 

클래스.필드;
클래스.메소드(매개값, ...);

 

 

 

 

예시 3 (정적 멤버 사용)

 

double result1 = 10 * 10 * Calculator.pi;
int result2 = Calculator.plus(10, 5);
int result3 = Calculator.minus(10, 5);

정적 필드와 정적 메소드는 원칙적으로 클래스 이름으로 접근해야 하나 아래와 같이 객체 참조 변수로도 접근할 수 있다.

Calculator myCalcu = new Calculator;
double result1 = 10 * 10 * myCalcu.pi;
int result2 = myCalcu.plus(10, 5);
int result3 = myCalcu.minus(10, 5);

 

 

 

정적 메소드 선언 시 주의사항

 

  • 객체가 없어도 실행된다는 특징 때문에  정적 메소드를 선언할 때는 이들 내부에 인스턴스 필드나 인스턴스 메소드 사용일 불가하다.
  • 객체 자신의 참조인 this 키워드 사용도 불가하다.
  • 정적 메소드에서 인스턴스 멤버를 사용하고자 한다면 객체를 먼저 생성 후 참조 변수로 접근해야 한다.
  • main() 메소드 또한 정적 메소드이므로 객체 생성 없이 인스턴스 필드와 인스턴스 메소드를 바로 사용할 수 없다.