Skills/Java

Java - static 키워드의 사용

aoaa 2022. 10. 11. 00:04

 얼마전 스터디에서 제가 Static 키워드에 대해 설명하던 도중 잘못알고 있던 부분이 있어 바로 잡으려고 글을 작성했습니다.


1. Static

 Java의 static keyword는 주로 메모리 관리에 사용되는 키워드로 주어진 클래스의 동일 변수나 메서드를 공유하는데 사용이 됩니다. 

멤버(블록, 변수, 메서드, 클래스)가 정적으로 선언되면 해당 클래스의 개체가 생성되기 전(컴파일 타임)에 개체에 대한 참조없이 접근할 수 있습니다.

 

 Java에서 일반적으로 만든 Class는 Static 영역에 생성되고, new 연산자를 통한 객체 생성은 Heap 영역에 저장이 됩니다.

객체 생성 시 Heap 영역의 메모리는 GC의 관리를 받게 되는데, Static 영역에 할당된 메모리는 모든 객체가 공유하는 메로리로 GC의 관리 영역 밖이기 때문에 프로그램 종료까지 메모리에 할당된 채로 존재하여 시스템에 영향을 미치게됩니다.

1.1 Static 변수

public class Human {
	public static final String name = "ROME";
    
    public static void printname() {
    	System.out.pritnln(name);
        }
}

 static을 사용해 여러 객체가 하나의 메모리를 참조하도록 하여(Singleton의 개념) 메모리 낭비를 막을 수 있습니다. 

이 때 클래스의 멤버변수를 상수(final)로 만들고자 할 때, 대문자와 '_'를 조합하여 이름짓고 static에 final을 관례적으로 붙입니다.

 유의할 점은 final 멤버 변수의 정의가 'Constant'인 것이 아니라 한 번만 초기화가 가능하다라는 것이기 때문에 final이 상수를 정의하는 말은 아닙니다. 멤버 변수의 데이터와 그 의미와 용도를 고정시키는 용도라고 이해하면 될 것 같습니다. 

 

1.2 Static 메서드

Static 메서드는 객체 생성없이 호출가능하지만 지양하고 있습니다. 

public class Test {
    private String name1 = "ROME";
    private static String name2 = "SEOUL";
 
    public static void printMax(int x, int y) {
        System.out.println(Math.max(x, y));
    }
         
    public static void printName(){
       System.out.println(name1); // java: non-static variable name1 cannot be referenced from a static context
       System.out.println(name2);
    }
}

 Utility와 관련된 함수들은 여러번 사용되어 static 메서드로 구현하는 것이 적합한데, 대표적으로 java.util.Math가 있습니다.

이 때 static 메서드는 인스턴스 변수를 사용하려고 하면 위처럼 error가 발생합니다.

 

 

 

정리하면

1) 클래스 설계 시, 모든 인스턴스에 공통적으로 사용해야하는 것은 static을 사용

2) static이 붙은 멤버변수는 인스턴스를 생성하지 않고 사용 가능하다.

3) static 메서드는 인스턴스 변수를 사용할 수 없다.

4) 메서드 내에서 인스턴스 변수 사용하지 않는다면 static을 고려해보자.

 

 이펙티브 자바 1장에 나온 내용을 보고 생각이 꼬였지만, 정리하고 나니 이해하기 쉬워졌습니다. 

 

 

 

 

 

 

 

 

참조

'Skills > Java' 카테고리의 다른 글

Java - JDBC Transaction  (0) 2022.10.18
Java - 커넥션 풀과 데이터소스  (0) 2022.10.13
Java - 정적 팩토리 메서드를 고려하는 상황  (1) 2022.10.08
Java - JDBC  (0) 2022.10.04
Java - equals(), hashcode() 메서드의 사용  (0) 2022.10.01