발표자 : 서동우
Generics - Generic programming 이란
- 데이터 형식에 의존하지 않고, 하나의 값이 여러 다른 데이터 타입들을 가질 수 있는 기술에 중점을 두어 재사용성을 높일 수 있는 프로그래밍 방식
- 제네릭 프로그래밍은 여러 가지 유용한 소프트웨어 컴포넌트들을 체계적으로 융합하는 방법을 연구하는 것으로 그 목적은 알고리즘, 데이터 구조, 메모리 할당 메커니즘, 그리고 기타 여러 소프트웨어적인 장치들을 발전시켜 이들의 재사용성, 모듈화, 사용 편의성을 보다 높은 수준으로 끌어올리고자 하는 것이다.
Generics – 그럼 자바에서는?
- JDK 1.5에서 처음 도입
- Generics add stability to your code by making more of your bugs detectable at compile time. – Oracle Javadoc
- 제네릭(Generic)은 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법을 의미한다. – 생활코딩
- 지네릭스는 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입 체크를 해주는 기능이다. – 자바의 정석
Generics - 그래서 정리하면
- Class, interface, method 선언 시 파라미터로 type을 받는다.
- 다른 input들에 대해서 동일한 코드를 제 사용할 수 있다.
- Type 변수는 non-primitive(int, long 같은것들은 사용할 수 없다.) 한 type만 올 수 있다.
Generics - 왜 사용할까요?
- 컴파일 시 타입체킹을 확실히 할 수 있다.
- 런타임 에러보다 컴파일 에러를 수정하는 게 편하다.
- 타입 변환(casting)을 안 해도 되니 빨라진다. (논란이 있다)
- 하나 잘 만들어서 여러 목적으로 사용할 수 있다. (= 코드의 중복을 줄일 수 있다.?)
- 조작해야 하는 데이터의 타입이 보장된다.
Generics 컨벤션
- E : Element
- K : Key
- N : Number
- T : Type
- V : Value
- S,U,V : 2nd, 3rd, 4th type
Generics 타입 파라미터 vs 타입 아규먼트
선언 부분에서 Box 에서 T는 Type Parameter
public class Box<T> // type paramter
구현 부분에서 Box 에서 String는 Type Argument
Box<String> box2 = new Box<>(); // type argument
Generics - Raw Types
Type argument를 생략한 Generic Type
값을 할당할 경우 unchecked conversation warning 이 나옵니다.
Box<Integer> box = new Box<>();
Box<String> box2 = new Box<>();
Box box4 = new Box(); // raw types
Generics - Generic Methods
- 타입을 파라미터로 가지고 있는 메서드
- 타입 파라미터의 scope가 선언된 메서드 내에서만 사용
- Static 메서드, 일반 메서드 둘 다 사용 가능
public class GenericMethod {
public static <T> void test(T data) {
}
public <T> void add(T data) {
}
}
사용하는 곳에서는 타입 추론을 한다.
GenericMethod.test(100);
Generics - Bounded Type Parameters
- Type arguments 의 타입에 제한을 걸 때 사용
- extends 키워드를 활용
- T extends 클래스명으로 사용할 경우 클래스 명의 하위 클래스만 사용할 수 있도록 제한을 걸 수 있음.
- 여러 개를 제한 조건으로 걸 수 있음
public class Box<T extends Number> { // Number클래스를 상속한 클래스만 사용할 수 있다.
}
- & 를 이용해서 여러 개 조건을 걸 수 있음
- T extends 클래스명 & 인터페이스명 …
- 클래스는 한 개만 가능(다중 상속이 안되기 때문에)
- 클래스와 인터페이스 조합의 경우는 클래스가 가장 앞에 있어야 함
public class Box<T extends Number & InterfaceBox> {
}
Generics - Wildcards
- ? 사용
- 제너릭 클래스나 메소드를 사용할 때 관련 type에 대한 정보를 알 수 없을 때 사용
Box<?> box;
public void setBox(Box<?> box) {
this.box = box;
}
Generics - Upper Bounded Wildcards
- Extends를 활용
- A extends B라고 선언되었을 때 B 또는 B의 서브 클래스만 사용 가능하도록 제한할 수 있음
Generics - Lower Bounded Wildcards
- super 키워드를 사용
- A super B 라고 사용되면 A 클래스는 B클래스 또는 B클래스의 상위 클래스만 사용 가능
Generics - 제너릭의 제한사항
- Primitive type을 사용할 수 없다.
- Type parameter의 인스턴스를 생성할 수 없다.
- Static field에서는 사용할 수 없다. (C#에서는 가능)
- Casting 하거나 instanceof 를 활용할 수 없다.
- 파라미터 타입의 배열을 생성할 수 없다.
- 오버로딩 할 수 없다.
- Parameter Type 객체를 Catch, Throw 할 수 없다.
Enum Type
- Enumerate
- 영어의 의미는 열거하다.
- 무엇인가를 열거하는 용도로 사용
- 상수의 그룹을 사용할 수 있는데 특수한 데이터 타입
- 상수이기 때문에 대문자로 표시(권장)
- enum 키워드를 사용하여 정의
- 특수한 클래스이다.
- 불변의 객체
// 보통 아래와 같은 형태이다.
public enum Example1 {
AAAAAA,
BBBBBB,
CCCCCC;
}
Enum - 자바와 다른 언어의 차이점
- 메소드와 필드 정보를 가질 수 있다.
- 컴파일러에서 자동으로 유용한 메서드를 추가
Annotation
- 과거에는 특별한 처리를 위해 정보가 필요할 경우 메소드 명이나 클래스 명의 Full-Name이나 Prefix 등의 문자열을 약속하여 사용
- Junit의 경우 메소드 명에 test를 붙임
- testUserSerivce, testLoginService
문제점
- 코딩 시 오타가 날 수 있음
- 특별한 상황에는 해당 Naming 사용 불가
- 컴파일 레벨에서 해당 오류를 찾을 수 없음
Annotation
- 주석
- 메타데이터
- 비즈니스 로직에는 영향을 주지 않지만 해당 타켓의 연결 방법이나 소스코드의 구조를 변경할 수 있음
- 사용
- 컴파일러에게 정보를 제공
- 컴파일 단계와 배포 단계 처리
- 런타임 처리
Annotation은 어디에서 호출 가능할까요?
- 클래스, 인터페이스, 메소드의 선언 부
- 인스턴스 생성 시
- 타입 캐스팅
- Implements 구문
- Throw 선언 구문
META Annotation - @Retention
자바 컴파일러가 Annotation Annotation을 다루는 방법을 기술하며, 특정 시점까지 영향을 미치는지를 결정합니다.
보통 리플렉션을 활용할 때 많이 사용하므로 RUNTIME을 많이 사용한다.
종류
- RetentionPolicy.SOURCE : 컴파일 전까지만 유효. (컴파일 이후에는 사라짐, 소스 로직 내에서 영향을 미칠 때)
- RetentionPolicy.CLASS : 컴파일러가 클래스를 참조할 때까지 유효.
- RetentionPolicy.RUNTIME : 컴파일 이후에도 JVM에 의해 계속 참조가 가능. (리플렉션 사용)
META Annotation – @Target
어노테이션이 적용할 위치를 선택합니다.
배열 형태로 지정하면 여러 개 지정할 수 있다.
종류
- ElementType.PACKAGE : 패키지 선언
- ElementType.TYPE : 타입 선언
- ElementType.ANNOTATION_TYPE : 어노테이션 타입 선언
- ElementType.CONSTRUCTOR : 생성자 선언
- ElementType.FIELD : 멤버 변수 선언
- ElementType.LOCAL_VARIABLE : 지역 변수 선언
- ElementType.METHOD : 메서드 선언
- ElementType.PARAMETER : 전달 인자 선언
- ElementType.TYPE_PARAMETER : 전달인자 타입 선언
- ElementType.TYPE_USE : 타입 선언
META Annotation – 그외
- @Documented
- 해당 어노테이션을 Javadoc에 포함시킵니다.
- @Inherited
- 어노테이션의 상속을 가능하게 합니다.
- @Repeatable
- Java8 부터 지원하며, 연속적으로 어노테이션을 선언할 수 있게 해줍니다.
사전에 정의된 Annotation
- @Deprecated
- 없어질 인터페이스, 클래스, 메서드 등을 표시할 때 사용(사용을 권장하지 않을 때)
- @Override
- 오버라이드 된 메소드를 나타낼 때 사용
- @SuppressWarnings
- 컴파일러가 특정한 경고를 나타내지 않을 때 사용
- @SafeVarargs
- 제너릭 같은 가변 인자 매개변수를 사용할 때 경고를 무시합니다
- @FunctionalInterface
- 람다 함수 등을 위한 인터페이스를 지정합니다. 메소드가 없거나 두 개 이상 되면 컴파일 오류가 납니다.
Reflection이란?
- 구체적인 클래스 타입을 알지 못해도, 그 클래스의 메소드, 타입, 변수 등에 접근할 수 있는 자바 API
- 런타임 시에 해당 클래스의 정보를 가져올 수 있는 상황에서 사용
'Java > JavaCafe Study' 카테고리의 다른 글
4주차 컬렉션 API (0) | 2021.06.27 |
---|---|
3주차 객체지향 (0) | 2021.06.05 |
2주차 JAVA API (0) | 2021.05.30 |