금요일에 멘탈이 털리고 토,일은 공부안하고 보냈다.
놀면서도 공부생각이 나서 괴로웠다.
공부해야하는데.. 하면서도 막상 보면 이해도 안가고 스스로한테 화나서 회피했다.
에혀
다시 월요일이니까 시작한다.
으아아ㅏ아아럅
열거형에 멤버 추가하기
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
// 열거형
enum Direction {
EAST(1, ">"), SOUTH(2, "V"), WEST(3, "<"), NORTH(4, "^");
private static final Direction[] DIR_ARR = Direction.values(); // 배열로 반환
private final int value;
private final String symbol;
// 생성자
Direction(int value, String symbol) {
this.value = value;
this.symbol = symbol;
}
public int getValue() { return value; }
public String getSymbol() { return symbol; }
public static Direction of(int dir) {
if(dir<1 || dir>4) {
throw new IllegalArgumentException("Invalid value :" + dir);
}
return DIR_ARR[dir-1];
}
// 방향을 회전시키는 메소드, 90도씩 회전
public Direction rotate(int num) {
num = num%4;
if(num<0) num += 4;
return DIR_ARR[(value-1+num)%4];
}
}
public class EnumEx2 {
public static void main(String[] args) {
for(Direction d : Direction.values())
System.out.printf("%s=%d, %s\n", d.name(), d.getValue(), d.getSymbol());
Direction d1 = Direction.EAST; // 열거형의 참조변수에 EAST값 넣어줌
Direction d2 = Direction.valueOf("WEST"); // 열거형의 참조변수에 WEST값 넣어줌
System.out.printf("d1=%s, %d, %s\n", d1.name(), d1.getValue(), d1.getSymbol());
System.out.printf("d2=%s, %d, %s\n", d2.name(), d2.getValue(), d2.getSymbol());
System.out.println(Direction.SOUTH.rotate(1));
System.out.println(Direction.SOUTH.rotate(2));
System.out.println(Direction.SOUTH.rotate(3));
System.out.println(Direction.SOUTH.rotate(4));
System.out.println(d1.rotate(3));
}
}
|
cs |
출력
EAST=1, >
SOUTH=2, V
WEST=3, <
NORTH=4, ^
d1=EAST, 1, >
d2=WEST, 3, <
WEST
NORTH
EAST
SOUTH
NORTH
열거형 상수에 값을 추가하려면 지정된 값을 저장할 수 있는 인스턴스 변수와 생성자를 추가해줘야 함
열거형에 추상 메소드 추가하기
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
// 열거형
enum Transportation {
// 열거형 상수, 추상메소드를 구현
BUS(100) { int fare(int distance) { return distance * BASIC_FARE; }},
TRAIN(150) { int fare(int distance) { return distance * BASIC_FARE; }},
SHIP(100) { int fare(int distance) { return distance * BASIC_FARE; }},
AIRPLANE(300) { int fare(int distance) { return distance * BASIC_FARE;}};
// 열거형 상수의 값에 대한 변수, protected로 해야 각 상수에서 접근가능
protected final int BASIC_FARE;
// 열거형 상수의 값에 대한 생성자
Transportation(int basicFare) {
BASIC_FARE = basicFare;
}
public int getBasicFare() { return BASIC_FARE; }
// 추상메소드, 거리에 따른 요금 계산
abstract int fare(int distance);
}
public class EunuEx3 {
public static void main(String[] args) {
// 거리 100에 대한 각 열거형 상수들의 요금계산
System.out.println("bus fare="+Transportation.BUS.fare(100));
System.out.println("train fare="+Transportation.TRAIN.fare(100));
System.out.println("ship fare="+Transportation.SHIP.fare(100));
System.out.println("airplane fare="+Transportation.AIRPLANE.fare(100));
}
}
|
cs |
출력
bus fare=10000
train fare=15000
ship fare=10000
airplane fare=30000
열거형에 추상 메소드를 선언하면 열거형 상수가 이 추상 메소드를 반드시 구현해야 함
열거형의 이해
열거형 Direction이 다음과 같이 정의되어 있을 때,
enum Direction { EAST, SOUTH, WEST, NORTH }
- 열거형 상수 하나하나가 Direction객체
- 클래스화 해보면?
|
1
2
3
4
5
6
7
8
9
10
11
12
|
class Direction {
static final Direction EAST = new Direction("EAST");
static final Direction SOUTH = new Direction("SOUTH");
static final Direction WEST = new Direction("WEST");
static final Direction NORTH = new Direction("NORTH");
private String name;
private Direction(String name) {
this.name = name;
}
}
|
cs |
위와 같다.
애노테이션 ( annotation )
- 미리 정의된 태그들을 이용해서 주석 안에 정보를 저장하고, javadoc.exe라는 프로그램이 이 정보를 읽어서 문서를 작성하는 데에 사용한다. 이러한 기능을 응용해, 프로그램의 소스코드 안에 다른 프로그램을 위한 정보를 미리 약속된 형식으로 포함시킨 것이 애노테이션
- 주석처럼 프로그래밍 언어에 영향을 미치지 않으면서 다른 프로그램에게 유용한 정보를 제공할 수 있다는 장점
-ex)
'@Test'라는 애노테이션을 메소드 앞에 붙이면, 해당 애노테이션이 붙은 메소드만 테스트가능.
'@Test'는 '이 메소드를 테스트 해야 함'을 테스트 프로그램에게 알리는 역할을 담당, 메소드가 포함된 프로그램 자체에는 영향X
표준 애노테이션
- 자바에서 기본적으로 제공하는 애노테이션들은 몇 개 없는데, 이 중 일부는 '메타애노테이션'으로 애노테이션을 정의하는데 사용되는 애노테이션의 애노테이션
@Override
- 메소드 앞에만 붙일 수 있는 애노테이션
- 조상의 메소드를 오버라이딩하는 것이라는 걸 컴파일러에게 알려주는 역할
@Deprecated
- 더 이상 사용되지 않는 필드나 메소드에 붙임
- 이 애노테이션이 붙은 대상은 다른 것으로 대체되었으니 더 이상 사용하지 않는 것을 권한다는 의미
- '@Deprecated'가 붙은 대상을 사용해도 컴파일은 정상적으로 실행
@FunctionalInteface
- '함수형 인터페이스'를 선언할 때 사용
- 이 애노테이션을 붙이면 컴파일러가 '함수형 인터페이스'를 올바르게 선언했는지 확인
@SuppressWarnings
- 컴파일러가 보여주는 경고메시지가 나타나지 않게 억제해주는 역할
- '@SuppressWarnings'로 억제할 수 있는 경고 메시지의 종류로 주로 사용되는 것은 'deprecation', 'unchecked', 'rawtypes', 'varargs'등
'deprecation' : '@Deprecated'가 붙은 대상을 사용해서 발생 하는 경고를 뜻함
'unchecked' : 지네릭스로 타입을 지정하지 않았을 때 발생하는 경고
'rawtypes' : 지네릭스를 사용하지 않아서 발생하는 경고
'varargs' : 가변인자의 타입이 지네릭 타입일 때 발생하는 경고를 억제할 때 사용
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
import java.util.ArrayList;
class NewClass {
int newField;
int getNewField() { return newField; }
@Deprecated
int oldField;
@Deprecated
int getOldField() { return oldField; }
}
public class AnnotationEx2 {
@SuppressWarnings("deprecation") // deprecation관련 경고를 억제
public static void main(String[] args) {
NewClass nc = new NewClass();
nc.oldField = 10; // @Deprecated가 붙은 대상 사용, 경고발생
System.out.println(nc.getOldField()); // @Deprecated가 붙은 대상 사용, 경고발생
@SuppressWarnings("unchecked") // 지네릭스 관련 경고를 억제
ArrayList<NewClass> list = new ArrayList(); // 타입 지정x, 경고발생
list.add(nc);
}
}
|
cs |
@SuppressWarnings를 합쳐서 선언 할 수 도 있다
|
1
2
|
@SuppressWarnings({"deprecation", "unchecked"}) // deprecation과 unchecked 관련 경고를 억제
|
cs |
@SafeVarargs
- 메소드에 선언된 가변인자 타입이 non-reifiable타입일 경우, 해당 메소드의 선언, 호출부분에서 'unchecked'경고 발생
- 해당 코드에 문제가 없다면 이 경고를 억제하기 위해 이 애노테이션을 사용
- static이나 final이 붙은 메소드와 생성자에만 붙일 수 있음 ( 오버라이드될 수 있는 메소드에는 사용 불가 )
reifiable, non-reifiable타입?
- 지네릭스에서 살펴봤듯이 어떤 타입들은 컴파일 이후에 제거되는데, 컴파일 후에도 제거되지 않는 타입을 reifiable타입, 제거되는 타입을 non-reifiable타입
- 지네릭 타입들은 대부분 컴파일 시에 제거되므로 non-reifiable타입
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
import java.util.Arrays;
class MyArrayList<T> {
T[] arr;
@SafeVarargs // unchecked경고 억제
@SuppressWarnings("varargs") // varargs경고 억제, 이 애노테이션으로 unchecked를 억제하려면 선언,호출부분에 선언해야함
MyArrayList(T... arr) { // 가변인자
this.arr = arr;
}
@SafeVarargs
// @SuppressWarnings("unchecked")
public static <T> MyArrayList<T> asList(T... a) {
return new MyArrayList<>(a);
}
public String toString() {
return Arrays.toString(arr);
}
}
public class AnnotationEx4 {
// @SuppressWarnings("unchecked")
public static void main(String[] args) {
MyArrayList<String> list = MyArrayList.asList("1", "2", "3");
System.out.println(list);
}
}
|
cs |
12행 주석처리, 13,24행 주석해제 -> 같은 결과
메타 애노테이션
- 애노테이션을 위한 애노테이션
- 애노테이션에 붙이는 에노테이션으로, 애노테이션을 정의할 때 애노테이션의 적용대상이나 유지기간등을 지정하는 데에 사용
@Target
- 애노테이션이 적용가능한 대상을 지정하는데 사용
- ex)
'@SuppressWarnings'에 적용할 수 있는 대상을 '@Target'으로 지정한다면?
|
1
2
3
4
5
|
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
|
cs |
@Retention
- 애노테이션이 유지되는 기간을 지정하는데 사용
- 애노테이션의 유지정책의 종류는 아래와 같다
SOURCE : 소스 파일에만 존재. 클래스파일에는 존재X
CLASS : 클래스 파일에 존재. 시행시에 사용불가. 기본값
RUNTIME : 클래스 파일에 존재. 실행시에 사용가능
@Documented
- 애노테이션에 대한 정보가 javadoc으로 작성한 문서에 포함되도록 함
- 자바에서 제공하는 기본 애노테이션 중에 '@Override', '@SuppressWarnings'를 제외하고는 모두 이 메타 애노테이션이 붙어 있음
@Inherited
- 애노테이션이 자손 클래스에 상속되도록 함
- '@Inherited'가 붙은 애노테이션을 조상클래스에 붙이면, 자손 클래스도 이 애노테이션이 붙은 것과 같이 인식 됨
@Repeatable
- 보통은 하나의 대상에 한 종류의 애노테이션을 붙이는데, '@Repeatable'이 붙은 애노테이션은 여러 번 붙일 수 있음
- 같은 이름의 애노테이션이 여러 개가 하나의 대상에 적용될 수 있기 때문에 이 애노테이션들을 하나로 묶어서 다룰 수 있는 애노테이션을 추가로 정의해야함 ( 이 애노테이션을 @Repeatable로 지정해야함 )
@Native
- 네이티브 메소드에 의해 참조되는 '상수필드'에 붙이는 애노테이션
- 네이티브 메소드는 JVM이 설치된 OS의 메소드를 의미함
- Object클래스의 메소드들이 대부분 네이티브 메소드
- 네이티브 메소드를 호출하는 방법은 일반 메소드와 같지만 실제로 호출되는 것은 OS의 메소드
애노테이션 타입 정의하기
- 새로운 애노테이션을 정의하는 방법은 아래와 같다
인터페이스를 정의하는 것과 동일하며, '@'기호를 붙이면 됨
ex)
@interface 애노테이션이름 {
타입 요소이름(); // 애노테이션의 요소 선언
...
}
애노테이션의 요소
- 애노테이션 내에 선언된 메소드를 '에노테이션의 요소'라고 함
- 반환값이 있고 매개변수는 없는 추상메소드의 형태이며, 상속을 통해 구현하지 않아도 됨
- 애노테이션을 적용할 때, 이 요소들의 값을 전부 지정해주어야 함
- 요소의 이름도 같이 적으므로 순서는 상관x
java.lang.annotation.Annotation
- 모든 애노테이션의 조상은 Annotation
- 상속이 허용되지 않아 extends로 조상 지정 불가
마커 애노테이션 Marker Annotation
- 애노테이션의 요소를 하나도 정의하지 않을 수 있음 (ex. Serializable, Cloneable인터페이스)
- 요소가 하나도 정의되지 않은 애노테이션
애노테이션 요소의 규칙
- 요소의 타입은 기본형, String, enum, 애노테이션, Class만 허용
- ()안에 매개변수 선언 불가
- 예외 선언 불가
- 요소를 타입 매개변수로 정의 불가
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
// 열거형
enum TestType { FIRST, FINAL }
@Retention(RetentionPolicy.RUNTIME) // 메타애노테이션
@interface DateTime { // 새로운 애노테이션 정의
// 애노테이션 요소
String yymmdd();
String hhmmss();
}
@Retention(RetentionPolicy.RUNTIME) // 실행 시에 사용가능하도록 설정
@interface TestInfo { // 새로운 애노테이션 정의
// 애노테이션 요소
int count() default 1;
String testedBy();
String[] testTools() default "JUnit";
TestType testType() default TestType.FIRST;
DateTime testDate();
}
@Deprecated // 앞으로 사용하지 않을 것이라는 의미
@SuppressWarnings("1111") //
// 애노테이션 적용 시, 요소들의 값을 지정해주고 이름도 적어야함
@TestInfo(testedBy="aaa", testDate=@DateTime(yymmdd="201116", hhmmss="171725"))
public class AnnotationEx5 {
public static void main(String[] args) {
Class<AnnotationEx5> cls = AnnotationEx5.class; // AnnotationEx5의 Class객체를 얻음
TestInfo anno = (TestInfo)cls.getAnnotation(TestInfo.class); // AnnotationEx5에 적용된 @TestInfo의 정보를 얻음
System.out.println("anno.testedBy()="+anno.testedBy());
System.out.println("anno.testDate().yymmdd()="+anno.testDate().yymmdd());
System.out.println("anno.testDate().hhmmss()="+anno.testDate().hhmmss());
for(String str : anno.testTools())
System.out.println("testTools="+str);
System.out.println();
// AnnotationEx5에 적용된 모든 애노테이션을 가져옴
Annotation[] annoArr = cls.getAnnotations();
for(Annotation a : annoArr)
System.out.println(a);
}
}
|
cs |
출력
anno.testedBy()=aaa
anno.testDate().yymmdd()=201116
anno.testDate().hhmmss()=171725
testTools=JUnit
@java.lang.Deprecated()
@annotation.TestInfo(count=1, testType=FIRST, testTools [JUnit], testedBy=aaa, testDate=@annotation.DateTime(yymmdd=201116, hhmmss=171725))
'아카이브 > 자바의 정석' 카테고리의 다른 글
| 13장 Thread 20201120 (0) | 2020.11.20 |
|---|---|
| 13장 Thread 20201118 (0) | 2020.11.18 |
| 12장 지네릭스,열거형,애노테이션 20201113 (0) | 2020.11.13 |
| 12장 지네릭스,열거형,애노테이션 20201112 (0) | 2020.11.12 |
| 12장 지네릭스,열거형,애노테이션 20201111 (0) | 2020.11.11 |