How To - Simple Java Reflection

Reflection is the ability of a computer program to examine, introspect, and modify its own structure and behavior at runtime. Reflection is very useful for creating frameworks, serializers, metaprogramming, among other solutions. Let’s have a quick intro on how to do reflection in Java and how it works.

Suppose we have these classes: 

public abstract class SuperHero {

    private String name;
    private List<String> powers;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<String> getPowers() {
        return powers;
    }

    public void setPowers(List<String> powers) {
        this.powers = powers;
    }
}
public class SpiderMan extends SuperHero {

    private String catchPhrase;

    public String getCatchPhrase() {
        return catchPhrase;
    }

    public void setCatchPhrase(String catchPhrase) {
        this.catchPhrase = catchPhrase;
    }
}

Let’s use reflection to print all the methods names.

public static void main(String args[]) throws Exception {
    printClazzMethods(SpiderMan.class);
}

public static void printClazzMethods(Class clazz) throws IllegalAccessException, InstantiationException {
    for (Method method : clazz.getDeclaredMethods()) {
        System.out.println(method.getName());
    }
}

getCatchPhrase
setCatchPhrase
Process finished with exit code 0

So, what happened? When doing reflection, Java will only give you the declared methods of the given class. If you want to access all the methods, including those in the superclass, you have to explicitly ask for them.

public static void main(String args[]) throws Exception {
    printClazzAndSuperclassMethods(SpiderMan.class);
}

/*----- You can create your own iterate solution -----*/
public static void printClazzAndSuperclassMethods(Class clazz) throws IllegalAccessException, InstantiationException {
    if (clazz.getSuperclass() != Object.class) { // Because I don’t want to print Objet’s methods
        printClazzAndSuperclassMethods(clazz.getSuperclass());
    }
    for (Method method : clazz.getDeclaredMethods()) {
        System.out.println(method.getName());
    }
}

getName
setName
getPowers
setPowers
getCatchPhrase
setCatchPhrase
Process finished with exit code 0

Let us modify our classes to see some of the information we can get from the fields:

public abstract class SuperHero {

    protected String name;
    public List<String> powers;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<String> getPowers() {
        return powers;
    }

    public void setPowers(List<String> powers) {
        this.powers = powers;
    }
}

public class SpiderMan extends SuperHero {

    private String catchPhrase;

    public String getCatchPhrase() {
        return catchPhrase;
    }

    public void setCatchPhrase(String catchPhrase) {
        this.catchPhrase = catchPhrase;
    }
}

By doing a simple field introspection:

public static void main(String args[]) throws Exception {
    printFields(SpiderMan.class);
}

public static void printFields(Class clazz) throws IllegalAccessException, InstantiationException {
    if (clazz.getSuperclass() != Object.class) {
        printFields(clazz.getSuperclass());
    }
    for (Field field : clazz.getDeclaredFields()) {
        // You can see the getModifiers values in Modifier class
        System.out.println("Field " + field.getName() + " has modifier " + field.getModifiers() 
            + " with type " + field.getType());
    }
}

We get:

Field name has modifier 4 with type class java.lang.String
Field powers has modifier 1 with type interface java.util.List
Field catchPhrase has modifier 2 with type class java.lang.String

Process finished with exit code 0

As you can see relfection is not hard at all. Is just a matter of knowing the API and have a clear understanding of what you're trying to solve. There's a lot more you can do with reflection. I will continue posting some more real life escenarios where reflection is very helpful. Remember that reflection is a very expensive operation so you shouldn't be using it just because it's acool way to approach the problem. But if you need to create generic implementations, reflection is a nice way to go!

Tags: 

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.

PHP code

  • You may post PHP code. You should include <?php ?> tags.