프로그래밍백엔드 개발자

자바에서 리플렉션(Reflection)이란 무엇인가요? 그것의 장점, 단점 및 사용 시 잠재적인 위험은 무엇인가요?

Hintsage AI 어시스턴트로 면접 통과

답변

리플렉션은 프로그램 실행 중 클래스, 객체, 메소드 및 필드의 구조와 동작을 조사하고 변경할 수 있는 메커니즘입니다. 이는 java.lang.reflect 패키지를 통해 구현됩니다.

할 수 있는 것:

  • 실행 중 클래스에 대한 정보 얻기
  • 메소드를 호출하고 필드에 동적으로 접근하기
  • 이름으로 클래스의 새 인스턴스 생성하기

예시:

import java.lang.reflect.Method; public class ReflectionExample { public void greet() { System.out.println("Hello!"); } public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("ReflectionExample"); Object instance = clazz.getDeclaredConstructor().newInstance(); Method method = clazz.getMethod("greet"); method.invoke(instance); // 출력: Hello! } }

장점:

  • 유연성 및 확장성 (예: 프레임워크, DI)
  • 미리 타입을 알지 못하더라도 객체와의 작업을 위한 제네릭 코드 가능

단점/위험:

  • 성능 저하
  • 보안 문제 가능성 (접근 제어자 우회)
  • 캡슐화 파괴
  • 유지 보수성이 낮아짐

함정 질문

리플렉션을 통해 클래스의 private 필드 및 메소드에 접근할 수 있나요? 그 결과는 무엇인가요?

답변: 네, Field 또는 MethodsetAccessible(true) 메소드를 통해 가능합니다:

Field field = clazz.getDeclaredField("privateField"); field.setAccessible(true); field.set(obj, "value");

이는 클래스의 캡슐화를 위반하며 위험을 동반합니다: 상황이 취약해지고 보안 오류가 발생할 수 있으며 새로운 JVM 버전에서는 이러한 행위가 접근 정책에 의해 제한될 수 있습니다.

주제의 세부 사항을 몰라서 발생한 실제 오류 사례


이야기

대형 프로젝트에서 리플렉션을 통해 DTO의 자동 매핑을 구현하면서 "Optional" 유형의 필드를 올바르게 처리하지 않아 대량 데이터 처리 시 NullPointerException이 발생했습니다. 리플렉션 패키지는 Optional 값과 null을 구분하지 않았기 때문입니다.


이야기

은행 소프트웨어에서 직렬화를 위해 setAccessible(true)를 통해 private 필드에 접근하는 기능이 구현되었습니다. JVM 업데이트 후 동작이 변경되어 private 필드에 대한 접근이 차단되었고, 중요한 직렬화 기능이 갑자기 프로덕션에서 작동하지 않게 되었습니다.


이야기

ORM 프레임워크에서 프록시 객체를 생성할 때 데이터 스키마 변경 후 리플렉션 캐시를 갱신하는 것을 잊어서 새로운 클래스 필드와의 작업 시 예기치 않은 예외가 발생했습니다. 새로운 필드가 캐시에 반영되지 않았기 때문입니다.