Programing Language/Java

[Java] 정적 & 불변 제어자(Static & Final Modifier)

vinedpillar 2022. 6. 27. 16:27

클래스 멤버의 메모리 저장 방식

  • 클래스의 인스턴스가 생성되면 스택 메모리에 변수와 인스턴스가 생성된 힙 메모리의 주소가 생성되며, 힙 메모리에는 인스턴스의 데이터들이 저장됩니다.

  • 클래스의 필드 데이터는 생성된 인스턴스마다 값이 다를 수 있지만, 메서드는 인스턴스가 달라도 같은 기능을 가지게 됩니다.

  • 동일한 기능을 수행하는 메서드 코드가 여러 인스턴스에 중복하여 저장되면 메모리를 불필요하게 낭비하는 셈이 되기 때문에 JVM에서는 이를 메서드 영역(= 클래스 영역) 이라는 별도의 메모리 공간을 나눠 저장하고 있습니다.

  • 또한 이렇게 별도로 저장된 메서드를 호출할 때 인스턴스가 생성되지 않으면 호출될 수 없도록 제한을 걸어놓고 있습니다.

 

 

 

 

정적 제어자(Static Modifier)

  • 정적(static) 제어자는 클래스의 요소를 인스턴스를 생성하지 않아도 사용할 수 있게 만들어주는 제어자입니다.

  • 클래스의 멤버를 정적으로 선언할 경우 데이터를 힙 메모리가 아닌 메서드 영역에 저장하게 됩니다.

  • 때문에 인스터스 생성 없이도 바로 필드나 메서드의 사용이 가능하게 됩니다.
정적 필드 사용 방법

public class 클래스이름 {
    // 정적 필드 선언
    // 초기값 지정 가능
    static 타입 변수이름
    
    // 정적 메서드 선언
    static 리턴타입 메서드이름(매개변수) {
    	메서드 내용
    }
}

 

  • 클래스의 모든 인스턴스가 동일하게 가지고 있어야할 공용적인 필드는 정적 필드로 선언하는 것이 좋습니다.

  • 인스턴스의 필드 값을 매개변수나 연산 값으로 사용하지 않는 메서드는 정적 메서드로 선언하는 것이 좋습니다.
정적 필드와 메서드 선언 예시

// 계산기 프로그램 예시
public class calculator {
    // 인스터스(일반) 필드
    String calculatorName;
    
    // 정적 필드
    static double pi = 3.14159;
    static double euler = 2.71828;
	
    
    // 인스턴스(일반) 메서드
    // 인스턴스 값을 매개로 하기 때문에 일반 메서드로 선언
    void setcalculatorName(String calculatorName) {
    	this.calculatorName = calculatorName;
    }
    
    // 정적 메서드
    static int plus(int x, int y) {
    	return x + y;
    }
    
    // 정적 메서드
    static int minus(int x, int y) {
    	return x - y;
    }
}

 

 

 

 

정적 블록(static block)

  • 정적으로 사용되는 필드 값은 선언과 동시에 초기값을 대입하는 것이 일반적입니다.

  • 하지만 필드값의 초기화 작업이 복잡하다면 정적 블록을 활용할 수 있습니다.

  • 정적 블록은 클래스가 메모리로 로딩될 때 자동으로 실행되며, 선언된 순서대로 실행됩니다.

  • 정적 메서드와 정적 블럭은 인스턴스가 생성되지 않아도 실행되기 때문에 인스턴스가 생성되어야만 값을 사용할 수 있는 인스턴스 필드와 메서드는 사용할 수 없습니다.

  • 마찬가지로 자신의 인스턴스 값을 참조하는 this 키워드도 사용할 수 없습니다.
정적 블럭 사용 방법

static {

	정적 블럭 선언 위치

}

 

 

정적 블럭 사용 예시

public class calculator {
    static String companyCode = "ASO";
    static String productCode = "CAL";
    static String productionDate = "20180328";
    static String serialNumber;
    
    // serialNumber에 20180328CALASO 저장
    static {
    	serialNumber = productionDate + productCode + companyCode;
    }
}

 

 

 

 

불변 제어자(Final Modifier)

  • 불변(final) 제어자는 선언된 클래스나 필드, 메서드가 변경되는 것을 막아주는 제어자입니다.

  • 불변으로 선언된 필드 값은 프로그램 실행 중에는 수정할 수 없습니다.

  • final 필드의 초기값을 선언하는 방법은 2가지 뿐입니다.
    • 필드 선언시 변수와 값을 같이 선언하는 방법
    • 생성자를 통해 초기화 할 때 선언
불변(final) 키워드 사용 방법

public class 클래스이름 {
    // 불변 필드 선언
    final 타입 변수이름 = 초기값;
}

 

불변 제어자 사용 예시

public class Calculator {
    // 불변 필드 선언
    // 초기값 미지정
    final String calculatorName;
    
    // 초기값 지정
    final double pi = 3.14159;
    final double euler = 2.71828;
	
    
    // 컨스트럭터를 통한 필드값 초기화
    public Calculator(String calculatorName) {
    	this.calculatorName = calculatorName;
    }
}

 

  • 추가적으로 불변(final) 예약어는 각 선언된 위치에 따라서 아래의 기능을 가지게 됩니다.
    • 클래스 단위에서 final 제어자가 선언될 경우 상속을 할 수 없게 됩니다.
    • 필드 단위에서 final 제어자가 선언될 경우 값을 변경 할 수 없게 됩니다. 
    • 메서드 단위에서 final 제어자가 선언될 경우 오버라이딩을 할 수 없게 됩니다.

 

 

 

 

상수(Constant)

  • 상수는 설정된 값이 절대 변하지 않으면서 어디서나 쓰일 수 있는 값을 뜻합니다.

  • 상수는 static final 두 예약어를 붙여서 선언합니다.

  • 선언된 상수는 인스턴스 생성 없이 클래스로 접근하여 바로 사용할 수 있습니다.
  • 상수는 모든 문자를 대문자로 쓰고 단어 사이를 언더바 연결하는 방식으로 사용하는 것이 관례입니다.
상수 선언 방법

// 초기값 동시에 선언
static final 타입 상수이름 = 초기값;

// 정적 블럭을 이용한 대입
static final 타입 상수이름;
static {
	상수이름 = 초기값;
}

 

상수 선언 예시

// 구체의 표면적을 저장하는 클래스
public class Sphere {
    static final double PI = 3.14159;
    static final double DIAMETER = 200;
    static final double SURFACE_AREA;
    
    // SURFACE_AREA 초기값 계산 후 선언
    static {
    	SURFACE_AREA = 4 * PI * (DIAMETER / 2) * (DIAMETER / 2);
    }
}

 

댓글수0