前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 通过反射获取方法与变量

Java 通过反射获取方法与变量

作者头像
头发还在
发布2023-10-16 11:00:46
2910
发布2023-10-16 11:00:46
举报
文章被收录于专栏:桃花源桃花源

0、反射技术

反射技术是Java生态中的重要内容,在Spring以及其他框架中得到了广泛的应用。

有了反射技术,我们可以在程序运行的过程中:

  • 构建任意一个类的对象,
  • 了解任意一个对象所属的类,
  • 获悉任意一个类中的所有成员变量和方法,
  • 调用任意一个类中的属性和方法。

1、获取方法

1.1、创建实体类

实体类中包含私有方法、公有方法、私有变量、公有变量。

代码语言:javascript
复制
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("这是一个私有方法");
    }

    public void getName(){
        System.out.println("这是一个公有方法");
    }

    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、获取构造方法

1.1.1 获取类中的所有构造方法

首先需要通过上一篇文章中提到的方法,获取到 class对象,再通过 getDeclaredConstructors() 获取到该类下所有构造方法。

代码语言:javascript
复制
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);
        }
    }
}

输出的结果如下:

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()

从输出的结果中,可以看到:实体类中四个构造方法都被获取到了,包括一个私有构造方法。及构造方法中的参数列表也能被取出来。

1.1.2 获取所有公有构造方法

不同于获取所有构造方法的反射方法,这里使用 getConstructors() 即可。

代码语言:javascript
复制
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);
        }
    }
}

输出如下:

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

没有获取到类中类型为 private 的构造方法,仅有 public 方法。

1.1.3 根据参数列表,获取对应的构造方法

如果我们想要根据参数列表,获取到特定的构造方法时,可以使用 getDeclaredConstructor() 方法,方法中指明构造方法需要的参数:

  • 所有参数,必须使用 class 对象;
  • 参数的顺序应和构造方法中的顺序一致;
  • 要获取无参构造方法,可以输入 null 作为参数,或为空;
  • 这种方式可能会产生方法找不到的异常,因此需要对异常进行捕获或抛出。
代码语言:javascript
复制
import java.lang.reflect.Constructor;

public class Test {
    public static void main(String[] args) {
        try {
            Class<Student> student = Student.class;
            //获取私有构造方法
            Constructor<?> constructor = student.getDeclaredConstructor(String.class);
            System.out.println(constructor);
            //获取公有构造方法
            Constructor<?> constructor2 = student.getDeclaredConstructor(String.class, Integer.class);
            System.out.println(constructor2);
            //获取无参构造方法
            Constructor<?> constructor3 = student.getDeclaredConstructor(null);
            System.out.println(constructor3);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

输出结果为

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

  • 如果只想获取 public 类型的构造方法,可以使用 getConstructor() 方法,当对应的构造方法为 private 时,会报异常 java.lang.NoSuchMethodException
  • 根据参数列表没有找到对应的方法,程序会报异常 java.lang.NoSuchMethodException

1.2、获取普通方法

1.2.1 获取所有普通方法

使用class对象的 getDeclaredMethods() ,可以获取当前类下所有普通方法(非构造方法)。

代码语言:javascript
复制
import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) {
        Class<Student> student = Student.class;
        //获取所有方法
        Method[] declaredMethods = student.getDeclaredMethods();
        for (Method method : declaredMethods){
            System.out.println(method);
        }
    }
}

输出结果为

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)

类型为 private 和 public 的方法,都被获取到了。

1.2.2 获取所有公有的普通方法

使用class对象的 getMethods() ,可以获取当前类及其所有父类下所有被 public 修饰的普通方法(非构造方法)。

代码语言:javascript
复制
import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) {
        Class<Student> student = Student.class;
        //获取所有方法
        Method[] declaredMethods = student.getMethods();
        for (Method method : declaredMethods){
            System.out.println(method);
        }
    }
}

输出结果中,包含了 Student 类及默认父类 Object 类下所有由 public 修饰的方法。

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 根据指定方法名及参数列表,获取指定方法
  • 如果要获取的方法为 public 时,使用 getMethod() 方法;
  • 如果想要获取私有方法时,需要使用 getDeclaredMethod() 方法。
  • 因为存在同名方法,需要在getMethod()方法中第一个参数指定要获取的方法名,后边为参数列表;
  • 无参方法时,参数列表可以没有,或使用 null 表示;
  • 因为可能存在方法找不到的情况,所以这里需要对异常进行处理或抛出;
  • 当使用getMethod()获取 private 修饰的方法时,也会抛出方法找不到的异常。
代码语言:javascript
复制
import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) {
        Class<Student> student = Student.class;
        try {
            //获取带参方法
            Method method = student.getMethod("setAge", Integer.class);
            System.out.println(method);
            //获取无参方法
            Method method2 = student.getMethod("getName", null);
            System.out.println(method2);
            //获取无参方法
            Method method3 = student.getMethod("getName");
            System.out.println(method3);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

输出结果

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

2、获取成员变量

获取所有成员变量

代码语言:javascript
复制
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);
        }
    }
}

输出结果

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、获取类的其他信息

3.1、获取类名

代码语言:javascript
复制
public class Test {
    public static void main(String[] args) {
        Class<Student> student = Student.class;
        System.out.println(student.getName());
    }
}

获取类名其实有多种方式:

要么是通过类名获取,

或者通过对象获取,

或者指定类的全路径获取。

3.2、获取包名

可以拿到该类所在的包的全路径信息。

代码语言:javascript
复制
public class Test {
    public static void main(String[] args) {
        Class<HighSchoolStudent> student = HighSchoolStudent.class;
        Package aPackage = student.getPackage();
        System.out.println(aPackage);
    }
}

3.3、获取父类

代码语言:javascript
复制
public class Test {
    public static void main(String[] args) {
        Class<HighSchoolStudent> student = HighSchoolStudent.class;
        Class<? super HighSchoolStudent> superclass = student.getSuperclass();
        System.out.println(superclass);
    }
}

这种方式只能拿到该类的直接父类,如果想要获取所有父类,可以在拿到父类后循环遍历,直到父类为 Object 为止。

代码语言:javascript
复制
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);
        }
    }
}

输出:

class java.util.AbstractList class java.util.AbstractCollection class java.lang.Object

3.4、获取实现的所有接口

该方法可以获取到该类实现的所有接口。

代码语言:javascript
复制
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());
        }
    }
}

输出如下:

java.util.List java.util.RandomAccess java.lang.Cloneable java.io.Serializable

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0、反射技术
  • 1、获取方法
    • 1.1、创建实体类
      • 1.1、获取构造方法
        • 1.1.1 获取类中的所有构造方法
        • 1.1.2 获取所有公有构造方法
        • 1.1.3 根据参数列表,获取对应的构造方法
      • 1.2、获取普通方法
        • 1.2.1 获取所有普通方法
        • 1.2.2 获取所有公有的普通方法
        • 1.2.3 根据指定方法名及参数列表,获取指定方法
    • 2、获取成员变量
    • 3、获取类的其他信息
      • 3.1、获取类名
        • 3.2、获取包名
          • 3.3、获取父类
            • 3.4、获取实现的所有接口
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档