JAVA/JAVA

Java | Static 정적 변수 & 정적 메소드

pathas 2020. 1. 28. 22:18

Static 정적 변수 & 정적 메소드


정적 변수(=Class 변수)

변수 앞에 static을 작성해서 사용하며,
정적 변수는 객체를 생성하지 않아도 메모리에 할당됨

변하지 않으면서 프로그램 전체에서 공유하고자 하는 변수가 필요할 때 사용

※ [객체명.정적 변수명] or [클래스명.정적 변수명]으로 정적 변수에 접근 가능

일반적으로는 [클래스명.정적 변수명]을 많이 사용


사용례_정적 변수 / 인스턴스 변수 비교

public class StaticVariable {

    // 정적 변수 index 선언
    static int index = 0;

    // 인스턴스 변수(멤버 변수) insIndex 선언
    int insIndex = 0;

    // index의 값을 1씩 증가시키는 메소드 생성
    public void upIndex() {
        index += 1;
    }

    // insIndex의 값을 1씩 증가시키는 메소드 생성
    public void upInsIndex() {
        insIndex += 1;
    }

    // insIndex의 값을 반환하는 get() 메소드 생성
    public int getIns() {
        return insIndex;
    }

    public static void main(String[] args) {

         // StaticVariable 클래스의 sv1 객체 생성
        StaticVariable sv1 = new StaticVariable();
        sv1.upIndex();    // sv1 객체에서 index 값 + 1
        sv1.upInsIndex();    // sv1 객체에서 insIndex 값 + 1
        int insIndex1 = sv1.getIns();    // sv1의 insIndex 값을 insIndex1 변수에 저장

         // StaticVariable 클래스의 sv2 객체 생성
        StaticVariable sv2 = new StaticVariable();
        sv2.upIndex();    // sv2 객체에서 index 값 + 1
        sv2.upInsIndex();    // sv2 객체에서 insIndex 값 + 1
        int insIndex2 = sv2.getIns();    // sv2의 insIndex 값을 insIndex2 변수에 저장

         // 정적 변수 index 값 출력
        System.out.println(index); // 2

         // 인스턴스 변수 insIndex 값 출력
        System.out.println(insIndex1); // 1
        System.out.println(insIndex2); // 1
    }

}

※ 정적 변수 index의 값은 2가 출력된 반면, 인스턴스 변수는 각각의 객체에 속하는 멤버 변수이기 때문에
insIndex1, insIndex2의 값은 각각 1이 출력됨


정적 메소드(=Class 메소드)

메소드 앞에 static을 작성해서 사용,
정적 메소드 또한 객체를 생성하지 않아도 메모리에 할당됨

※ static 메소드는 인스턴스 변수(멤버 변수)에 접근할 수 없음

※ '정적'이지 않은 변수, 메소드는 인스턴스(일반) 변수, 메소드라고 함


정적 메소드 / 일반 메소드 차이

정적 메소드 일반 메소드
객체를 생성하지 않고 메소드 호출 가능
[클래스명.정적메소드명(~)]
객체를 생성해야 메소드 호출 가능
[객체명.일반메소드명(~)]
바로 메모리에 올라가기 때문에 지속적으로 메모리 공간을 차지함 객체를 생성할 때 4byte의 메모리 공간이 필요
기본적인 기능 특수한 기능

※ 좋은 프로그램을 작성하기 위해서는 정적 메소드와 일반 메소드를 적절하게 사용해야 함

 

※ 정적 메소드 역시 [객체명.정적메소드명(~)]으로 호출할 수 있지만, 일반적으로 잘 사용하지는 않음


사용례_정적 메소드 & 일반 메소드

점수 합계, 평균 계산 프로그램

public class MethodEx {
    // 과목 점수, 정적 메소드를 사용하기 위해서는 정적 변수가 필요함
    static int kor = 89;
    static int eng = 78;
    static int mat = 56;

    // 총점 계산 메소드, 정적 메소드
    static int calcSum() {
        int sum = kor + eng + mat;
        return sum;
    }

    // 일반 메소드
    // 평균 계산 메소드, 과목 수 : 3개
    double calcAvg(int tot) {
        return (double) ((double) tot / 3);
    }

    public static void main(String[] args) {
        // 정적 메소드 사용, 클래스명.메소드명(~)
        int result = MethodEx.calcSum();
        System.out.println(result);        // 223

         // 일반 메소드 사용, 객체 생성 → 객체명.메소드명(~)
         MethodEx me = new MethodEx();
        double avgResult = me.calcAvg(result);
        System.out.println(avgResult);    // 74.33333...
    }
}

Math 메소드

java.lang.Math
자바의 lang 패키지 안에 있는 Math 클래스에 기본적인 수학 메소드들이 저장되어 있음

정적 메소드이기 때문에 객체를 따로 생성하지 않고 Math.메소드명()으로 사용 가능

사용례

public class MathTest {
    public static void main(String[] args) {
        int abs = -500;
         // 삼항 연산자로 절댓값 계산
        abs = (abs < 0)? -abs : abs;
        System.out.println(abs);    // 500

         // Math 클래스의 abs 메소드로 절댓값 계산
        abs = Math.abs(-2500);
        System.out.println(abs);    // 2500

         // Math 클래스의 max 메소드로 최댓값 계산
        int max = Math.max(43, 95);
        System.out.println(max);    // 95
    }
}

※ API문서 참조 단축키 : 클래스 이름을 쓰고 클래스 내부에 커서를 옮긴 뒤 Shift + F2 입력
API에 대해 많이 알면 보다 편리하게 프로그램을 작성할 수 있음


정적 변수와 정적 메소드에 대해 알아보았습니다.

정적 변수와 정적 메소드는 바로 메모리에 할당되기 때문에

과도하게 사용하면 메모리의 낭비 또는 과부화를 초래할 수 있습니다.

따라서 Static은 꼭 필요한 경우에만 작성해야 메모리를 효율적으로 관리할 수 있겠습니다.