일반적으로 반사의 단점
리플렉션은 직선 코드보다 이해하기 어렵습니다.
내 경험상 리플렉션은 Java의 "전문가 수준"기능입니다. 나는 대부분의 프로그래머들이 리플렉션을 적극적으로 사용하지 않는다고 주장한다 (즉 리플렉션을 사용하는 라이브러리를 소비하는 것은 중요하지 않다). 따라서 프로그래머가 코드를 이해하기 어렵습니다.
정적 분석에는 반사 코드에 액세스 할 수 없습니다
getFoo
클래스에 게터 가 있고 이름을로 바꾸고 싶다고 가정 합니다 getBar
. 리플렉션을 사용하지 않으면 코드베이스를 검색하고 getFoo
getter를 사용하는 모든 장소를 찾을 수 있으므로 업데이트 할 수 있으며 누락 된 경우에도 컴파일러가 불평합니다.
그러나 getter를 사용하는 장소가 callGetter("Foo")
and callGetter
does getClass().getMethod("get"+name).invoke(this)
인 경우 위의 방법으로 찾지 못하고 컴파일러는 불평하지 않습니다. 코드가 실제로 실행될 때만을 얻을 수 있습니다 NoSuchMethodException
. 그리고 그 예외 (추적 된)가 callGetter
"하드 코딩 된 문자열에만 사용되며 실제로는 일어날 수 없기 때문에" 삼켜 질 때의 고통을 상상해보십시오 . OP가 자신의 SO 답변에서 정확히 그렇게 한 것을 제외하고 는 필드 이름이 변경되면 일반 세터 사용자는 아무런 조치도 취하지 않는 세터의 매우 모호한 버그를 제외하고는 알 수 없습니다. 운이 좋으면 getter 사용자는 무시 된 예외의 콘솔 출력을 볼 수 있습니다.)
컴파일러가 리플렉션 코드를 타입 검사하지 않음
이것은 기본적으로 위의 큰 하위 지점입니다. 리플렉션 코드는 모든 것 Object
입니다. 런타임에 유형을 확인합니다. 오류는 단위 테스트에서 발견되지만 적용 범위가있는 경우에만 발견됩니다. ( "이것은 단지 getter 일 뿐이다. 테스트 할 필요는 없다")
리플렉션 코드를 최적화에 사용할 수 없습니다
이론적으로는 아니지만 실제로는 인라인 캐시를 인라인하거나 생성하는 JVM을 찾을 수 없습니다 Method.invoke
. 이러한 최적화를 위해 일반적인 메소드 호출을 사용할 수 있습니다. 그것들은 훨씬 더 빠릅니다.
리플렉션 코드는 일반적으로 느립니다
리플렉션 코드에 필요한 동적 메서드 조회 및 형식 검사는 일반 메서드 호출보다 느립니다. 값싼 한 줄의 게터를 반사 짐승으로 바꾸면 (이것을 측정하지는 않았 음) 여러 단계의 속도 저하를보고있을 것입니다.
일반적인 게터 / 세터의 단점
클래스에 더 이상 캡슐화가 없기 때문에 이것은 나쁜 생각입니다. 모든 필드에 액세스 할 수 있습니다. 그것들을 모두 공개 할 수도 있습니다.