Java中的反射

Java中的反射知识点(通俗讲解)

首先我得介绍以下常用的反射类, 然后给出相应的代码示例, 切记, 学会应用, 不要死记, 不要死记, 不要死记!

Class类

Class类是java.lang.Class包中的, 其常用到的方法如下(不需要死记, 用到的时候调用)

  1. 返回className的类或接口的Class对象
public static Class<?> forName(String className)
  1. 返回Class对象所对应类的父类的Class对象
public Class<? super T> getSuperclass()
  1. 返回Class对象所对应的类的"包.类名"形式的全名
public String getName()
  1. 返回一个包含所有声明的字段的数组,包括私有、受保护、默认和公共字段
public Field[] getDeclaredFields()
  1. 返回一个包含所有公共方法的数组,包括继承的方法
public Method[] getMethods()
  1. 返回一个包含所有公共构造函数的数组
public Constructor<?>[] getConstructors()
  1. 返回一个包含该类实现的接口的Class对象数组
public Class<?>[] getInterfaces()
  1. 检查该类是否是接口
public boolean isInterface()
  1. 检查该类是否是枚举类型
public boolean isEnum()
  1. 检查该类是否是数组类型
public boolean isArray()

Executable类

Executable类存于java.lang.reflect.Executable中, 以下是常用的方法

  1. 返回表示方法或构造函数修饰符的整数。可以使用Modifier类的方法来解释这个整数,以获得修饰符的详细信息。
public int getModifiers()
  1. 返回方法或构造函数的名称。
public String getName()
  1. 返回表示方法或构造函数参数类型的Class对象数组。
public Class<?>[] getParameterTypes()
  1. 返回表示方法或构造函数泛型参数类型的Type对象数组。
public Type[] getGenericParameterTypes()
  1. 返回所有形参, 并存入数组Parameter[]中
public Parameter[] getParameters()
  1. 返回参数的个数
public int getParameterCount()

Constructor<T>类

存在于java.lang.reflect. Constructor<T>中

  1. 返回构造函数的名称。
public String getName()
  1. 使用指定的参数值来创建构造函数的新实例。
public T newInstance(Object... initargs)
  1. setAccessible 方法的作用是在需要绕过Java语言访问控制检查的情况下,允许对对象进行访问,即使它们通常是私有的或受保护的。这可以用于反射,以访问那些在正常情况下不可访问的类成员(字段、方法、构造函数等)。
public void setAccessible(boolean flag) throws SecurityException

Method类

存于java.lang.reflect.Method中

  1. 返回方法的名称。
public String getName()
  1. 返回方法的修饰符,可以使用Modifier类的方法来解释这个整数,以获得修饰符的详细信息。
public int getModifiers()
  1. 调用方法并传递给它指定的参数值。返回方法的结果,如果方法是静态方法,则 obj 参数可以为 null。
public Object invoke(Object obj, Object... args)

Field类

存于中

  1. 返回字段的名称。
public String getName()
  1. 返回表示字段类型的 Class 对象。
public Class<?> getType()
  1. 设置指定对象中字段的值为新值。
public void set(Object obj, Object value)
  1. 获取指定对象中字段的值。
public Object get(Object obj)

Parameter类

存于java.lang.reflect.Parameter中

  1. 返回参数的名称。如果 Java 编译器在编译时保留了参数名称(通过编译时选项 -parameters),则可以获取实际参数名称,否则将返回一个泛型名称,如 “arg0”。
public String getName()
  1. 返回参数的修饰符,可以使用 Modifier 类的方法来解释这个整数,以获得修饰符的详细信息。
public int getModifiers()
  1. 返回参数的参数化类型。这通常包括泛型类型信息,例如泛型类、泛型方法的类型参数等。
public Type getParameterizedType()
  1. 返回参数的类型的 Class 对象。
public Class<?> getType()

如下是详细的示例代码

这里的示例按顺序包括了查看类等名称, 并进行了相应的反射调用, 当然我是存于chapter18这个包下的

package chapter18;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

interface fly {
    void fly();
}

class Person implements fly {
    private String name;
    private int age;

    public Person() {

    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public void getString() {
        System.out.println(name + age);
    }

    @Override
    public void fly() {

    }

    @Override
    public String toString() {
        return name + " " + age;
    }


}

class Student extends Person {

}


public class Demo1801 {
    public static void main(String[] args) throws Exception {
        //查看部分
        System.out.println("---------------------查看部分---------------");
        //获取包+类名
        Class<?> c1 = null;
        Class<?> c2 = null;
        Class<?> c3 = null;
        //三种方式获取Class对象
        c1 = Class.forName("chapter18.Person");
        c2 = Person.class;
        c3 = new Person().getClass();
        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);

        //获取父类
        Class<?> c4 = null;
        c4 = Student.class;
        System.out.println(c4.getSuperclass());

        //获取接口
        Class<?>[] list = c1.getInterfaces();
        for (Class<?> c : list) {
            System.out.println(c);
        }

        //获取构造方法
        Constructor<?>[] conList = c1.getDeclaredConstructors();//建立构造器数组,用来存储构造方法
        for (int i = 0; i < conList.length; i++) {
            int modify = conList[i].getModifiers();//获取访问权限
            String name = conList[i].getName();//获取方法名
            System.out.println(Modifier.toString(modify) + " " + name);
            Class<?> para[] = conList[i].getParameterTypes();//获取参数类型
            for (Class<?> c : para) {
                System.out.println(c.getName());
            }
        }

        //获取方法
        Method[] declaredMethod = c1.getDeclaredMethods();
        for (Method method : declaredMethod) {
            //如果想获取权限那些,和上面的构造方法获取方式一样
            System.out.println(method);
        }

        //获取一个类的所有变量(成员)
        Field[] declaredFields = c1.getDeclaredFields();
        for (Field f: declaredFields) {
            //如果想获取权限那些,和上面的构造方法的获取方式一致
            System.out.println(f);
        }

        //调用部分
        System.out.println("---------------------调用部分---------------------------");

        //调用构造方法
        Constructor<Person> constructor = (Constructor<Person>) c1.getConstructor(String.class, int.class);
        System.out.println(constructor.newInstance("John",20));

        //调用方法
        Method method = c1.getMethod("getString");
        method.invoke(new Person("H",1));

        //访问数据成员
        Field nameField = c1.getDeclaredField("name");
        nameField.setAccessible(true); // 设置可访问私有字段
        String nameValue = (String) nameField.get(new Person("M",10));
        System.out.println("Name: " + nameValue);

        Field ageField = c1.getDeclaredField("age");
        ageField.setAccessible(true);
        int ageValue = ageField.getInt(new Person("M",10));
        System.out.println("Age: " + ageValue);

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值