Java gets methods and variables through reflection

0, reflection technology

Reflection technology is an important part of the Java ecosystem and has been widely used in Spring and other frameworks.

With reflection technology, we can:

  • construct an object of any class,

  • Know the class to which any object belongs,

  • Know all member variables and methods in any class,

  • Call properties and methods in any class.

1. Obtaining method

1.1, create entity classes

The entity class contains private methods, public methods, private variables, and public variables.

public class Student {
    private String name;
    private Integer age;
    public String className;

    public Student() {
    }

    private Student(String name) {
        this.name = name;
    }

    public Student(Integer age) {
        this. age = age;
    }

    public Student(String name, Integer age) {
        this.name = name;
        this. age = age;
    }

    private void getAge(){
        System.out.println("This is a private method");
    }

    public void getName(){
        System.out.println("This is a public method");
    }

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

    public void setAge(Integer age) {
        this. age = age;
    }

    public void setClassName(String className) {
        this. className = className;
    }
}

1.1, get the construction method

1.1.1 Get all constructors in the class

First, you need to get the class object through the method mentioned in the previous article, and then get all the constructors under the class through getDeclaredConstructors().

import java.lang.reflect.Constructor;

public class Test {
    public static void main(String[] args) {
        Class<Student> student = Student. class;
        Constructor<?>[] constructors = student. getDeclaredConstructors();

        for (Constructor constructor : constructors){
            System.out.println(constructor);
        }
    }
}

The output results are as follows:

public com.reflect.Student(java.lang.String,java.lang.Integer)

public com.reflect.Student(java.lang.Integer)

private com.reflect.Student(java.lang.String)

public com. reflect. Student()

From the output results, we can see that all four construction methods in the entity class have been obtained, including a private construction method. And the parameter list in the constructor can also be taken out.

1.1.2 Get all public constructors

Unlike the reflection method that gets all constructors, just use getConstructors() here.

import java.lang.reflect.Constructor;

public class Test {
    public static void main(String[] args) {
        Class<Student> student = Student. class;
        Constructor<?>[] constructors = student. getConstructors();

        for (Constructor constructor : constructors){
            System.out.println(constructor);
        }
    }
}

The output is as follows:

public com.reflect.Student(java.lang.String,java.lang.Integer)

public com.reflect.Student(java.lang.Integer)

public com. reflect. Student()

There is no private constructor in the class, only public methods.

1.1.3 Obtain the corresponding construction method according to the parameter list

If we want to get a specific constructor according to the parameter list, we can use the getDeclaredConstructor() method, which specifies the parameters required by the constructor:

  • All parameters must use class objects;
  • The order of parameters should be consistent with the order in the constructor;
  • To get a parameterless constructor, you can enter null as a parameter, or empty;
  • This method may generate an exception that the method cannot be found, so the exception needs to be caught or thrown.
import java.lang.reflect.Constructor;

public class Test {
    public static void main(String[] args) {
        try {
            Class<Student> student = Student. class;
            //Get the private constructor
            Constructor<?> constructor = student. getDeclaredConstructor(String. class);
            System.out.println(constructor);
            // Get the public constructor
            Constructor<?> constructor2 = student.getDeclaredConstructor(String.class, Integer.class);
            System.out.println(constructor2);
            //Get the no-argument constructor
            Constructor<?> constructor3 = student. getDeclaredConstructor(null);
            System.out.println(constructor3);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

The output is

private com.reflect.Student(java.lang.String)

public com.reflect.Student(java.lang.String,java.lang.Integer)

public com. reflect. Student()

  • If you only want to get the constructor of the public type, you can use the getConstructor() method. When the corresponding constructor is private, an exception java.lang.NoSuchMethodException will be reported;
  • If no corresponding method is found according to the parameter list, the program will report an exception java.lang.NoSuchMethodException.

1.2. Obtain common methods

1.2.1 Get all common methods

Use the getDeclaredMethods() of the class object to get all the common methods (non-constructor methods) under the current class.

import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) {
        Class<Student> student = Student. class;
        //Get all methods
        Method[] declaredMethods = student. getDeclaredMethods();
        for (Method method : declaredMethods){
            System.out.println(method);
        }
    }
}

The output is

public void com.reflect.Student.getName()

public void com.reflect.Student.setName(java.lang.String)

private void com.reflect.Student.getAge()

public void com.reflect.Student.setAge(java.lang.Integer)

public void com.reflect.Student.setClassName(java.lang.String)

Both private and public methods are obtained.

1.2.2 Get all public common methods

Using the getMethods() of the class object, you can get all the common methods (non-constructor methods) modified by public under the current class and all parent classes.

import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) {
        Class<Student> student = Student. class;
        //Get all methods
        Method[] declaredMethods = student. getMethods();
        for (Method method : declaredMethods){
            System.out.println(method);
        }
    }
}

The output results include all methods modified by public under the Student class and the default parent class Object class.

public void com.reflect.Student.getName()

public void com.reflect.Student.setName(java.lang.String)

public void com.reflect.Student.setAge(java.lang.Integer)

public void com.reflect.Student.setClassName(java.lang.String)

public final void java.lang.Object.wait() throws java.lang.InterruptedException

public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException

public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException

public boolean java.lang.Object.equals(java.lang.Object)

public java.lang.String java.lang.Object.toString()

public native int java.lang.Object.hashCode()

public final native java.lang.Class java.lang.Object.getClass()

public final native void java.lang.Object.notify()

public final native void java.lang.Object.notifyAll()

1.2.3 Get the specified method according to the specified method name and parameter list

  • If the method to be obtained is public, use the getMethod() method;

  • If you want to get a private method, you need to use the getDeclaredMethod() method.

  • Because there is a method with the same name, you need to specify the method name to be obtained as the first parameter in the getMethod() method, followed by the parameter list;

  • When there is no parameter method, the parameter list can be empty, or use null to represent;

  • Because there may be situations where the method cannot be found, exceptions need to be handled or thrown here;

  • When using getMethod() to obtain a private modified method, an exception that the method cannot be found will also be thrown.

import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) {
        Class<Student> student = Student. class;
        try {
            // Get the method with parameters
            Method method = student.getMethod("setAge", Integer.class);
            System.out.println(method);
            // Get method without parameters
            Method method2 = student. getMethod("getName", null);
            System.out.println(method2);
            // Get method without parameters
            Method method3 = student. getMethod("getName");
            System.out.println(method3);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

output result

public void com.reflect.Student.setAge(java.lang.Integer)

public void com.reflect.Student.getName()

public void com.reflect.Student.getName()

2. Get member variables

Get all member variables

import java.lang.reflect.Field;

public class Test {
    public static void main(String[] args) {
        Class<Student> student = Student. class;
        Field[] declaredFields = student. getDeclaredFields();
        for (Field field: declaredFields){
            System.out.println(field);
        }
    }
}

output result

private java.lang.String com.reflect.Student.name

private java.lang.Integer com.reflect.Student.age

public java.lang.String com.reflect.Student.className

3. Get other information of the class

3.1, Get the class name

public class Test {
    public static void main(String[] args) {
        Class<Student> student = Student. class;
        System.out.println(student.getName());
    }
}

There are actually many ways to get the class name:

either by class name,

Or get it through the object,

Or get the full path of the specified class.

3.2, get the package name

You can get the full path information of the package where the class is located.

public class Test {
    public static void main(String[] args) {
        Class<HighSchoolStudent> student = HighSchoolStudent. class;
        Package aPackage = student. getPackage();
        System.out.println(aPackage);
    }
}

3.3, get the parent class

public class Test {
    public static void main(String[] args) {
        Class<HighSchoolStudent> student = HighSchoolStudent. class;
        Class<? super HighSchoolStudent> superclass = student. getSuperclass();
        System.out.println(superclass);
    }
}

This method can only get the direct parent class of the class. If you want to get all the parent classes, you can loop through the parent class after getting the parent class until the parent class is Object.

public class Test {
    public static void main(String[] args) {
        Class<ArrayList> arrayListClass = ArrayList. class;
        Class superclass = arrayListClass. getSuperclass();
        System.out.println(superclass);

        while (! "java. lang. Object". equals(superclass. getName())) {
            superclass = superclass. getSuperclass();
            System.out.println(superclass);
        }
    }
}

output:

class java.util.AbstractList

class java.util.AbstractCollection

class java.lang.Object

3.4. Obtain all implemented interfaces

This method can get all interfaces implemented by this class.

import java.util.ArrayList;

public class Test {
    public static void main(String[] args) {
        Class<ArrayList> arrayListClass = ArrayList. class;
        Class<?>[] interfaces = arrayListClass. getInterfaces();
        for(Class clazz: interfaces){
            System.out.println(clazz.getName());
        }
    }
}

The output is as follows:

java.util.List

java.util.RandomAccess

java.lang.Cloneable

java.io.Serializable