Reflection in Java allows a program to access and manipulate its own structure, behavior, and configuration at runtime. It works by storing metadata about classes, fields, methods and constructors that can then be accessed dynamically. The key advantages are signature-based polymorphism, inspecting and manipulating classes flexibly without knowing their structure at compile-time. However, reflection is slower than direct code and exposes implementation details, posing some security risks.