I'll speak on behalf of C#, though this isn't much different from Java.
When you have a type system similar to C#, there are a lot of things you can learn about a given data type. In fact, you can learn so much about it, you would never have to have ever seen/known about the type in advance to learn everything you need to know about it.
What I just described is what reflection can do for you. Reflection is the ability to, in a sense, query a type about its capabilities, and even call methods.
As an example, in C#, all objects provide the "GetType()" function. So, we might have something like this (assume var is just some object):
System.Type t = var.GetType();
OK, now we have the type. With the type, we can now query it...Properties is a member Property (C# supports true properties, Java does not) of class Type, and this essentially returns an array of PropertyInfo objects.
foreach (PropertyInfo pi in t.Properties)
{
Console.WriteLine("Property Name: " + pi.Name;
}
As I said, there are also mechanisms where I can use reflection to actually invoke methods contained within objects.
Reflection can ve very powerful, but as you might imagine, is not fast at all. I have used it in places that make some things easier, but you definitely have to make sure that performance is not critical.