๐ŸŽ“ A1Learner
๐Ÿ”
0 of 30 lessons completed

Java Reflection Basics

Reflection is a program reading its own blueprint while it runs. The Class object is the door to that blueprint.

One class, three doors

Three routes lead to the Class object of String. All three print the same class name, and the last line proves all three are the same object.

public class Main {
  public static void main(String[] args) throws Exception {
    Class<?> first = String.class;
    String word = "hello";
    Class<?> second = word.getClass();
    Class<?> third = Class.forName("java.lang.String");
    System.out.println(first.getName());
    System.out.println(second.getName());
    System.out.println(third.getName());
    System.out.println(first == second && second == third);
  }
}

Declared fields, sorted

The Class object of Book lists its declared fields. The program collects the field names, sorts them, and prints one name per line.

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
  public static void main(String[] args) {
    List<String> names = new ArrayList<>();
    for (Field field : Book.class.getDeclaredFields()) {
      names.add(field.getName());
    }
    Collections.sort(names);
    for (String name : names) {
      System.out.println(name);
    }
  }
}
class Book {
  private String title;
  int pages;
  String author;
}

Declared methods, sorted

The same door lists the methods Book declares. The names sort before printing, so the listing is stable on every run.

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
  public static void main(String[] args) {
    List<String> names = new ArrayList<>();
    for (Method method : Book.class.getDeclaredMethods()) {
      names.add(method.getName());
    }
    Collections.sort(names);
    for (String name : names) {
      System.out.println(name);
    }
  }
}
class Book {
  void borrow() {
  }
  String describe() {
    return "A book";
  }
  String getTitle() {
    return "Dune";
  }
}

Example

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
  public static void main(String[] args) {
    System.out.println("Class: " + Playlist.class.getSimpleName());
    List<String> fieldNames = new ArrayList<>();
    for (Field field : Playlist.class.getDeclaredFields()) {
      fieldNames.add(field.getName());
    }
    Collections.sort(fieldNames);
    System.out.println("Fields:");
    for (String name : fieldNames) {
      System.out.println(name);
    }
    List<String> methodNames = new ArrayList<>();
    for (Method method : Playlist.class.getDeclaredMethods()) {
      methodNames.add(method.getName());
    }
    Collections.sort(methodNames);
    System.out.println("Methods:");
    for (String name : methodNames) {
      System.out.println(name);
    }
  }
}
class Playlist {
  String title;
  int tracks;
  void play() {
  }
  void shuffle() {
  }
}

Key points

  • Every class has one Class object, shared by all its instances.
  • String.class names the class directly in code.
  • getClass() answers the Class object of the object it is called on.
  • Class.forName reads the class name as text and loads that class.
  • getDeclaredFields returns the fields declared in the class itself.
  • getDeclaredMethods returns the methods declared in the class itself.
  • Reflection gives no order promise for fields or methods. Programs sort the names before printing them.

In this example, the Class object of Playlist answers its simple name first. The program then collects its declared field names and its declared method names. Both lists sort before printing, so the whole listing is identical on every run.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

Why do reflection listings in this lesson sort the names before printing?