모든 클래스를 로딩 한 다음 Class의 인스턴스가 생긴다. “타입.class”로 접근할 수 있다.
모든 인스턴스는 getClass() 메소드를 가지고 있다. “인스턴스.getClass()”로 접근할 수 있다.
클래스를 문자열로 읽어오는 방법
Class.forName(“FQCN”)
클래스패스에 해당 클래스가 없다면 ClassNotFoundException이 발생한다.
Class를 통해 할 수 있는 것
필드 (목록) 가져오기
메소드 (목록) 가져오기
상위 클래스 가져오기
인터페이스 (목록) 가져오기
애노테이션 가져오기
생성자 가져오기
...
예시
클래스에 접근하는 방법 3 가지.
public class Main {
public static void main(String[] args) throws ClassNotFoundException {
Class<Book> bookClass = Book.class;
Book book = new Book();
Class<? extends Book> aClass = book.getClass();
Class<?> aClass1 = Class.forName("april.apr11st.Book");
}
}
콜렉션이 제공하는 기능으로 클래스의 정보를 가져올 수 있다.
필드 확인 (나머지도 유사)
class.getField() : public한 field만 가져온다.
class.getDeclaredFields() : 모든 field 가져온다.
class.setAccessible(true) : 접근이 불가한 녀석에게 접근이 가능하게 해준다.
Modifier로 private인지 static인지도 다 확인이 가능하다.
메소드 확인
생성자 확인
부모 클래스 확인
인터페이스 확인
3. 애노테이션과 리플렉션
중요 애노테이션
@Retention : 해당 애노테이션을 언제까지 유지할 것인가? 소스, 클래스, 런타임
기본은 .class 라서 메모리로 로딩되는 시점에는 애노테이션 정보를 가지고 있지 않다.
@Inherit : 해당 애노테이션을 하위 클래스까지 전달할 것인가?
@Target : 어디에 사용할 수 있는가? (필드, 메소드, 클래스)
기본값을 설정해두면 그 값이 default 값
'value'라 지칭하면 바로 값만 넣어도 된다. (값이 하나일 때만)
리플렉션
getAnnotations(): 상속받은 (@Inherit) 애노테이션까지 조회
getDeclaredAnnotations(): 자기 자신에만 붙어있는 애노테이션 조회
예시
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Target(ElementType.TYPE)
public @interface HelloAnnotation {
String name();
int age() default 500;
}
4. 리플렉션 API 2부: 클래스 정보 수정 또는 실행
Class 인스턴스 만들기
Class.newInstance()는 deprecated 됐으며 이제부터는 생성자를 통해서 만들어야 한다.
생성자로 인스턴스 만들기
Constructor.newInstance(params)
필드 값 접근하기/설정하기
특정 인스턴스가 가지고 있는 값을 가져오는 것이기 때문에 인스턴스가 필요하다.
Field.get(object) (값을 꺼낼 때 필드가 특정한 인스턴스에 해당하는 필드라면 object에 넣어주면 된다.)
Filed.set(object, value)
Static 필드를 가져올 때는 object가 없어도 되니까 null을 넘기면 된다.
메소드 실행하기
Object Method.invoke(object, params)
예시
public class Main {
public static void main(String[] args) throws ... {
Class<Car> carClass = Car.class;
Constructor<?> constructor = carClass.getConstructor(null);
Car car = (Car) constructor.newInstance();
System.out.println(car);
Field a = Car.class.getDeclaredField("b");
a.setAccessible(true);
System.out.println(a.get(car));
a.set(car, "BBBB");
System.out.println(a.get(car));
}
}
5. 나만의 DI 프레임워크 만들기
@Inject 라는 애노테이션 만들어서 필드 주입 해주는 컨테이너 서비스 만들기
public class BookService {
@Inject
BookRepository bookrepository;
}
<br>
- ContainerService.java
```java
public static <T> T getObject(T classType)
3부. 리플렉션
1. 스프링의 Depedency Injection은 어떻게 동작할까?
2. 리플렉션 API 1부: 클래스 정보 조회
예시
클래스에 접근하는 방법 3 가지.
콜렉션이 제공하는 기능으로 클래스의 정보를 가져올 수 있다.
3. 애노테이션과 리플렉션
@Retention
: 해당 애노테이션을 언제까지 유지할 것인가? 소스, 클래스, 런타임@Inherit
: 해당 애노테이션을 하위 클래스까지 전달할 것인가?@Target
: 어디에 사용할 수 있는가? (필드, 메소드, 클래스)@Inherit
) 애노테이션까지 조회예시
4. 리플렉션 API 2부: 클래스 정보 수정 또는 실행
예시
5. 나만의 DI 프레임워크 만들기
@Inject
라는 애노테이션 만들어서 필드 주입 해주는 컨테이너 서비스 만들기}
6. 리플렉션 정리
@Entity
클래스에 Setter가 없다면 리플렉션을 사용한다.