Java Invoking Code by Reflection
Reflective invocation calls methods and builds objects chosen by name at runtime. The compiler never sees the call, so the program checks names itself while it runs.
A method chosen by name text
The name greet sits in a String variable, and invoke calls the method it names. The printed line is the return value of that call.
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) throws Exception {
Greeter greeter = new Greeter();
String chosen = "greet";
Method method = Greeter.class.getDeclaredMethod(chosen);
Object result = method.invoke(greeter);
System.out.println(result);
}
}
class Greeter {
public String greet() {
return "Hello from greet";
}
public String farewell() {
return "Goodbye from farewell";
}
}A constructor builds the object
getDeclaredConstructor finds the two-argument constructor of Book. newInstance runs it with real arguments, and the built fields print.
import java.lang.reflect.Constructor;
public class Main {
public static void main(String[] args) throws Exception {
Constructor<Book> ctor = Book.class.getDeclaredConstructor(String.class, int.class);
Book book = ctor.newInstance("Dune", 412);
System.out.println(book.title);
System.out.println(book.pages);
}
}
class Book {
String title;
int pages;
Book(String title, int pages) {
this.title = title;
this.pages = pages;
}
}setAccessible reads a private field
The code field of Vault is private, so normal code cannot read it. setAccessible opens that one field, and get reads its value.
import java.lang.reflect.Field;
public class Main {
public static void main(String[] args) throws Exception {
Vault vault = new Vault();
Field field = Vault.class.getDeclaredField("code");
field.setAccessible(true);
System.out.println(field.get(vault));
}
}
class Vault {
private String code = "sunrise-42";
}A missing method name is caught
No method named missing exists on Greeter, so the lookup throws NoSuchMethodException. The catch block prints the program line and the program ends normally.
public class Main {
public static void main(String[] args) {
try {
Greeter.class.getDeclaredMethod("missing");
System.out.println("Method found");
} catch (NoSuchMethodException e) {
System.out.println("No method named missing");
}
}
}
class Greeter {
public String greet() {
return "Hello from greet";
}
}Example
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) throws Exception {
Constructor<Ticket> ctor = Ticket.class.getDeclaredConstructor(String.class);
Ticket ticket = ctor.newInstance("B7");
Method label = Ticket.class.getDeclaredMethod("label");
System.out.println(label.invoke(ticket));
Field seat = Ticket.class.getDeclaredField("seat");
seat.setAccessible(true);
System.out.println(seat.get(ticket));
}
}
class Ticket {
private String seat;
Ticket(String seat) {
this.seat = seat;
}
public String label() {
return "Seat " + seat;
}
}Key points
- getDeclaredMethod finds a method by its name text and its parameter types.
- invoke runs that method on an object and returns its result as an Object.
- A Constructor object builds instances with newInstance and real arguments.
- setAccessible opens one private member to one reflection object.
- A missing method name fails at lookup time with NoSuchMethodException.
- Strong encapsulation pushes back against setAccessible. The modules lesson shows why it can be refused.
In this example, reflection builds a Ticket through its Constructor object with the seat text B7. A Method object then invokes label by name, and its return value prints. A Field object with setAccessible reads the private seat field, and that value prints on the second line.
Note
Reflective calls skip compile-time checking. A wrong name is a runtime failure, not a compile error.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
A program asks reflection for a method name that the class does not declare. What happens?