[{"data":1,"prerenderedAt":713},["ShallowReactive",2],{"post-document:\u002Fjava\u002Fadvanced\u002F2026\u002F08\u002F11\u002Fjava-reflection\u002F":3},{"id":4,"title":5,"body":6,"categories":694,"date":696,"description":697,"extension":698,"image":699,"key_concepts":699,"last_modified_at":699,"legacyPath":700,"meta":701,"navigation":158,"part":703,"path":704,"published":158,"robots":699,"seo":705,"series":706,"stem":707,"strengths":699,"summary":699,"tags":708,"tradeoffs":699,"__hash__":712},"posts\u002Fposts\u002FBackend\u002FJAVA\u002Fadvanced\u002F2026-08-11-java-reflection.md","Java 심화 Part 1: Reflection",{"type":7,"value":8,"toc":681},"minimark",[9,13,18,93,100,104,107,123,130,184,188,201,220,228,240,244,249,277,283,287,315,321,331,335,338,422,427,440,444,451,525,531,538,542,545,564,567,573,580,604,608,624,627,631,637,642,677],[10,11,5],"h2",{"id":12},"java-심화-part-1-reflection",[14,15,17],"h3",{"id":16},"_1-먼저-알아둘-단어","1. 먼저 알아둘 단어",[19,20,21,34],"table",{},[22,23,24],"thead",{},[25,26,27,31],"tr",{},[28,29,30],"th",{},"단어",[28,32,33],{},"정의",[35,36,37,46,54,65,75,85],"tbody",{},[25,38,39,43],{},[40,41,42],"td",{},"Reflection",[40,44,45],{},"실행 중인 클래스나 객체의 구조를 프로그램이 직접 조회하고 조작하는 기능",[25,47,48,51],{},[40,49,50],{},"Metadata",[40,52,53],{},"클래스 이름, 필드, 메서드, 생성자, 애너테이션처럼 클래스 자체에 관한 정보",[25,55,56,62],{},[40,57,58],{},[59,60,61],"code",{},"Class\u003C?>",[40,63,64],{},"특정 클래스의 메타데이터를 다루는 객체",[25,66,67,72],{},[40,68,69],{},[59,70,71],{},"Field",[40,73,74],{},"클래스에 선언된 필드 정보를 나타내는 객체",[25,76,77,82],{},[40,78,79],{},[59,80,81],{},"Method",[40,83,84],{},"클래스에 선언된 메서드 정보를 나타내는 객체",[25,86,87,90],{},[40,88,89],{},"Annotation",[40,91,92],{},"클래스나 메서드 등에 붙여 추가 의미를 전달하는 표식",[94,95,96],"blockquote",{},[97,98,99],"p",{},"Reflection은 프로그램이 실행 중에 클래스의 구조를 직접 조사하고, 필요하면 메서드를 호출하거나 필드 값을 읽고 수정할 수 있게 해주는 기능이다.",[14,101,103],{"id":102},"_2-reflection으로-확인할-수-있는-것","2. Reflection으로 확인할 수 있는 것",[97,105,106],{},"Reflection을 사용하면 실행 중에 다음 정보를 확인할 수 있다.",[108,109,110,114,117,120],"ul",{},[111,112,113],"li",{},"이 클래스 이름이 무엇인지",[111,115,116],{},"어떤 필드가 있는지",[111,118,119],{},"어떤 메서드와 생성자가 있는지",[111,121,122],{},"어떤 애너테이션이 붙어 있는지",[97,124,125,126,129],{},"예제를 위한 ",[59,127,128],{},"User"," 클래스를 먼저 보자.",[131,132,137],"pre",{"className":133,"code":134,"language":135,"meta":136,"style":136},"language-java shiki shiki-themes github-light github-dark","class User {\n    private String name;\n\n    public void hello() {\n        System.out.println(\"hello\");\n    }\n}\n","java","",[59,138,139,147,153,160,166,172,178],{"__ignoreMap":136},[140,141,144],"span",{"class":142,"line":143},"line",1,[140,145,146],{},"class User {\n",[140,148,150],{"class":142,"line":149},2,[140,151,152],{},"    private String name;\n",[140,154,156],{"class":142,"line":155},3,[140,157,159],{"emptyLinePlaceholder":158},true,"\n",[140,161,163],{"class":142,"line":162},4,[140,164,165],{},"    public void hello() {\n",[140,167,169],{"class":142,"line":168},5,[140,170,171],{},"        System.out.println(\"hello\");\n",[140,173,175],{"class":142,"line":174},6,[140,176,177],{},"    }\n",[140,179,181],{"class":142,"line":180},7,[140,182,183],{},"}\n",[14,185,187],{"id":186},"_3-클래스-정보-가져오기","3. 클래스 정보 가져오기",[97,189,190,193,194,196,197,200],{},[59,191,192],{},"User.class","로 ",[59,195,128],{}," 클래스의 정보를 담은 ",[59,198,199],{},"Class"," 객체를 가져올 수 있다.",[131,202,204],{"className":133,"code":203,"language":135,"meta":136,"style":136},"Class\u003CUser> clazz = User.class;\n\nSystem.out.println(clazz.getName());\n",[59,205,206,211,215],{"__ignoreMap":136},[140,207,208],{"class":142,"line":143},[140,209,210],{},"Class\u003CUser> clazz = User.class;\n",[140,212,213],{"class":142,"line":149},[140,214,159],{"emptyLinePlaceholder":158},[140,216,217],{"class":142,"line":155},[140,218,219],{},"System.out.println(clazz.getName());\n",[131,221,226],{"className":222,"code":224,"language":225,"meta":136},[223],"language-text","출력: User\n","text",[59,227,224],{"__ignoreMap":136},[97,229,230,233,234,236,237,239],{},[59,231,232],{},"clazz","에는 ",[59,235,128],{}," 객체 한 개의 데이터가 아니라 ",[59,238,128],{}," 클래스 자체의 구조 정보가 들어 있다.",[14,241,243],{"id":242},"_4-메서드와-필드-조회하기","4. 메서드와 필드 조회하기",[245,246,248],"h4",{"id":247},"메서드-조회","메서드 조회",[131,250,252],{"className":133,"code":251,"language":135,"meta":136,"style":136},"Method[] methods = clazz.getDeclaredMethods();\n\nfor (Method method : methods) {\n    System.out.println(method.getName());\n}\n",[59,253,254,259,263,268,273],{"__ignoreMap":136},[140,255,256],{"class":142,"line":143},[140,257,258],{},"Method[] methods = clazz.getDeclaredMethods();\n",[140,260,261],{"class":142,"line":149},[140,262,159],{"emptyLinePlaceholder":158},[140,264,265],{"class":142,"line":155},[140,266,267],{},"for (Method method : methods) {\n",[140,269,270],{"class":142,"line":162},[140,271,272],{},"    System.out.println(method.getName());\n",[140,274,275],{"class":142,"line":168},[140,276,183],{},[131,278,281],{"className":279,"code":280,"language":225,"meta":136},[223],"출력: hello\n",[59,282,280],{"__ignoreMap":136},[245,284,286],{"id":285},"필드-조회","필드 조회",[131,288,290],{"className":133,"code":289,"language":135,"meta":136,"style":136},"Field[] fields = clazz.getDeclaredFields();\n\nfor (Field field : fields) {\n    System.out.println(field.getName());\n}\n",[59,291,292,297,301,306,311],{"__ignoreMap":136},[140,293,294],{"class":142,"line":143},[140,295,296],{},"Field[] fields = clazz.getDeclaredFields();\n",[140,298,299],{"class":142,"line":149},[140,300,159],{"emptyLinePlaceholder":158},[140,302,303],{"class":142,"line":155},[140,304,305],{},"for (Field field : fields) {\n",[140,307,308],{"class":142,"line":162},[140,309,310],{},"    System.out.println(field.getName());\n",[140,312,313],{"class":142,"line":168},[140,314,183],{},[131,316,319],{"className":317,"code":318,"language":225,"meta":136},[223],"출력: name\n",[59,320,318],{"__ignoreMap":136},[97,322,323,326,327,330],{},[59,324,325],{},"getDeclaredMethods()","와 ",[59,328,329],{},"getDeclaredFields()","는 해당 클래스에 직접 선언된 메서드와 필드를 가져온다.",[14,332,334],{"id":333},"_5-실행-중에-메서드-호출하기","5. 실행 중에 메서드 호출하기",[97,336,337],{},"Reflection을 사용하면 메서드 이름을 문자열로 찾아 실행할 수도 있다.",[131,339,341],{"className":133,"code":340,"language":135,"meta":136,"style":136},"import java.lang.reflect.Method;\n\nclass User {\n    public void hello() {\n        System.out.println(\"hello\");\n    }\n}\n\npublic class ReflectionExample {\n    public static void main(String[] args) throws ReflectiveOperationException {\n        User user = new User();\n\n        Method method = User.class.getDeclaredMethod(\"hello\");\n        method.invoke(user);\n    }\n}\n",[59,342,343,348,352,356,360,364,368,372,377,383,389,395,400,406,412,417],{"__ignoreMap":136},[140,344,345],{"class":142,"line":143},[140,346,347],{},"import java.lang.reflect.Method;\n",[140,349,350],{"class":142,"line":149},[140,351,159],{"emptyLinePlaceholder":158},[140,353,354],{"class":142,"line":155},[140,355,146],{},[140,357,358],{"class":142,"line":162},[140,359,165],{},[140,361,362],{"class":142,"line":168},[140,363,171],{},[140,365,366],{"class":142,"line":174},[140,367,177],{},[140,369,370],{"class":142,"line":180},[140,371,183],{},[140,373,375],{"class":142,"line":374},8,[140,376,159],{"emptyLinePlaceholder":158},[140,378,380],{"class":142,"line":379},9,[140,381,382],{},"public class ReflectionExample {\n",[140,384,386],{"class":142,"line":385},10,[140,387,388],{},"    public static void main(String[] args) throws ReflectiveOperationException {\n",[140,390,392],{"class":142,"line":391},11,[140,393,394],{},"        User user = new User();\n",[140,396,398],{"class":142,"line":397},12,[140,399,159],{"emptyLinePlaceholder":158},[140,401,403],{"class":142,"line":402},13,[140,404,405],{},"        Method method = User.class.getDeclaredMethod(\"hello\");\n",[140,407,409],{"class":142,"line":408},14,[140,410,411],{},"        method.invoke(user);\n",[140,413,415],{"class":142,"line":414},15,[140,416,177],{},[140,418,420],{"class":142,"line":419},16,[140,421,183],{},[131,423,425],{"className":424,"code":280,"language":225,"meta":136},[223],[59,426,280],{"__ignoreMap":136},[97,428,429,432,433,193,436,439],{},[59,430,431],{},"getDeclaredMethod(\"hello\")","로 메서드를 찾고, ",[59,434,435],{},"invoke(user)",[59,437,438],{},"user"," 객체에서 그 메서드를 실행한다.",[14,441,443],{"id":442},"_6-private-필드-접근","6. private 필드 접근",[97,445,446,447,450],{},"Reflection을 사용하면 ",[59,448,449],{},"private"," 필드에도 접근을 시도할 수 있다.",[131,452,454],{"className":133,"code":453,"language":135,"meta":136,"style":136},"import java.lang.reflect.Field;\n\nclass User {\n    private String name = \"민형\";\n}\n\npublic class ReflectionExample {\n    public static void main(String[] args) throws ReflectiveOperationException {\n        User user = new User();\n\n        Field field = User.class.getDeclaredField(\"name\");\n        field.setAccessible(true);\n\n        System.out.println(field.get(user));\n    }\n}\n",[59,455,456,461,465,469,474,478,482,486,490,494,498,503,508,512,517,521],{"__ignoreMap":136},[140,457,458],{"class":142,"line":143},[140,459,460],{},"import java.lang.reflect.Field;\n",[140,462,463],{"class":142,"line":149},[140,464,159],{"emptyLinePlaceholder":158},[140,466,467],{"class":142,"line":155},[140,468,146],{},[140,470,471],{"class":142,"line":162},[140,472,473],{},"    private String name = \"민형\";\n",[140,475,476],{"class":142,"line":168},[140,477,183],{},[140,479,480],{"class":142,"line":174},[140,481,159],{"emptyLinePlaceholder":158},[140,483,484],{"class":142,"line":180},[140,485,382],{},[140,487,488],{"class":142,"line":374},[140,489,388],{},[140,491,492],{"class":142,"line":379},[140,493,394],{},[140,495,496],{"class":142,"line":385},[140,497,159],{"emptyLinePlaceholder":158},[140,499,500],{"class":142,"line":391},[140,501,502],{},"        Field field = User.class.getDeclaredField(\"name\");\n",[140,504,505],{"class":142,"line":397},[140,506,507],{},"        field.setAccessible(true);\n",[140,509,510],{"class":142,"line":402},[140,511,159],{"emptyLinePlaceholder":158},[140,513,514],{"class":142,"line":408},[140,515,516],{},"        System.out.println(field.get(user));\n",[140,518,519],{"class":142,"line":414},[140,520,177],{},[140,522,523],{"class":142,"line":419},[140,524,183],{},[131,526,529],{"className":527,"code":528,"language":225,"meta":136},[223],"출력: 민형\n",[59,530,528],{"__ignoreMap":136},[97,532,533,534,537],{},"다만 ",[59,535,536],{},"setAccessible(true)","는 캡슐화를 우회하는 기능이다. Java 모듈 환경에서는 접근이 제한될 수도 있으므로, 일반 애플리케이션 코드에서 무분별하게 사용하면 안 된다.",[14,539,541],{"id":540},"_7-spring에서-reflection을-사용하는-이유","7. Spring에서 Reflection을 사용하는 이유",[97,543,544],{},"Spring 같은 프레임워크는 실행 중에 클래스를 조사해야 한다.",[131,546,548],{"className":133,"code":547,"language":135,"meta":136,"style":136},"@Service\npublic class UserService {\n}\n",[59,549,550,555,560],{"__ignoreMap":136},[140,551,552],{"class":142,"line":143},[140,553,554],{},"@Service\n",[140,556,557],{"class":142,"line":149},[140,558,559],{},"public class UserService {\n",[140,561,562],{"class":142,"line":155},[140,563,183],{},[97,565,566],{},"Spring은 대략 다음 흐름으로 동작한다.",[131,568,571],{"className":569,"code":570,"language":225,"meta":136},[223],"클래스들을 조사한다\n    ↓\n@Service가 붙은 클래스를 찾는다\n    ↓\n관리할 객체를 생성한다\n    ↓\nBean으로 등록한다\n    ↓\n필요한 곳에 의존성을 주입한다\n",[59,572,570],{"__ignoreMap":136},[97,574,575,576,579],{},"예를 들어 ",[59,577,578],{},"@Autowired","가 붙은 필드를 확인해 해당 타입의 객체를 넣어 주는 과정에도 Reflection이 활용될 수 있다.",[131,581,583],{"className":133,"code":582,"language":135,"meta":136,"style":136},"class OrderService {\n    @Autowired\n    private UserService userService;\n}\n",[59,584,585,590,595,600],{"__ignoreMap":136},[140,586,587],{"class":142,"line":143},[140,588,589],{},"class OrderService {\n",[140,591,592],{"class":142,"line":149},[140,593,594],{},"    @Autowired\n",[140,596,597],{"class":142,"line":155},[140,598,599],{},"    private UserService userService;\n",[140,601,602],{"class":142,"line":162},[140,603,183],{},[14,605,607],{"id":606},"_8-사용할-때-주의할-점","8. 사용할 때 주의할 점",[108,609,610,613,616,621],{},[111,611,612],{},"일반 코드보다 느릴 수 있다.",[111,614,615],{},"컴파일러가 확인해 주는 타입 안정성이 약해질 수 있다.",[111,617,618,620],{},[59,619,449],{}," 접근 제한을 우회할 수 있어 코드 추적이 어려워진다.",[111,622,623],{},"프레임워크 내부 기능이나 정말 동적으로 처리해야 하는 경우에 사용하는 편이 좋다.",[97,625,626],{},"Spring, Hibernate, Jackson, 테스트 프레임워크처럼 클래스 구조를 자동으로 분석해야 하는 라이브러리와 프레임워크에서 Reflection을 많이 사용한다.",[14,628,630],{"id":629},"_9-요약","9. 요약",[131,632,635],{"className":633,"code":634,"language":225,"meta":136},[223],"Reflection\n    ↓\n실행 중에 클래스 구조를 조사한다\n    ↓\n필드, 메서드, 생성자, 애너테이션 정보를 확인한다\n    ↓\n필요하면 메서드 호출과 필드 접근도 가능하다\n",[59,636,634],{"__ignoreMap":136},[94,638,639],{},[97,640,641],{},"Reflection은 런타임에 클래스의 메타데이터를 조회하고 조작하는 기능이다. 강력하지만 타입 안정성과 캡슐화를 약화시킬 수 있으므로, 주로 프레임워크 내부나 동적 처리가 꼭 필요한 상황에서 사용한다.",[108,643,644,655,666],{},[111,645,646,647],{},"런타임 동적 로딩 및 조작\n",[108,648,649,652],{},[111,650,651],{},"컴파일 시점이 아닌 실행 중에 객체 정보를 확인하거나 수정 가능",[111,653,654],{},"클래스 이름이 동적으로 결정되거나, 조건에 따라 특정 메서드를 실행해야 할 때 사용",[111,656,657,658],{},"어노테이션 기반 동작 제어\n",[108,659,660,663],{},[111,661,662],{},"런타임에 Annotation을 읽어서 특정 메서드나 필드에 대해 자동 동작을 수행",[111,664,665],{},"예: Spring에서 Autowired로 의존성 주입, RequestMapping으로 URL 메서드 매핑",[111,667,668,669],{},"플러그인 시스템 및 동적 확장\n",[108,670,671,674],{},[111,672,673],{},"실행 중에 플러그인 추가, 또는 인터페이스를 구현하지 않은 클래스도 동적으로 실행 가능",[111,675,676],{},"외부 패키지의 클래스를 런타임에 로드하여 확장 기능 구현 가능",[678,679,680],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":136,"searchDepth":149,"depth":149,"links":682},[683],{"id":12,"depth":149,"text":5,"children":684},[685,686,687,688,689,690,691,692,693],{"id":16,"depth":155,"text":17},{"id":102,"depth":155,"text":103},{"id":186,"depth":155,"text":187},{"id":242,"depth":155,"text":243},{"id":333,"depth":155,"text":334},{"id":442,"depth":155,"text":443},{"id":540,"depth":155,"text":541},{"id":606,"depth":155,"text":607},{"id":629,"depth":155,"text":630},[135,695],"advanced","2026-08-11 10:40:00 +0900","Java Reflection으로 런타임에 클래스, 필드, 메서드, 애너테이션 정보를 조회하고 호출하는 방법을 정리한다.","md",null,"\u002Fjava\u002Fadvanced\u002F2026\u002F08\u002F11\u002Fjava-reflection\u002F",{"layout":702},"post","1","\u002Fposts\u002Fbackend\u002Fjava\u002Fadvanced\u002F2026-08-11-java-reflection",{"title":5,"description":697},"Java 심화","posts\u002FBackend\u002FJAVA\u002Fadvanced\u002F2026-08-11-java-reflection",[709,42,50,89,710,711],"Java","Spring","DI","4QYtLrWc5QYYhvZSROb6iUxRUpxBVsP3WTUxBV8MxaE",1788744784442]