자바 Reflection이란 무엇인가? #17
Replies: 5 comments
자바 Reflection이 무엇인지 자유롭게 서술해주세요.자바 리플렉션이란 Spring 프레임워크에서 핵심적으로 상요하고 있는 자바의 기능 중 하나로, 프로그램이 실행 중(runtime에 자기 자신을 들여다보고 분석하는 기능이다. 코드가 마치 거울을 보듯 자신의 내부 구조(클래스, 메서드, 필드 등)를 파악하고, 심지어는 그 구조를 변경하거나 조작할 수 있게 해주는 강력한 도구이다. 리플렉션은 일반적인 애플리케이션 코드보다는, 특정 기술이나 규약에 의존하지 않는 범용적인 기능을 만들어야 하는 프레임워크나 라이브러리에서 핵심적인 역할을 하게 된다. 리플렉션의 원리를 알기 위해서는 컴파일 시점의 JVM 동작 원리를 알아볼 필요가 있다. 1단계: 컴파일 (.java >> .class) 리플렉션의 거의 모든 작업은 클래스가 로드될 때 JVM이 힙 영역에 저장하는 리플렉션을 사용하면 문자열 이름만으로 클래스를 제어할 수 있다. 심지어 private 접근 제한까지 우회하여 내부 상태를 읽고 수정할 수 있다. [ 사용 예1. Spring에서 의존성 주입(DI) ] Spring 컨테이너가 UserService 객체에 UserRepository를 주입하는 과정을 리플렉션 관점에서 보면 아래와 같다.
[ 사용 예2. JPA 등 ORM 프레임워크 ]
[ 사용 예3. JUnit 등 테스트 프레임워크 ]
이 덕분에 개발자가 테스트 메서드를 일일이 호출하는 main 메서드를 만들 필요가 없어진다. [ 유의사항1. 성능저하 ] [ 유의사항2. 캡슐화 파괴 ] [ 유의사항3. 컴파일 타임 안정성 ] |
자바 Reflection이 무엇인지 자유롭게 서술해주세요.→ 클래스 타입을 알지 못해도 해당 클래스의 메서드나 타입 등에 접근이 가능하게하는 api입니다. 컴파일이 아니라 실행시간에 동적으로 특정 클래스의 정보를 추출할 수 있는 프로그래밍 기법입니다. //리플렉션 없을때
Book book = new Book();
book.lib();
// 컴파일에서는 Book타입과 lib() 메서드를 알고 있음//리플렉션 사용시
String className ="Book";
Class<?> aaa = class.forName(className);
Object ooo = aaa.getDeclaredConstructor().newInstance();
Method mehod = aaa.getMethod("lib");
method.invoke(ooo);
//클래스 정보, 메서드 정보 얻음클래스 변수에 문자가 들어있다면 클래스 정보를 찾고 인스턴스 생성하고 메서드도 호출하게 됩니다. 프레임 워크나 라이브러리에서 사용되는 라이브러리 코드의 구조를 파악하거나, 메타 데이터를 처리할떄 유용합니다. |
자바 Reflection이란 무엇인가? #17자바 Reflection이 무엇인지 자유롭게 서술해주세요.리플렉션은 런타임에 클래스와 인터페이스 등을 검사하고 조작할 수 있는 기능으로, 즉 자바의 메서드 영역에 저장된 메타 정보를 사용하여 실행 중에 객체의 필드나 메서드에 접근하고 변경하는 기술이다. 클래스 객체를 통해 정보에 접근하며, setAccessible(true)를 사용하여 접근 제한자(private 등)를 우회하여 필드 값을 읽거나 수정할 수 있다. private필드 값을 수정하는 것 자체가 객체지향 원칙 중 캡슐화를 위배할 위험이 있다고 볼 수 있으므로, 일반적인 비즈니스 로직 구현에서는 리플렉션의 사용을 지양하는 게 좋다. 다만 런타임에 사용자의 입력이나 설정에 따라 유연하게 기능을 제어하거나 상호작용해야 하는, 런타임에 동적인 기능 제어가 필요한 프레임워크/라이브러리 개발 시에는 유용하다. 예를 들어 의존성 주입(IoC)이나 전략 패턴을 런타임에 동적으로 구현할 때 유용하다. 코드 예시)
public class Client {
public void execute(String type) {
MovingStrategy strategy;
if ("default".equals(type)) strategy = new DefaultStrategy();
else strategy = new RandomStrategy(); strategy.move();
}
}
//안정적이지만 확장 시 코드 수정이 필요
public class DynamicClient {
public void execute(String className) throws Exception { // 클래스 이름을 통해 동적으로 인스턴스 생성
Class clazz = Class.forName(className);
MovingStrategy strategy = (MovingStrategy)
clazz.getDeclaredConstructor().newInstance();
strategy.move();
}
}
//유연하지만 런타임 오류 위험 및 성능 저하 발생
public interface MovingStrategy { void move(); }
public class DefaultStrategy implements MovingStrategy {
public void move() {
System.out.println("기본 이동");
}
}
public class RandomStrategy implements MovingStrategy {
public void move() {
System.out.println("랜덤 이동");
}
}https://www.youtube.com/watch?v=RZB7_6sAtC4 추가적 공부할거) 성능 오버헤드의 구체적 이유: 리플렉션이 왜 느린지에 대해 단순히 '느리다'는 결과뿐만 아니라, JVM이 컴파일 시점에 최적화(인라인화 등)를 할 수 없는 구조적 이유(메타데이터 접근 비용 등)를 파악하면 더 완벽한 이해가 가능합니다. |
|
일반적으로 우리는 코드를 작성하는 시점인 컴파일 타임에 어떤 클래스와 메서드를 사용할지 미리 정해두고 개발하지만, 리플렉션은 코드가 실행되는 런타임 시점에 컴파일된 클래스 정보를 거울처럼 들여다보고 그 안의 필드나 메서드 정보를 추출하고 조작할 수 있는 기법을 말한다. 스프링 프레임워크 같은 라이브러리를 만들 때 우리는 사용자가 나중에 어떤 이름의 클래스를 만들지 전혀 모르는 상태에서 코드를 짜야 하는데, 이때 스프링은 개발자가 new 키워드로 직접 객체를 생성하는 대신 사용자가 작성한 클래스 이름만 문자열로 넘겨받아 리플렉션을 통해 동적으로 객체를 생성하고 관리한다. 이러한 리플렉션은 컴파일 당시에는 알 수 없는 클래스도 런타임에 동적으로 로드할 수 있다는 강력한 유연성을 제공하지만, 타입 검사가 런타임에 이루어져 일반적인 메서드 호출보다 성능이 훨씬 느리고, 존재하지 않는 멤버를 문자열로 입력했을 때 컴파일 에러 없이 실행 시점에 NoSuchMethodException이 터져 디버깅이 어려워지며, private 멤버까지 강제로 접근해 객체 지향의 캡슐화 원칙을 깰 수 있다는 단점이 있다. |
|
먼저 컴파일,런타임,다형성에 대해 알고있어야한다. reflection 이란? 이름이 진짜로 존재하는지를 컴파일 시점이 아니라 런타임에 확인하는 방식으로 클래스의 구조(필드, 메서드 등)를 다루는 것 검증 책임을 컴파일 시점에서 런타임으로 미루는 기술 reflection이 왜 필요해?
|
Uh oh!
There was an error while loading. Please reload this page.
📆 일자: 26년 7월 22일(수)
오늘의 질문
자바 Reflection이 무엇인지 자유롭게 서술해주세요.
All reactions