리플렉션 기능(java.lang.reflect)을 이용하면 프로그램에서 임의의 클래스에 접근할 수 있다. Class 객체가 주어지면 그 클래스의 생성자, 메서드, 필드에 해당하는 constructor, Method, Field 인스턴스를 가져올 수 있고, 이어서 이어서 그 클래스의 멤버 이름, 필드 타입, 시그니처 등을 가져올 수 있다.
예를 들어 Method.invoke()는 어떤 클래스의 어떤 객체가 가진 어떤 메서드라도 호출할 수 있게 해준다.
이처럼 리플렉션을 사용하면 컴파일 당시에 존재하지 않는 클래스도 이용할 수 있는데, 물론 단점이 있다.
리플렉션은 아주 제한된 형태로만 사용해야 그 단점을 피하고 이점을 취할 수 있다
드물긴 하지만, 리플렉션은 런타임에 존재하지 않을 수도 있는 다른 클래스, 메서드, 필드와의 의존성을 관리할 때 적합하다. 이 기법은 버전이 여러개 존재하는 외부 패키지를 다룰 때 유용하다. 가동할 수있는 최소환의 환경, 즉 주로 가장 오래된 버전만을 지원하도록 컴파일한 후, 이후 버전의 크래스와 메서드 등은 리플렉션으로 접근하는 방식이다.
리플렉션은 복잡한 특수 시스템을 개발할 때 필요한 강력한 기능이지만, 단점도 많다. 컴파일 타임에는 알 수 없는 클래스를 사용하는 프로그램을 작성한다면 리플렉션을 사용해야 할 것이다. 단 되도록 객체 생성에만 사용하고, 생성한 객체를 이용할 때는 적절한 인터페이스나 컴파일 타임에 알 수 있는 상위 클래스로 형변환해 사용해야 한다.