※ 6장_클래스
▶ 6.1 객체 지향 프로그래밍
▷ 객체지향 프로그래밍의특징
캡슐화
- 캡슐화란 객체의 필드, 메소드를 하나로 묶고, 실제 구현 내용을 감추는 것을 말한다.
- 외부 객체는 객체 내부의 구조를 알지 못하며 객체가 노출해서 제공하는 필드와 메소드만 이용할 수 있다.
- 필드와 메소드를 캡슐화 하여 보호하는 이유는 외부의 잘못된 사용으로 인해 객체가 손상되지 않도록 하는데 있다.
- 자바 언어는 캡슐화된 멤버를 노출시킬 것인지, 숨길 것인지를 결정하기 위해 접근제한자를 사용한다. 접근 제한자는 객체의 필드와 메소드의 사용 범위를 제한함으로써 외부로부터 보호한다.
상속
- 객체 지향 프로그래밍에서 상위 객체는 자기가 가지고 있는 필드와 메소드를 하위 객체에게 물려주어 하위 객체가 사용할 수 있도록 해준다.
- 상속은 상위 객체를 재사용해서 하위 객체를 쉽고 빨리 설계할 수 있도록 도와준다.
- 이미 잘 개발된 객체를 재사용해서 새로운 객체를 만들기 때문에 반복된 코드의 중복을 줄여준다.
다형성
- 다형성은 같은 타입이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질을 말한다.
- 코드 측면에서 보면 다형성은 하나의 타입에 여러 객체를 대입함으로써 다양한 기능을 이용할 수 있도록 해준다.
- 자바는 다형성을 위해 부모 클래스 또는 인터페이스의 타입 변환을 허용한다.
- 부모 타입에서는 모든 자식 객체가 대입될 수 있고, 인터페이스 타입에는 모든 구현 객체가 대입될 수 있다.
▶ 6.2 객체와 클래스
객체는 설계도를 바탕으로 만들어진다. 자바에서는 설계도가 바로 클래스이다.
클래스에는 객체를 생성하기 위한 필드와 메소드가 정의되어 있다. 클래스로부터 만들어진 객체를 해당 클래스의 인스턴스라고 하고, 클래스로부터 객체를 만드는 과정을 인스턴스화라고 한다.
▶ 6.3 클래스 선언
일반적으로 소스 파일당 하나의 클래스를 선언한다. 하지만 두개 이상의 클래스 선언도 가능하다.
public class Car {
}
class Tire {
}
두개 이상의 클래스가 선언된 소스파일을 컴파일하면 바이트 코드 파일은 (.class) 클래스를 선언한 개수만큼 생긴다. 소스 파일은 클래스 선언을 담고 있는 저장 단위일 뿐이지 클래스 자체가 아니다.
▶ 6.4 객체 생성과 클래스 변수
클래스로부터 객체를 생성하는 방법은 다음과 같이 new 연산자를 사용하면 된다.
new 는 클래스로부터 객체를 생성시키는 연산자이다. new 연산자로 생성된 객체는 메모리 힙(heap) 영역에 생성된다.
new 연산자는 힙 영역에 객체를 생성시킨 후, 객체의 주소를 리턴하도록 되어있다.
클래스 변수 = new 클래스();
이렇게 new 연산자로 객체를 생성하고 리턴된 객체의 주소를 변수에 저장하면 변수가 객체를 참조하게 된다.
public class Student{
}
public class StudentExample {
public static void main(String[] args) {
Student s1 = new Student();
System.out.println("s1 변수가 Student 객체를 참조합니다.");
Student s2 = new Student();
System.out.println("s2 변수가 또 다른 Student 객체를 참조합니다.");
}
]
위 예제가 실행되면 메모리에 클래스 변수와 객체가 생성된다. 이때 s1 과 s2 가 참조하는 Student 객체는 완전히 독립된 서로 다른 객체이다.
여기서 Student 와 StudentExample 클래스의 용도에 대해 알아볼 필요가 있다.
클래스는 두가지 용도가 있다.
1. 라이브러리(API) 용
라이브러리 클래스는 다른 클래스에서 이용할 목적으로 설계된다.
2. 실행용
프로그램 전체에서 사용되는 클래스가 100 개라면 99개는 라이브러리이고 단 하나가 실행 클래스이다.
실행 클래스는 프로그램의 실행 진입점인 main() 메소드를 제공하는 역할을 한다.
Student는 라이브러리 클래스이고 StudentExample는 실행 클래스이다.
▶ 6.5 클래스의 구성멤버
필드, 생성자, 메소드
▶ 6.6 필드
▷ 필드 타입별 기본 초기값
- byte : 0
- char : \u0000
- short : 0
- int : 0
- long : 0L
- float : 0.0F
- double : 0.0
- boolean : false
- 배열 : null
- 클래스(String 포함) : null
- 인터페이스 : null
클래스 외부에서 필드를 사용할 경우 우선적으로 클래스로부터 객체를 생성한 뒤 필드를 사용해야한다.
그 이유는 필드는 객체에 소속된 데이터이므로 객체가 존재하지 않으면 필드도 존재하지 않기 때문이다.
▶ 6.7 생성자
생성자를 실행시키지 않고는 클래스로부터 객체를 만들 수 없다.
new 연산자에 의해 생성자가 성공적으로 실행되면 힙 영역에 객체가 생성되고 객체의 주소가 리턴된다.
▷ 기본생성자
모든 클래스는 생성자가 반드시 존재하며, 하나 이상을 가질 수 있다.
클래스 내부에 생성자 선언을 생략했다면 컴파일러는 중괄호 {} 블록 내용이 비어있는 기본생성자를 바이트 코드에 자동 추가시킨다.
▶ 6.8 메소드
▶ 6.9 인스턴스 멤버와 this
인스턴스 멤버란 객체를 생성한 후 사용할 수 있는 필드와 메소드를 말한다.
인스턴스 필드와 메소드는 객체에 소속된 멤버이기 때문에 객체없이는 사용할 수 없다.
public class Car {
//필드
int gas;
//메소드
void setSpeed(int speed) {...}
}
Car myCar = new Car();
myCar.gas = 10;
myCar.setSpeed(60);
gas 필드와 setSpeed 메소드는 인스턴스 멤버이기 때문에 외부 클래스에서 참조하기 위해서는 우선 Car 객체(인스턴스)를 생성하고 참조변수 myCar 또는 yourCar 로 접근해야 한다.
객체 외부에서 인스턴스 멤버에 접근하기 위해 참조 변수를 사용하는 것과 마찬가지로 객체 내부에서도 인스턴스 멤버에 접근하기 위해 this 를 사용할 수 있다. 객체는 자신을 this 라고 한다.
this 는 주로 생성자와 메소드의 매개 변수 이름이 필드와 동일할 경우, 인스턴스 멤버인 필드임을 명시하고자 할 때 사용된다.
Car(String model) {
this.model = model;
}
void setModel(String model) {
this.model = model;
}
public class Car {
//필드
String model;
int speed;
//생성자
Car(String model){
this.model = model;
}
//메소드
void setSpeed(int speed){
this.speed = speed;
}
void run() {
for(int i=10; i<=50; i+=10){
this.setSpeed(i);
}
}
}
▶ 6.10 정적 멤버와 static
정적 멤버는 클래스에 고정된 멤버로서 객체를 생성하지 않고 사용할 수 있는 필드와 메소드를 말한다.
정적 멤버는 객체(인스턴스) 에 소속된 멤버가 아니라 클래스에 소속된 멤버이기 때문에 클래스 멤버라고도 한다 .
▷ 정적 멤버 선언
정적 필드와 정적 메소드를 선언하는 방법은 필드와 메소드 선언 시 static 키워드를 추가적으로 붙이면 된다.
public class 클래스 {
static 타입 필드 [= 초기값];
static 리턴 타입 메소드(매개변수선언, ...) {...}
}
정적 필드와 정적 메소드는 클래스에 고정된 멤버이므로 클래스 로더가 클래스를 로딩해서 메소드메모리 영역에 적재할 때 클래스별로 관리된다.
- 객체마다 가지고 있어야 할 데이터라면 인스턴스 필드로 선언한고, 객체마다 가지고 있을 필요성이 없는 공용적인 데이터라면 정적 필드로 선언하는 것이 좋다.
- 메소드의 경우, 인스턴스 필드를 이용해서 실행해야 한다면 인스턴스 메소드로 선언하고, 인스턴스 필드를 이용하지 않는다면 정적 메소드로 선언한다.
▷ 정적 멤버 사용
클래스 이름과 함께 도트(.) 연산자로 접근한다.
public class Calculator {
static double pi = 3.14159;
static int puls(int x, int y){...}
static int minus(int x, int y){...}
}
double result1 = 10 * 10 * Calculator.pi;
int result2 = Calculator.plus(10,5);
int result3 = Calculator.minus(10,5);
▷ 정적 초기화 블록
정적필드는 아래와 같이 필드 선언과 동시에 초기값을 주는 것이 보통이다.
static double pi = 3.14159;
자바는 정적 필드의 복잡한 초기화 작업을 위해서 정적 블록(static block) 을 제공한다.
static {
...
}
정적 블록은 클래스 내부에 여러개가 선언되어도 상관없다.
다음 예제에서 info 필드는 정적 블록에서 company 와 model 필드값을 서로 연결해서 초기값으로 설정한다.
public class Television {
static String company = "Samsung";
static String model = "LCD";
static String info;
static {
info = company + "-" + model;
}
}
▷ 정적 메소드와 블록 선언 시 주의할 점
정적 메소드와 정적 블록은 객체가 없어도 실행된다는 특징 때문에 이들 내부에 인스턴스 필드나 인스턴스 메소드를 사용할 수 없다.
또한 객체 자신의 참조인 this 키워드도 사용이 불가능하다.
정적 메소드와 정적 블록에서 인스턴스 멤버를 사용하고 싶다면 다음과 같이 객체를 먼저 생성하고 참조 변수로 접근해야 한다.
static void Method3() {
ClassName obj = new ClassName();
obj.field1 = 10;
obj.method1();
}
main() 메소드도 정적 메소드이므로 객체 생성 없이 인스턴스 필드와 인스턴스 메소드를 main( ) 메소드에서 바로 사용할 수 없다.
public class Car{
int speed;
void run() {
System.out.println(speed + "으로 달립니다");
}
public static void main(String[] args) {
Car myCar = new Car();
myCar.speed = 60;
myCar.run();
}
}
▷ 싱글톤(Singleton)
가끔 전체 프로그램에서 단 하나의 객체만 만들도록 보장해야 하는 경우가 있다. 단 하나만 생성된다고 해서 이 객체를 싱글톤(Singleton) 이라고 한다.
싱글톤을 만들려면
- 1. 클래스 외부에서 new 연산자로 생성자를 호출할 수 없도록 막아야 한다
- 생성자를 호출한만큼 객체가 생성되기 때문이다
- 생성자를 외부에서 호출할 수 없도록 하려면 생성자 앞에 private 접근 제한자를 붙여주면 된다.
- 2. 자신의 타입인 정적 필드를 하나 선언하고 자신의 객체를 생성해 초기화 한다
- 클래스 내부에서는 new 연산자로 생성자 호출이 가능하다.
- 3. 정적 필드도 private 접근 제한자를 붙여 외부에서 필드값을 변경하지 못하도록 막는다
- 4. 대신 외부에서 호출할 수 있는 정적 메소드인 getInstance() 를 선언하고 정적 필드에서 참조하고 있는 자신의 객체를 리턴해준다.
아래는 싱글톤을 만드는 코드이다.
public class 클래스 {
private static 클래스 singleton = new 클래스();
private 클래스() {}
static 클래스 getInstance() {
return singleton;
}
}
외부에서 객체를 얻는 유일한 방법은 getInstance() 메소드를 호출하는 방법이다.
getInstance() 메소드는 단 하나의 객체만 리턴하기 때문에 아래 코드에서 변수1 과 변수2는 동일한 객체를 참조한다.
클래스 변수1 = 클래스.getInstance();
클래스 변수2 = 클래스.getInstance();
싱글톤 객체
public class SingletonExample {
public static void main(String[] args) {
/*
Singleton obj1 = enw Singleton();
Singleton obj2 = enw Singleton();
*/
Singleton obj1 = Singleton.getInstance();
Singleton obj2 = Singleton.getInstance();
if(obj1 == obj2) {
System.out.prinbtln("같은 Singleton 객체 입니다.");
} else {
System.out.prinbtln("다른 Singleton 객체 입니다.");
}
}
}
▶ 6.11 final 필드와 상수
fianl 필드는 초기값이 저장되면 이것이 최종값이 되어서 프로그램 실행 도중에 수정할 수 없다는 것이다.
final 필드의 초기값을 주는 방법은 두가지가 있다.
- 1. 필드 선언 시에 주는 방법
- 단순 값이라면 필드 선언 시에 주는 것이 제일 간단하다.
- 2. 생성자에서 주는 방법
- 복잡한 초기화 코드가 필요하거나 객체 생성 시에 외부 데이터로 초기화해야 한다면 생성자에서 초기값을 지정해야 한다.
생성자는 final 필드의 최종 초기화를 마쳐야 하는데, 만약 초기화되지 않은 final 필드를 그대로 남겨두면 컴파일 에러가 발생한다.
public class Person {
final String nation = "Korea";
final String ssn;
String name;
public Person(String ssn, String name) {
this.ssn = ssn;
this.name = name;
}
}
위 예제에서 주민등록번호 필드는 한번 값이 저장되면 변경할 수 없다록 final 필드로 선언했다.
하지만 주민등록번호는 Person 객체가 생성될 때 부여되므로 Person 클래스 설계 시 초기값을 미리 줄 수 없다. 그래서 성자 매개값으로 주민등록번호를 받아서 초기값으로 지정해주었다.
반면 nation 은 항상 고정된 값을 갖기 때문에 필드 선언 시 초기값으로 "Korea" 를 주었다.
▷ 상수(static final)
일반적으로 불변의 값을 상수라고 불리는데, final 필드를 상수라고 부르진 않는다.
왜 ? 불변의 값은 객체마다 저장할 필요가 없는 공용성을 띠고 있으며, 여러가지 값으로 초기화 될 수 없기 때문이다.
( 상수라고 불리우는 수학에서 원주율 파이나, 지구의 무게 및 둘레는 여러가지 값으로 초기화 될 수 없지 않은가 ? )
final 필드는
- 객체마다 저장되고
- 생성자의 매개값을 통해 여러 가지 값을 가질 수 있기 때문에
상수가 될 수 없다.
상수는 static 이면서 final 이어야 한다.
static final 필드는 객체마다 저장되지 않고, 클래스에만 포함된다. 그리고 한 번 초기값이 저장되면 변경할 수 없다.
▶ 6.12 패키지
프로젝트를 개발하다 보면 적게는 수십 개, 많게는 수백 개의 클래스를 작성해야 한다.
클래스를 체게적으로 관리하지 않으면 클래스 간의 관계가 뒤엉켜서 복잡하고 난해한 프로그램이 되어 결국 유지보수가 어렵게 된다.
자바에서는 클래스를 체계적으로 관리하기 위해서 패키지를 사용한다.
자바는 우리가 폴더를 만들어 파일을 저장, 관리하듯이 패키지를 만들어 클래스를 저장하고 관리한다.
패키지는 클래스를 유일하게 만들어주는 식별자 역할을 한다.
클래스 이름이 동일하더라도 패키지가 다르면 다른 클래스로 인식한다.
클래스의 전체 이름은 "패키지명 + 클래스명" 이다.
▷ 패키지 선언
패키지는 클래스를 컴파일 하는 과정에서 자동적으로 생성되는 폴더이다.
컴파일러는 클래스에 포함되어있는 패키지 선언을 보고, 파일 시스템의 폴더로 자동 생성시킨다.
도메인 이름으로 패키지 이름을 만들 경우, 도메인 이름 역순으로 패키지 이름을 지어주는데, 그 이유는 포괄적인 이름이 상위 패키지가 되도록 하기 위해서이다. 그리고 마지막에는 프로젝트 이름을 붙여주는 것이 관례이다.
com.samsung.projectname
com.hyndai.projectname
com.lg.projectname
org.apache.projectname
▶ 6.13 접근 제한자
라이브러리 클래스를 설계할 때에는 외부 클래스에서 접근할 수 있는 멤버와 접근할 수 없는 멤버로 구분해서 필드, 생성자, 메소드를 설계하는 것이 바람직하다.
객체 생성을 막기 위해서 생성자를 호출하지 못하게 하거나 객체의 특정 데이터를 보호하기 위해 해당 필드에 접근하지 못하도록 막아야 한다. 그리고 특정 메소드를 호출할 수 없도록 제한할 필요가 있다.
자바는 이러한 기능을 구현하기 위해 접근제한자(Access Modifier) 를 제공하고 있다.
접근 제한자는 public, protected, default, private 과 같이 네 가지 종류가 있다.
public
- 공개한다는 의미를 가지고 있다.
- 외부 클래스가 자유롭게 사용할수 있는 공개 멤버를 만든다.
- 적용대상 : 클래스, 필드, 생성자, 메소드
- 접근할 수 없는 클래스 : 없음
protected
- 같은 패키지 또는 자식 클래스에서 사용할 수 있는 멤버를 만든다.
- 적용 대상: 필드, 생성자, 메소드
- 접근할 수 없는 클래스 : 자식 클래스가 아닌 다른 패키지에 소속된 클래스
default
- 나머지 세가지 접근제한자가 적용되지않은 멤버는 default 접근 제한을 가진다
- 같은 패키지에 소속된 클래스에서만 사용할 수 있는 멤버를 만든다.
- 적용대상 : 클래스, 필드, 생성자, 메소드
- 접근할 수 없는 클래스 : 다른 패키지에 소속된 클래스
private
- 개인적인것이라 외부에 노출되지 않는 멤버를 만든다.
- 적용대상 : 필드, 생성자, 메소드
- 접근할 수 없는 클래스 : 모든 외부 클래스
▷ 클래스의 접근 제한
클래스를 선언할 때 고려해야 할 사항은 같은 패키지 내에서만 사용할지, 아니면 다른 패키지에서도 사용할 수 있도록 할 것인지를 결정해야 한다. 클래스에 적용할 수 있는 접근제한은 public 과 default 두가지 이다.
//default 접근 제한
class 클래스 {...}
//public 접근 제한
pulic class 클래스{...}
default 접근 제한
클래스를 선언할 때 public 을 생략했다면 클래스는 default 접근 제한을 가진다.
클래스가 default 접근 제한을 가지게 되면 같은 패키지에서는 아무런 제한 없이 사용할 수 있지만 다른 패키지에서는 사용할 수 없도록 제한된다.

public 접근 제한
클래스가 public 접근 제한을 가지게 되면 같은 패키지뿐만 아니라 다른 패키지에서도 아무런 제한 없이 사용할 수 있다.
클래스를 다른 개발자가 사용할 수 있도록 라이브러리 클래스로 개발되어야 한다면, 반드시 public 접근 제한을 갖도록 해야 한다.

▷ 생성자의 접근 제한
객체를 생성하기 위해서는 new 연산자로 생성자를 호출해야한다. 하지만 생성자를 어디에서나 호출할 수 있는 것은 아니다.
생성자가 어떤 접근 제한을 갖느냐에 따라 호출 가능 여부가 결정된다.
생성자는 public, protected, default, private 접근 제한을 가질 수 있다.

클래스에 생성자를 선언하지 않으면 컴파일러에 의해 자동으로 기본 생성자가 추가되는데, 이때 생성자의 접근제한은 클래스의 접근 제한과 동일하다.
public
- 모든 패키지에서 아무런 제한 없이 생성자를 호출할 수 있다.
- 생성자가 public 접근 제한을 가진다면 클래스도 public 접근 제한을 가지는 것이 정상적이다.
- 클래스가 default 인데 생성자가 public 일경우 ? 클래스 사용이 같은 패키지로 한정되므로, 생성자가 public 이더라도 같은 패키지에서만 생성자를 호출할 수 있다.
protected
- default 접근제한과 마찬가지로 같은 패키지에 속하는 클래스에서 생성자를 호출할 수 있도록 한다.
- default 접근제한자와의 차이점은 다른 패키지에 속한 클래스가 해당 클래스의 자식(child) 클래스라면 생성자를 호출할 수 있다.
default
- 생성자를 선언할 때 public 또는 private 를 생략했다면 생성자는 default 접근 제한을 가진다.
- default 접근제한은 같은 패키지에서는 아무런 제한 없이 생성자를 호출할 수 있으나 다른 패키지에서는 생성자를 호출할 수 없도록 한다.
private
- private 접근은 동일 패키지이건, 다른 패키지이건 상관없이 생성자를 호출하지 못하도록 제한한다.
- 따라서 클래스 외부에서 new 연산자로 객체를 만들 수 없다. 오로지 클래스 내부에서 생성자를 호출할 수 있고, 객체를 만들 수 있다.
가끔 프로그램에서 단 하나의 객체만 만들도록 보장해야 하는 경우가 있다. 이런 경우 여러개의 객체를 만들지 못하도록 설계해야 하는데 이것을 싱글톤(Singleton) 패턴이라고 한다. 싱글톤 패턴은 생성자를 private 접근 제한자로 선언하고, 자신의 유일한 객체를 리턴하는 getInstance() 정적 메소드를 선언하는 것을 말한다.
싱글톤 객체
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton() {}
static Singleton getInstance() {
return singleton;
}
}
▷ 필드와 메소드의 접근 제한
필드와 메소드를 선언할 때 고려해야 할 사항은 클래스 내부에서만 사용할 것인지, 패키지 내에서만 사용할 것인지, 아니면 다른 패키지에서도 사용할 수 있도록 할 것인지를 결정해야 한다.
필드는 public, protected, default, private 접근 제한을 가질 수 있다.
public
- 모든 패키지에서 아무런 제한 없이 필드와 메소드를 사용할 수 있도록 해준다.
- 필드와 메소드가 public 접근 제한을 가질 경우 클래스도 public 접근 제한을 가져야 한다.
protected
- 같은 패키지에 속하는 클래스에서 필드와 메소드를 사용할 수 있도록 한다.
- 차이점은 다른 패키지에 속한 클래스가 해당 클래스의 자식 클래스라면 필드와 메소드를 사용할 수 있다.
default
- 같은 패키지에서는 아무런 제한 없이 필드와 메소드를 사용할 수 있으나, 다른 패키지에서는 필드와 메소드를 사용할 수 없도록 한다.
private
- 동일 패키지이건 다른 패키지이건 상관없이 필드와 메소드를 사용하지 못하도록 제한한다.
- 오로지 클래스 내부에서만 사용할 수 있다.
▶ 6.14 Getter 와 Setter 메소드
일반적으로 객체 지향 프로그래밍에서 객체의 데이터는 객체 외부에서 직접적으로 접근하는 것을 막는다. 그 이유는 객칑 데이터를 외부에서 마음대로 읽고 변경할 경우 객체의 무결성이 깨어질 수 있기 때문이다.
이러한 문제점을 해결하기 위해 객체지향 프로그래밍에서는 메소드를 통해서 데이터를 변경하는 방법을 선호한다.
데이터는 외부에서 접근할 수 없도록 막고, 메소드는 공개해서 외부에서 메소드를 통해 데이터에 접근하도록 유도한다. 그 이유는 메소드는 매개값을 검증해서 유효한 값만 데이터로 저장할 수 있기 때문이다. 이러한 역할을 하는 메소드가 Setter 이다.
void setSpeed(double speed) {
if(speed < 0) {
this.speed = 0;
return;
}else {
this.speed = speed;
}
}
외부에서 객체의 데이터를 읽을 때도 메소드를 사용하는 것이 좋다. 객체 외부에서 객체의 필드값을 사용하기에 부적절한 경우도 있는데, 이런 경우에는 메소드로 필드값을 가공한 후 외부로 전달하면 된다. 이런 메소드가 바로 Getter 이다.
double getSpeed() {
double km = speed * 1.6;
return km;
}
클래스를 선언할 때 가능하다면 필드(멤버변수) 를 private 으로 선언해서 외부로부터 보호하고, 필드에 대한 Setter 와 Getter 메소드를 작성해서 필드값을 안전하게 변경/사용하는 것이 좋다.
▶ 6.15 어노테이션
어노테이션은 메타데이터(metadata) 라고 볼 수 있다. 메타데이터란 애플리케이션이 처리해야 할 데이터가 아니라, 컴파일 과정과 실행 과정에서 코드를 어떻게 컴파일하고 처리할 것인지를 알려주는 정보이다.
어노테이션은 다음 세 가지 용도로 사용된다.
- 컴파일러에게 코드 문법 에러를 체크하도록 정보를 제공
- 소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동으로 생성할 수있도록 정보를 제공
- 실행 시 특정 기능을 실행하도록 정보를 제공
▷ 어노테이션 타입 정의와 적용
어노테이션 타입을 정의하는 방법은 인터페이스를 정의하는 것과 유사하다. @interface 를 사용해서 어노테이션을 정의한다.
public @interface AnnotationNmae {
타입 elementName() [default 값];
}
이렇게 정의한 어노테이션은 코드에서 @AnnotationName 으로 사용한다
public @interface AnnotationName {
String elementName();
int elementName2() default 5;
}
앨리먼트 이름 뒤에는 메소드를 작성하는 것처럼 () 를 붙여야 한다.
위와 같이 정의한 어노테이션을 코드에서 적용할 때에는 다음과 같이 기술한다.
@AnnotationName(elementName1="값", elementName2=3);
또는
@AnnotationName(elementName1="값");
elementName1 은 디폴트 값이 없기 때문에 반드시 값을 기술해야 하고, elementName2 는 디폴트 값이 있기 때문에 생략 가능하다. 어노테이션은 기본 엘리먼트인 value 를 가질 수 있다.
'JAVA' 카테고리의 다른 글
| [Java] ThreadLocal, 템플릿메서드 디자인패턴을 사용한 LogTrace 개발 (0) | 2025.04.02 |
|---|---|
| [JAVA] 네트워킹 NetWorking (0) | 2022.04.17 |
| [JAVA] Thread 스레드 (0) | 2022.04.14 |
| [JAVA] IO (0) | 2022.04.13 |
| [JAVA] GUI / 계속 추가예정 (0) | 2022.04.11 |