◆ 인스턴스 멤버
- 객체(인스턴스)마다 가지고 있는 필드와 메소드
- 인스턴스 멤버는 객체라는 소속이 있기 때문에 객체 없이 사용할 수 없다.
※ this : 객체 내부에서 인스턴스 멤버 소속임을 명확하게 하기 위해 사용
◆ 정적 멤버
- 모든 객체가 공유하는 필드와 메소드
- 객체 내부에 존재하지 않고 메소드 영역에 존재하기 때문에
객체를 생성하지 않고 클래스명으로 바로 접근하여 사용할 수 있다.
※ static : 정적 멤버로 선언할 때 static 키워드 사용
◆ 인스턴스 멤버 / 정적 멤버 선언의 기준
인스턴스 멤버 => 인스턴스 멤버 + 정적 멤버 모두 사용가능
정적 멤버 => 오로지 정적 멤버만 사용가능
<필드>
- 인스턴스 필드 : 객체마다 가지고 있어야하는 데이터
- 정적 필드 : 모든 객체가 공유하는 데이터
<메소드>
- 인스턴스 메소드 : 인스턴스 필드로 작업해야 할 메소드
- 정적 메소드 : 인스턴스 필드로 작업하지 않는 메소드
인스턴스 멤버(필드, 메소드) |
정적 멤버(필드, 메소드) |
- new 연산자로 객체가 생성될 때 함께 생성 - 인스턴스 필드의 초기화 : 생성자가 담당
|
- 메소드 영역에 존재하여 클래스로 접근가능 - 정적 필드의 초기화 : static initializer 담당 (초기화는 단 한번만 수행되며 클래쯔 객체 생성 전에 수행) |
◆ 정적 멤버와 static
정적 멤버에는 static이라는 키워드를 사용하여 선언하며
크게 세가지의 종류가 있다.
1. 정적 필드
2. 정적 메소드
3.정적 초기화 블록(static initializer)
여기서는 앞서 설명되지 못했던 static initializer에 대해 알아보자!
※ static initializer
- 클래스가 메소드 영역으로 로딩될 때 자동으로 실행하는 블록으로 정적 필드의 초기화를 담당
- 직접 생성하지 않아도 컴파일러가 생성하여 초기화를 해준다(생성자와 동일한 원리)
<참고> static initializer의 생성
static initializer는 class loader에 의해서 .class파일(바이트코드)을 찾아서 Class타입의 객체로 만들어
메소드 영역에 집어 넣기 전에 오로지 단 한번 호출된다!!
◆ final필드와 상수(static final)
- final 필드 : 각 객체마다 가지는 불변의 인스턴스 필드
- 상수(static final) : 모든 객체 안에서 변하지 않는 불변의 정적 필드
(메소드 영역에 클래스별로 관리되는 불변의 정적 필드)
◆ 싱글톤(Singleton)
하나의 어플리케이션 내에서 단 하나만 생성되는 객체
※ <싱글톤을 만드는 방법>
step1. 외부에서 new 연산자로 생성자를 호출할 수 없도록 생성자에 private를 붙인다.
즉, 싱글톤 패턴에서는 외부에서는 다른 객체를 생성할 수 없다!!!(캡슐화)
step2. 클래스 자신의 타입으로 정적 필드를 선언하여 단 하나인 싱글톤 객체의 주소를 보관한다.
- private 붙이는 이유 : 클래스 내부에서 생성자를 호출한 후,
외부에서 접근하지 못하도록 하기 위함(캡슐화)
- static 붙이는 이유 : 단 한번 객체가 생성되기 때문에 인스턴스 멤버로 사용할수가 없다!
따라서, 객체생성없이 호출할 수 있도록 static 메소드로 선언해야 한다.
step3. 외부에서 호출할 수 있는 정적 메소드인 gerInstance() 선언한다.
- public 붙이는 이유 : 모든 클래스에서 사용 가능하도록 하기 위함
- static 붙이는 이유 : 단 한번 객체가 생성되기 때문에 인스턴스 멤버로 사용할 수 없다.
따라서, 객체생성없이 호출할 수 있도록 static 메소드로 선언해야 한다.
이외에 싱글톤 클래스 내부에 작성한 필드는 private 접근제한자의 인스턴스 필드로 선언한다!
why? 싱글톤 객체는 단 한번 생성되는 하나의 객체
---> 그 객체가 생성될 때 인스턴스 멤버들이 생성되기 때문에 굳이 static을 붙이지 않아도 된다.
◆ 패키지
- 클래스를 기능별로 묶어서 관리하도록 하는 것
- 클래스를 유일하게 만들어주는 식별자로 클래스 간 이름 충돌 방지한다.
- 물리적으로 파일 시스템의 폴더(디렉토리)와 비슷한 개념이며, 계층구조를 갖는다.
※ 소스파일 작성 시, 패키지 선언보다 앞서서 작성할 수 있는 소스는 없다!
◆ 접근제한자(Access Modifier)
- 클래스 및 클래스의 구성 멤버에 대한 접근을 제한하는 역할(은닉화, 캡슐화)
- 클래스 내부에서는 접근제한자의 의미가 없다.
※ 접근제한자의 종류
접근 제한 |
적용대상 |
접근할 수 없는 클래스 |
public |
클래스, 필드, 생성자, 메소드 |
없음 |
protected |
필드, 생성자, 메소드 |
자식 클래스가 아닌 다른 패키지에 소속된 클래스 |
default |
클래스, 필드, 생성자, 메소드 |
다른 패키지에 소속된클래스 |
private |
필드, 생성자, 메소드 |
모든 외부 클래스 |
◆ 어노테이션(Annotation)
- 프로그램에게 추가적인 정보를 제공해주는 메타 데이터
다시 말해 주어진 데이터에 대해 설명해주는 데이터
- 어노테이션도 참조타입이기 때문에 사용할 때는 import문을 작성
※ 어노테이션의 용도
- 컴파일러에게 코드 작성 문법 에러 체크하도록 정보 제공
- 소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동 생성하게 정보 제공
- 런타임 시 특정 기능을 실행하도록 정보 제공
※ 어노테이션의 정의
- 어노테이션을 정의할 때, 인터페이스 형태로 만들 수 있는데 '@interface'를 붙여준다.
- 어노테이션의 속성은 element라고 부르며 기본 엘리먼트는 " 타입 + value( ); " 로 선언한다.
(+. String value( ); --> ( ) 소괄호가 들어가있기 때문에 필드라고 부를 수 없다!!)
- 어노테이션 사용 시 속성에 전달할 값이 있는 경우, ( ) 소괄호 안에 넣어주면 된다.
기본 엘리먼트는 이름 생략 가능하며, 이외에는 " value = 값 " 형태로 기술한다.
- 값을 외부에서 받지 못한 경우, 속성 선언 시 정의된 default 값을 가져갈 수 있다.
(default 값이 없는 경우에는 어노테이션 사용 시 반드시 값을 전달해야 한다!!)
<어노테이션의 속성 타입>
(1) 기본 타입(primitive type)
(2) String 타입
(3) 열거타입( Enumeration type)
(4) Class 타입(clazz) - 클래스, 인터페이스는 제외
(5) 위의 (1)부터 (4)까지의 타입으로 구성된 배열
<어노테이션의 적용 대상>
- @Target 어노테이션 사용하여 어노테이션의 적용대상을 지정
- 적용 대상은java.lang.annotation.ElementType 열거 상수로 정의
<어노테이션 유지 정책>
- @Retention 어노테이션 적용 코드가 유지되는 시점을 지정하는 것
- 그 시점은 java.lang.annotation.RetentionPolicy 열거 상수로 정의
•리플렉션(Reflection): 런타임에 클래스의 메타 정보를 얻는 기능
<어노테이션 정보 사용>
- 클래스에 적용된 어노테이션 정보 얻기
: 클래스.class의 어노테이션 정보를 얻는 메소드 이용
- 필드, 생성자, 메소드에 적용된 어노테이션 정보 얻기
: 다음 메소드 이용해 java.lang.reflect 패키지의 Field, Constructor, Method 클래스의 배열 얻어냄