📌 Java Study
🔸 2022-08-04 목요일
[클래스와 객체]
1. static 변수, 메서드
static 변수
: 여러 인스턴스가 하나의 값을 공유할 필요가 있음
- 처음 프로그램이 로드될 때 데이터 영역에 생성됨
- 인스턴스의 생성과 상관없이 사용할 수 있으므로 클래스 이름으로 참조
클래스 변수
, 정적 변수
라고도 함
- C 언어 같은 경우, Global 변수로 외부에 변수를 선언해놓으면 프로그램 전체에서 사용할 수 있음
- JAVA는 클래스 외부에는 어떠한 변수를 둘 수 없고, 모든 변수 또는 메서드가 클래스 내부에 있어야 함
- static 으로 설정된 변수는 여러 인스턴스가 그 값을 공유할 수 있음
- 일반 변수들은
new
키워드로 생성하지만, static 변수는 처음 이 프로그램이 로드될 때 데이터 영역에 생성
Student.serialNum = 100;
Student studentHeo = new Student("Heo");
System.out.println(studentHeo.serialNum); // 1001
Student studentKim = new Student("Kim");
System.out.println(studentKim.serialNum); // 1002
System.out.println(studentHeo.serialNum); // 1002
- 초기값 StudentID = 1000 으로 설정
- 생성자 만들 시 serialNum++ 처리
- 위 출력문 3개 중 2번과 3번이 동일한 것으로 보아 studentHeo와 studentKim 두 개가 같은 메모리를 바라보고 있음
- serialNum = 1000 (
데이터 영역
)
- studentHeo, studentKim (
스택 메모리
)
- studentHeo 인스턴스, studentKim 인스턴스 (
힙 메모리
)
- 스택 메모리의 두 변수가 동일한 메모리 serialNum을 바라보고 있음
public static int getSerialNum() {
int i = 0;
studentName = "Heo";
return serialNum;
}
int i = 0
의 i 지역변수는 함수가 시작되면, 스택 메모리에 생성되었다가 끝나면 없어짐
return serialNum
은 static 변수이기 때문에 static 메서드 사용
studentName = "Heo"
처럼 static 메서드 안
에서 인스턴스 변수를 사용할 수 없음
=> static 메서드는 인스턴스 생성과는 무관하게 호출되는 메서드
- 다른 아래와 같이 일반 메서드에서 static 변수를 사용해도 문제가 발생하지 않은 이유 => static 변수는 맨 처음에 프로그램이 로딩될 때 생성되기 때문, 따라서 static은 큰 메모리를 사용하면 속도 저하 및 부하 발생
public int getStudentID() {
serialNum++;
return studentID;
}
- static이 아닌 일반 메서드에서
serialNum++
을 해도 문제가 발생하지 않음
static 메서드 정리
- static 변수를 위한 기능을 제공하는 static 메서드
- static 메서드에서는 인스턴스 변수를 사용할 수 없음
- 클래스 이름으로 참조하여 사용하는 메서드
Student.getSerialNum()
- 클래스 메서드, 정적 메서드라고도 함
변수 유형 |
선언 위치 |
사용 볌위 |
메모리 |
생성과 소멸 |
지역 변수(로컬 변수) |
함수 내부에 선언 |
함수 내부에서만 사용 |
스택 |
함수가 호출될 때 생성되고 함수가 끝나면 소멸 |
멤버 변수(인스턴스 변수) |
클래스 멤버 변수로 선언 |
클래스 내부에서 사용, private이 아니면 참조 변수로 다른 클래스에서 사용 가능 |
힙 |
인스턴스가 생성될 때 힙에 생성되고, 가비지 컬렉터가 메모리를 수거할 때 소멸 |
static 변수(클래스 변수) |
static 예약어를 사용하여 클래스 내부에 선언 |
클래스 내부에서 사용하고, private이 아니면 클래스 이름으로 다른 클래스에서 사용 가능 |
데이터 영역 |
프로그램이 처음 시작할 때 상수와 함께 데이터 영역에 생성되고, 프로그램이 끝나고 메모리를 해제할 때 소멸 |
2. Singleton Pattern(static 응용)
singleton pattern
: 단 하나만 존재하는 인스턴스
- 생성자는 private
- static으로 유일한 객체 생성
- 외부에서 유일한 객체를 참조할 수 있는 public static get() 메서드 구현
- 예) 회사, 학교 등 하나만 있어야 하는 인스턴스
싱글톤 패턴
을 사용하는 이유
- 최초 한 번의 new 연산자를 통해 고정된 메모리 영역을 사용하기 때문에 메모리 낭비 방지
- 다른 클래스간 데이터 공유가 쉽다.
- 도메인 관점에서 인스턴스가 한 개만 존재한다는 것을 보증하고 싶은 경우
싱글톤 패턴
의 문제점
- 싱글톤 패턴 구현 코드 자체가 많이 필요
- 테스트하기 어려움, 테스트가 격리된 환경에서 수행되려면 매번 인스턴스의 상태를 초기화해줘야 함
- new 키워드를 직접 사용하여 클래스 안에서 객체를 생성하고 있으므로, SOLID 원칙 중 DIP에 위반 혹은 OCP 원칙 위반할 가능성 높음
SOLID
: 프로그래머가 시간이 지나도 유지 보수와 확장이 쉬운 시스템을 만들고자 설계한 원칙
DIP(의존관계 역전 원칙)
: 의존관계를 맺을 때, 변화하기 쉬운 것 보단 변화하기 어려운 것에 의존해야 한다.
OCP(개방-폐쇄 원칙)
: 기존의 코드를 변경하지 않고, 기능을 추가하거나 수정할 수 있도록 설계해야 한다.
SRP(단일 책임 원칙)
: 소프트웨어의 설계 부품(클래스, 메서드 등)은 단 하나의 책임만을 가져야 한다.
LSP(리스코프 치환 원칙)
: 자식 클래스는 부모 클래스에서 가능한 행위를 수행할 수 있어야 한다.
ISP(인터페이스 분리 원칙)
: 한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 않아야 한다.
🔖 Eclipse 실습
![day8](https://user-images.githubusercontent.com/79084294/182936917-633308e2-be79-459a-b1dc-4103ea76fada.png)
🔖 Eclipse 출력 Console
![day8_console1](https://user-images.githubusercontent.com/79084294/182936938-ee9528d1-e9fe-45e5-b52f-10963eb2f61d.png)
![day8_console2](https://user-images.githubusercontent.com/79084294/182936954-e31f340a-e477-441a-8e5b-7c91b58225d6.png)