- 접근 지정자
접근 지정자는 클래스 내부 4요소 앞에 붙을 때와 클래스 자체에 붙을 때를 나눠서 생각해야 한다.
· 멤버 및 생성자에 붙는 접근 지정자
접근 지정자의 종류
1. public : 동일 패키지 안 모든 클래스 + 다른 패키지의 모든 클래스에서 사용 가능
2. protected : 동일 패키지 안 모든 클래스 + 다른 패키지의 자식 클래스에서 사용 가능
3. default : 동일 패키지 안 모든 클래스에서 사용 가능
4. private : 자신의 클래스 내부에서만 사용 가능
※ 같은 패키지의 클래스는 같은 폴더에 위치한 클래스
※ 접근 지정자를 지정 안 할 시 모든 클래스 내부 구성 요소는 default 접근 지정자
· 클래스에 붙는 접근 지정자
클래스에선 public, default 접근 지정자만 사용 가능하다.
public class : 동일 패키지, 다른 패키지 모두 사용 가능
default class : 같은 패키지 내에서만 사용 가능. (다른 패키지에서 임포트 불가.)
-> 임포트를 대신해 클래스 풀네임 사용할 때도 public으로 선언되어 있어야 함
· 클래스 접근 지정자와 생성자 접근 지정자의 연관성
클래스에 생성자가 없으면 컴파일러가 기본 생성자를 자동 추가해준다고 블로그 게시물인 클래스 내부 구성요소에서 언급했다. 이때 자동으로 추가되는 기본 생성자의 접근 지정자는 클래스의 접근 지정자로 결정된다. 물론 각자의 의미는 다르다.
클래스 접근 지정자 : 다른 패키지에서 임포트해 사용할 수 있는지
생성자 접근 지정자 : 생성자를 호출해 객체를 생성할 수 있는지
public 클래스일 땐 생성자도 public 접근 지정자고(임포트O), default 클래스일 땐 생성자도 default 접근 지정자이다(임포트X).
다른 패키지일 때)
클래스 접근 지정자가 default면 임포트되지 않아 생성자는 접근지정자와 상관없이 호출 자체를 할 수 없다. 다른 클래스 내부에 생성자가 존재하기 때문이다.
생성자 접근 클래스가 default일 때 클래스 접근 지정자가 public이면 다른 패키지에 임포트는 가능하겠지만 생성자는 호출할 수 없어 객체를 생성할 수 없게 된다.
동일 패키지일 때)클래스 접근 지정자 상관없이 모두 객체를 선언할 수 있고 생성자 접근 지정자 상관없이 모두 호출 가능하다
- static 제어자
static 제어자는 클래스 멤버에 사용한다.
static이 붙어 있는 멤버 : 정적 멤버
인스턴스 멤버는 객체 안에 있을 때 사용할 수 있는 상태가 되는 멤버이고 static이 앞에 붙지 않는 것을 말한다.
· 정적 멤버의 특징
컴파일 시 객체 생성 없이 메모리를 할당해 클래스명.멤버명만으로 사용 가능하다
※ 정적 필드와 인스턴스 필드의 차이
정적 필드 : 클래스명.정적필드명으로 사용. 클래스 내부에 저장 공간이 있어 객체 생성 불필요.
인스턴스 필드 : 참조변수명.인스턴스필드명으로 사용. 힙 메모리에 위치해 참조변수 필요.
A a = new A();
System.out.println(a.m); // class A 인스턴스 필드 m
System.out.println(A.n); // class A 정적 필드 n
주의할 점은 객체 내부에 정적 필드인 n도 존재한다는 것이다. n의 실제 저장 공간은 정적 영역 내부에 있으며, 객체 내부의 n은 실제 정적 필드의 저장 공간의 참조값만 가지고 있다. 따라서 인스턴스 필드처럼 참조 변수명으로도 사용이 가능하긴 하다. 하지만 호출된 모양만으로도 정적 멤버임을 알 수 있도록 해야 함으로 이 방법은 별로 추천하지 않는다.
· 정적 필드는 객체 간 공유 변수의 성질이 있다.
-> 따라서 클래스별로 관리하는 클래스 변수라고도 한다
※ 정적 메서드와 인스턴스 메서드
정적 메서드는 객체 생성없이 클래스명으로 바로 접근할 수 있고, 인스턴스 메서드처럼 객체로 호출도 가능하다. 인스턴스 메서드는 반드시 객체 생성 후 사용할 수 있다.
class A {
void abc() {
System.out.println("인스턴스 메서드");
}
static void bcd() {
System.out.println("정적 메서드");
}
}
//인스턴스 메서드
A a = new A();
a.abc();
//상속 메서드
A.bcd();
A a1 = new A();
a.bcd();
· 두 메서드의 차이점
인스턴스 메서드는 인스턴스 메서드 영역, 정적 메서드는 클래스 내부에 존재한다.
· 정적 메서드 안에서 사용 가능한 필드와 메서드
정적 메서드 안에선 정적 필드와 정적 메서드만 사용할 수 있다. 인스턴스 필드, 인스턴스 메서드는 사용 불가하다. 정적 멤버는 객체 생성없이 실행될 수 있어야 하기 때문이다. 하지만 인스턴스 멤버는 반드시 객체 생성 후에 사용이 가능해 정적 메서드 내에 존재하면 객체를 생성해야 한다. 그래서 장적 메서드를 쓸 땐 메서드 내부에 객체 생성 이전에 사용할 수 있는 요소들로만 구성되어야 하는 것이다. -> 정적 메서드 내부엔 클래스 내부에서 자신의 객체를 가리키는 this 키워드를 사용할 수 없다. 그래서 this가 자동으로 붙어야 하는 인스턴스 멤버는 올 수 없는 것이다. 어느 객체인지 모르기 때문에.
※ 인스턴스 메서드 내에선 인스턴스 멤버, 정적 멤버 모두 사용 가능하다.
· 정적 초기화 블록
인스턴스 필드 초기화는 생성자에서 객체 만들기 때문에 생성자 내에서 일어나는 게 일반적이지만 정적 필드는 생성자가 호출되지 않은 상태에서도 초기화될 수 있어야 한다. 생성자는 정적 필드를 초기화할 수 없다는 의미다. 그래서 정적 필드 초기화를 위한 문법이 별개로 존재하는데 이것이 정적 초기화 블록이다.
문법)
static{ //실행되는 내용}
정적 초기화 블록은 클래스가 메모리에 로딩될 때 제일 먼저 실행되어 여기에 정적 필드 초기화 코드를 넣으면 된다.
'JAVA > 공부' 카테고리의 다른 글
자바 제어자-2 (0) | 2022.07.02 |
---|---|
클래스 상속과 다형성 (0) | 2022.07.02 |
클래스 외부 구성 요소 (0) | 2022.07.02 |
클래스 내부 구성 요소 (0) | 2022.07.02 |
클래스와 객체 (0) | 2022.07.02 |