-
[Java] Static 과 Final☕️ java 2023. 3. 3. 19:27
📌 Static
Java에서 Static 키워드를 사용한다는 것은 메모리에 한번 할당되어 프로그램이 종료될 때 해제되는 것을 의미
- GC가 관리 ❌
- 일반적으로 만든 Class는 Static 영역에 생성
- new 연산을 통해 생성한 객체는 Heap 영역에 생성
📖 GC
- Heap 영역의 메모리는 GC를 통해 수시로 관리받는다.
- 하지만 Static 키워드를 통해 Static 영역에 할당된 메모리는 객체가 공유하는 메모리라는 장점이 있지만 GC의 관리 영역 밖이다.
Static을 자주 사용하면 프로그램이 종료될 때까지 메모리가 할당된 상태로 존재한다.
- 자주 사용시 문제가 될 수 있다.
📌 Static 변수
- Static 변수는 클래스 변수이다.
- 객체를 생성하지 않고도 Static 자원에 접근이 가능하다.
💡 Static 변수 - 메모리에 고정적으로 할당되며, 프로그램이 종료될 때 해제되는 변수
- 여러 객체가 해당 메모리를 공유
- why❓ : static변수가 메모리에 한반 할당되기 때문에
예시
public class Person { // 100명의 Person 객체 생성시 같은 값을 갖는 메모리가 100개나 중복되어 생성 private String name = "beomsic"; // 여러 객체가 하나의 메모리를 참조해 메모리 효율이 높아진다. // final 키워드를 통해 변하지 않는 상수의 값으로 만든다. private static final String name = "beomsic"; }
- static은 상수의 값을 가지는 경우가 많다.
- 일반적으로 static 변수는 public 및 final과 함께 사용
- public static final
⚠️ 자바의 변수
- 자바에서 변수는 클래스 변수, 인스턴스 변수, 지역 변수가 있다.
- 종류를 결정짓는 요소 - ‘변수가 선언된 위치’
class test { int a; // 인스턴스 변수 static int b; // 클래스 변수 void method() { int c; // 지역 변수 } }
📖 인스턴스 변수- 인스턴스가 생성될 때 생성 ( 생성 시마다 새로운 변수가 생성 )
- 인스턴스 변수의 값을 읽거나 저장하기 위해서는 인스턴스를 먼저 생성해야 한다.
- 인스턴스 별로 다른 값을 가질 수 있다.
📖 클래스 변수- 인스턴스 변수에 static을 붙이면 된다.
- 클래스 변수는 인스턴스 변수와 달리 모든 인스턴스가 공통된 값을 공유한다.
- 클래스가 로딩될 때 생성된다.
📖 지역 변수- 메서드 내에서 선언되어 메서드 내에서만 사용할 수 있는 변수이다.
📌 Static 메소드
Static method는 객체의 생성 없이 호출이 가능하다.
- 객체에서 호출이 가능하지만 지양한다.
❗일반적으로 유틸리티 관련 함수들은 여러 번 사용된다 - static 메서드로 구현하는 것이 적합
- 대표적인 Util Class - java.util.Math
⚠️ 정적 메소드 사용 시 주의점
- 정적 메소드를 사용하기 위해 필요로 하는 인자는 모두 외부에서 주입해야 한다.
- 정적 메소드 안에는 클래스의 인스턴스 필드를 사용할 수 없다.
- static은 프로그램 시점에 메모리에 올라가기 때문
- 그 시점에 객체의 인스턴스 필드가 초기화되지 않았다면 문제가 발생
- 따라서, 정적 메소드 안에는 정적 변수만 사용할 수 있다.
- static 메소드에서 접근하기 위한 변수는 반드시 static 변수..!
🆚 Static 장 / 단점
장점
- 고정 메모리
- 접근 속도가 빠르다.(미리 메모리에 올라와 있기 때문)
- Static 영역에 할당되어 모든 객체가 공유하여 하나의 멤버를 어디서든지 참조할 수 있다.
단점
- 메모리 문제
- 미리 메모리를 할당받기 때문에 무분별하게 static을 사용할 경우 메모리 낭비
- 동시성 문제
- thread-safe 하지 않다.
- 모든 스레드에서 static 필드를 공유하기 때문
🧑🏻💻 예시
public class TestClass { int count = 0; public TestClass() { this.count++; System.out.println(this.count); } } public class Main { public static void main(String[] args) { TestClass t1 = new TestClass(); TestClass t2 = new TestClass(); } }
결과
1 1
- t1, t2 객체를 생성 시 생성자에서 각각 count 값을 1씩 증가해도 t1, t2의 count 변수는 서로 다른 메모리를 가리키고 있다.
Static 변수를 사용
public class TestClass { static int count = 0; public TestClass() { this.count++; System.out.println(this.count); } } public class Main { public static void main(String[] args) { TestClass t1 = new TestClass(); TestClass t2 = new TestClass(); } }
결과
1 2
- static으로 count 변수를 설정했기 때문에 같은 메모리 주소를 바라본다.
📌 final
💡 final 키워드는 ‘마지막의’ 또는 ‘변경될 수 없는’의 의미를 가지며 거의 모든 대상에 사용될 수 있다.
- 변수, 메서드, 클래스
final 키워드는 어떤 곳에 사용되냐에 따라 다른 의미를 가진다.변수
- 변수에 final을 부이면 이 변수는 수정할 수 없다는 의미 ⇒ 상수
- 수정될 수 없기 때문에 초기화 값은 필수이다.
- final로 변수가 선언되면 초기화 전에 사용할 시 컴파일 에러가 발생한다.
메서드
- 메서드에 final을 붙이면 override를 통해 재정의 될 수 없다.
- 상속받은 클래스에서 해당 메서드를 수정해서 사용하지 못하도록 할 수 있다.
클래스
- final 키워드를 클래스에 붙이면 상속 불가능 클래스가 된다.
- 클래스 설계 시 재정의 여부를 생각해서 재정의 불가능하게 사용하고 싶다면 final로 등록하는 게 유지보수 차원에서 좋다.
참고자료
https://mangkyu.tistory.com/47
'☕️ java' 카테고리의 다른 글
BigDecimal ❓ (0) 2023.03.07 [Java] String / StringBuffer / StringBuilde (0) 2023.03.03 Reflection API ? (0) 2023.02.09 커스텀 validation 만들기 (0) 2023.01.28 equals / hashCode (0) 2022.12.07