이번 아이템의 주제는 인스턴스화 막기다 Vv
생각보다 아이템 4가 많이 짧아서 인스턴스의 개념도 간략하게 설명하겠다!
자바에는 클래스와 인스턴스라는 개념이 존재한다.
두 개의 개념은 아주 가깝지만 큰 차이가 있다.
스태틱 영역은 클래스, 클래스 변수(정적 변수), 클래스 함수(정적 함수)가 위치하는 메모리영역이다.
main
메서드 시작전에 할당되어서 종료될 때까지 살아있는다.
힙 영역은 new
예약어로 생성된 객체(인스턴스)들이 존재한다. 즉 main
함수 실행 중에 할당되고 사라진다.
main 함수는 스택영역
을 차지한다.
결국 정적 변수, 정적 함수는 main
함수 실행 전부터 존재하게 되는 것이다.
따라서 정적 메서드, 정적 변수는 객체로 만들지 않더라도 사용할 수 있게 된다.
자세한 설명은 요기를 참고하자! 👉 자세히 보러가기
정적 변수,함수로만 구성된 클래스는 보통 유틸리티 클래스나, 클래스 명에 관련된 상수로 이루어진 클래스들이다.
Collections
에 관한 클래스이다.
가족별 생성 코드를 만드는 유틸리티 클래스이다.
상태저장이 불필요하기 때문에 인스턴스 변수가 필요하지 않다.
코드를 만드는 함수도 실행시점에 달라지지 않는 순수한 함수이다.
만약에 이 클래스를 매번 인스턴스화해서 사용한다면, 메모리의 낭비, 각각의 객체 변수명으로 여러곳에서 사용되는 불필요한 혼동이 있을 수 있다.
동일한 기능을 하는 코드인데도 변수명이 달라 팀원들에게 혼란을 줄 수 있게 된다.
그냥 단순히 이 클래스는 정적 변수,함수로만 이루어져있으니까 만들지마세요~ 하면 어떨까?
😤😤😤 어떻게 그걸 하나하나 확인하냐구요~! !!
쉽게 잊게 되는 사실은 생성자를 안만들어도 컴파일러가 자동으로 생성자를 만들어준다!
또한 이때 생성되는 생성자의 접근제어자는 클래스의 접근 제어자다.
유틸리티 클래스는 보통 여기저기서 사용하게 만들어지기 때문에 보통 public
접근 제어자를 가지고, 이로 인해 public
접근제어자를 가진 생성자가 만들어진다. 😅 😅
따라서 어떤 클래스의 인스턴스를 막고자 할때는 private를 붙인 생성자를 명시적으로 선언해야한다.
private FamilyCodeHandler() {
throw new AssertionError();
}
이렇게 되면 컴파일러가 생성자를 만들지 않으며, 다른 곳에서도 이 클래스를 인스턴스로 만들 수 없다.
상속을 하더라도 불가능하다.
하위 클래스의 생성자는 반드시 상위 클래스의 생성자를 호출하는데private
때문에 호출 자체가 불가능하기 때문이다.
private
: 클래스 외부에서 접근 불가능
물론 어노테이션도 있다.
@UtilityClass
@NoArgsConstructor(access = AccessLevel.PRIVATE)
private
생성자