Reflection Basics
Class — a runtime description of a type
Ordinary Java code usually works with objects and calls methods known in advance.
Reflection is useful when a program needs to inspect the type itself at runtime:
find its name, superclass, interfaces, annotations, or available members.
The entry point is a Class<?> object.
Class<String> type = String.class;
System.out.println(type.getName());
System.out.println(type.getSimpleName());
A Class object is not an instance of String.
It represents the description of the String type itself in the running JVM.
How to obtain Class
When the type is known in code, the simplest option is the .class literal.
If you already have an object, its runtime type can be obtained through getClass().
String text = "hello";
Class<String> first = String.class;
Class<? extends String> second = text.getClass();
When a class name arrives as a string at runtime,
Class.forName() is available. This form appears in infrastructure code
where the concrete type is not known to the source code in advance.
Class<?> type = Class.forName("java.util.ArrayList");
System.out.println(type.getSimpleName());
What can be learned about a type
Through Class, you can check whether the represented type is an interface, enum, record, or array,
obtain its package, superclass, and implemented interfaces, and then move on to fields, methods,
constructors, and annotations. We will examine these groups separately so that reflection does not turn into a list of API methods.