Java/The Java
[The Java] 리플렉션 API(1) : 클래스 정보 조회
메성
2021. 1. 3. 22:06
반응형
사용자가 정의한 클래스들은 프로그램 실행 시, 클래스 로더 에 의해 사용자 정의 클래스 타입의 Class 인스턴스들이 힙 영역에 올라간다.
힙 영역에 올라가 있는 사용자 정의 클래스 타입의 Class 인스턴스를 꺼내보자 (3가지 방법)
//Book => 사용자가 정의한 클래스
public class App {
public static void main( String[] args ) throws ClassNotFoundException {
//1. Book.class로 Class 인스턴스에 접근
Class<Book> bookClass = Book.class;
//2. 사용자 애플리케이션에 생성된 인스턴스를 사용하여 Class 인스턴스에 접근
Book book = new Book();
Class<? extends Book> aClass = book.getClass();
//3. 사용자 정의 클래스의 위치로 Class 인스턴스 접근
Class<?> aClass1 = Class.forName("org.example.Book");
}
}
리플렉션 API로 Class가 가지고 있는 정보에 접근해보자.
//사용자 정의 클래스
public class Book {
private static String B = "BOOK";
private static final String C = "BOOK";
private String a = "a";
public String d = "d";
protected String e = "e";
public Book() {}
public Book(String a, String d, String e) {
this.a = a;
this.d = d;
this.e = e;
}
private void f() {
System.out.println("F");
}
public void g() {
System.out.println("g");
}
public int h () {
return 100;
}
}
-
public한 필드만 가져오자
public static void main( String[] args ) throws ClassNotFoundException { Class<Book> bookClass = Book.class; //getFields는 public한 필드만 가져온다. Arrays.stream(bookClass.getFields()).forEach(System.out::println); }
결과
-
접근제한자에 상관없이 모든 필드를 가져오자
public static void main( String[] args ) throws ClassNotFoundException { Class<Book> bookClass = Book.class; //getDeclaredFields는 접근제한자에 상관없이 모든 필드를 가져온다. Arrays.stream(bookClass.getDeclaredFields()).forEach(System.out::println); }
결과
-
접근제한자에 상관없이 모든 필드의 값을 가져와보자(Error)
public static void main( String[] args ) throws ClassNotFoundException {
Class<Book> bookClass = Book.class;
Book book = new Book();
Arrays.stream(bookClass.getDeclaredFields()).forEach(f -> {
try {
System.out.printf("%s %s\n", f, f.get(book));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
});
}
결과
)
- public은 정상적으로 필드값을 가져오나 private은 접근이 불가능하다. 이때는 어떻게 해야할까?
- 접근제한자에 상관없이 모든 필드의 값을 가져와보자(Normal)
public static void main( String[] args ) throws ClassNotFoundException {
Class<Book> bookClass = Book.class;
Book book = new Book();
Arrays.stream(bookClass.getDeclaredFields()).forEach(f -> {
try {
//모든 접근제한자 접근
f.setAccessible(true);
System.out.printf("%s %s\n", f, f.get(book));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
});
}
결과
- setAccessible(true) : 리플렉션을 활용하여 모든 접근제한자에 접근할 수 있다.
- 메소드들을 가져오자(object 상속 받은 것 까지)
public static void main( String[] args ) throws ClassNotFoundException {
Class<Book> bookClass = Book.class;
Arrays.stream(bookClass.getMethods()).forEach(System.out::println);
}
결과
- 생성자를 가져오자
public static void main( String[] args ) throws ClassNotFoundException {
Class<Book> bookClass = Book.class;
Arrays.stream(bookClass.getDeclaredConstructors()).forEach(System.out::println);
}
- 부모 클래스를 가져오자
public static void main( String[] args ) throws ClassNotFoundException {
Class<? super MyBook> superclass = MyBook.class.getSuperclass();
System.out.println(superclass);
}
결과
- 확장한 인터페이스를 가져오자
public static void main( String[] args ) throws ClassNotFoundException {
Arrays.stream(MyBook.class.getInterfaces()).forEach(System.out::println);
}
결과
- getModifier를 사용하여 접근제한자나 static 여부를 확인해보자.
public static void main( String[] args ) throws ClassNotFoundException {
Arrays.stream(Book.class.getDeclaredFields()).forEach(f -> {
int modifiers = f.getModifiers();
System.out.println(f);
System.out.println(Modifier.isPrivate(modifiers));
System.out.println(Modifier.isProtected(modifiers));
System.out.println(Modifier.isStatic(modifiers));
});
}
결과
- 메소드의 여러 정보를 확인하자
public static void main( String[] args ) throws ClassNotFoundException {
Arrays.stream(Book.class.getMethods()).forEach(m -> {
int modifiers = m.getModifiers();
m.get...
});
}
메소드의 여러 정보
반응형