🎇인스턴스 멤버와 정적 멤버
인스턴스 멤버
- 객체에서 개별적으로 사용할 멤버는 객체마다 다르게 선언한다.
- 인스턴스 멤버는 객체 안에만 있는 멤버이므로, 사용하기 위해서는 객체를 생성해줘야 한다.
정적 멤버
- 공통으로 사용할 멤버는 클래스(설계도)에 그대로 남겨둔다.
- 정적 멤버는 클래스에 고정된 멤버로 클래스 로더에 의해 클래스 영역 내 클래스가 로딩됨과 동시에 초기화 된다.
정적 멤버 사용
- 클래스명.필드;
- 클래스명.메서드(매개변수, ...);
- 객체 생성 후 참조 변수로도 접근이 가능하지만, 이클립스에서 경고를 발생한다.
- 이는, 효율적인 방법이 아니다. 객체 내부에서 멤버를 찾은 뒤 없는 경우 클래스에서 다시 찾기 때문에 비효율적이다.
this
- 객체 내부에서 인스턴스 멤버와 외부로부터 입력 받은 매개변수와 구분 및 내부 인스턴스 멤버에 접근하기 위해 자신의 참조값을 가진 지역변수이다.
- 정적 멤버는 클래스 멤버이기 때문에 객체 참조값을 담은 this라는 지역변수가 없다.
정적 멤버 내에서 인스턴스 멤버 사용
- 정적 멤버 안에서 인스턴스 멤버를 사용하기 위해서는 객체를 생성 후 사용 할 수 있다.
싱글톤 패턴(객체)
- 프로그램 전체에서 단 하나만의 객체를 생성해야 할 경우 사용.
- private 생성자 → 내부적으로 하나의 객체를 생성하기 위해서 생성자의 접근을 private으로 제한한다.
- private로 접근을 제한한 정적 필드 하나를 선언 후 자신의 객체를 내부적으로 생성하여 초기화한다.
- 외부에서 필드값 조회를 위해 public static getInstance() 메서드를 정의한다.
🎇final 필드와 상수
final 필드
- 프로그램 실행 중 변경이 불가하며, 개발자가 정의한 필드를 'final filed'라고 한다.
- 일반적으로 final 필드는 선언과 동시에 초기화 해주거나, 생성자 메서드 매개변수로 값을 받아서 초기화해준다.
- 초기화 후 값을 수정하면 컴파일 에러가 발생한다.
상수
- 일반적인 유일한 불변 값
Ex) 원주율 파이, 지구 둘레, 중력 가속도
- final 필드와는 다르게 상수는 공용성이라는 것이 존재하는데, 어디서든 공통적으로 적용되는 불변의 개념을 의미한다.
- 즉, final 필드는 객체마다 존재할 수 있어 유일한 값이 아니지만, 상수는 'static final' 필드로 유일한 불변의 값을 의미한다.
🎇패키지와 접근 제한자
패키지
- java에서 클래스를 찾을 때 참고하는 주소.
- 클래스 가장 상부 첫 줄에 정의한다.
- 상위 패키지. 하위 패키지. 클래스명(클래스 full name)
- import : 한 클래스에서 다른 패키지 내부의 클래스 접근 시 사용.
- 상위 패키지가 다른 동명의 클래스를 한 곳에서 사용할 경우, 클래스를 full name으로 구분해줘야 한다.
접근 제한자
- 클래스 및 클래스 멤버에 접근을 제한하기 위한 것.
- public : 모든 패키지, 모든 클래스 사용 가능
- protected : 동일 패키지에서만 사용 가능하나, 상속 관계의 자식 클래스는 부모 클래스의 자원을 사용할 수 있다.
- default : 동일 패키지에서만 사용 가능.
- private : 클래스 내부에서만 사용 가능.
- 클래스, 생성자, 필드, 메서드 모두 접근 제한이 가능하나, 클래스의 경우 public 또는 default만 사용 가능하다.
Getter와 Setter
- 일반적으로 객체 지향 프로그래밍에서는 객체의 필드를 객체 외부에서 직접 접근하는 것을 막는다. 이는 외부에서 마음대로 변경할 경우 객체의 무결성(결함이 없는 성질)이 깨질 수 있기 때문이다.
- 객체의 무결성 유지를 위해 필드를 private으로 접근 제한 후 Getter와 Setter로만 접근하도록 한다.
- 이는 필드값을 직접 사용함으로서 부적절한 입력 값에 대한 검증하지 못한다는 점을 보완하여, 입력 값 검증 및 처리를 할 수 있도록 해준다.
- getXXX, setXXX(일반), isXXX(boolean형 Getter) 형태의 메서드로 정의한다.
✅질문사항
메서드 호출 시, 호출 스택 변화
※ 호출 스택
메서드가 호출 되면 호출 스택에 쌓이며, 메서드 종료 시 스택에서 제거되고 할당된 메모리가 해제된다.
public static void main(String[] args) {
Car car = new Car("포르쉐");
Car car2 = new Car("벤츠");
car.run();
car2.run();
}
위와 같은 코드의 경우, main() 메서드 안에 각 객체의 run() 메서드 2개가 호출 되었다.
위 메서드 호출 시 호출 스택을 살펴보면,
car.run() car2.run()
-------- => ----------
main main
이러한 식으로, 위의 run() 메서드가 먼저 스택에 쌓인 다음 종료 및 메모리 해제 후 다음 run() 메서드가 실행되어 스택에 쌓이게 된다.