当前位置: 首页 > news >正文

JAVA入门——反射

一、什么是反射

  • 反射允许对封装类的字段、方法和构造函数的信息进行编程访问
  • 我们是从class字节码文件中获取这些信息的,所以先学习如何获取class文件

二、获取class对象的三种方式

Class.forName("全类名")

类名.class

对象.getClass()

 例:

  • 第一种最常用,第二种多当做参数用,第三种只有在有了类对象时会用
public class MyReflectTest1 {

    public static void main(String[] args) throws ClassNotFoundException {

        //1.第一种方式:
        //全类名:包名+类名
        Class class1 = Class.forName("com.ma6.reflect.Student");

        //2.第二种方式:
        Class class2 = Student.class;

        //3.第三种方式:
        Class class3 = new Student().getClass();

        System.out.println(class1 == class2);
        System.out.println(class2 == class3);

    }

}

三、利用反射获取构造方法(Class类中方法)

Constructor是一个描述构造方法的类,JAVA中的所有事物都能看做对象,都有对应的类

Constructor<?>[] getConstructors();                //返回所有公共构造方法对象的数组

Constructor<?>[] getDeclaredConstructors();  //返回所有构造方法对象的数组

Constructor<T> getConstructor(Class<?>...parameterTypes);  //返回单个公共构造方法对象

Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes); //返回单个构造方法对象

注意:

  • 使用带有Declared的方法确实能获取私有的构造方法,但这仅仅是能看到,不能使用
  • 如果想要使用,需要先调用setAccessiable方法,传递true,再调用构造方法,这种方法称做“暴力反射”

小例子:

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class MyReflectTest2 {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //1.获取字节码文件对象
        Class<?> clazz = Class.forName("com.ma6.reflect.Student");

        //2.获取构造方法
        //<?>是无界通配符,可以匹配任意类型
/*        Constructor<?>[] cons = clazz.getConstructors();
        for (Constructor<?> con : cons) {
            System.out.println(con);
        }
        System.out.println();*/

/*        Constructor<?>[] cons1 = clazz.getDeclaredConstructors();
        for (Constructor<?> con : cons1) {
            System.out.println(con);
        }
        System.out.println();*/

/*        //获取空参构造
        Constructor<?> con2 = clazz.getDeclaredConstructor();
        System.out.println(con2);

        //获取String的构造
        Constructor<?> con3 = clazz.getDeclaredConstructor(String.class);
        System.out.println(con3);

        //获取int的构造
        Constructor<?> con4 = clazz.getConstructor(int.class);
        System.out.println(con4);*/

        //获取String,int的构造
        Constructor<?> con5 = clazz.getConstructor(int.class, String.class);
        System.out.println(con5);

        //3.获取构造方法属性
        //获取权限修饰符,构造方法的所有属性都能查询,详细查询帮助文档
        int modifiers = con5.getModifiers();
        System.out.println(modifiers);

        //4.可以用来创建对象
        Student stu = (Student)con5.newInstance(11, "王牛牛牛");
        System.out.println(stu);
    }

}

四、利用反射获取成员变量

Field:描述成员变量类

Field[] getFields();               //返回所有公共成员变量对象的数组

Field[] getDeclaredFields();//返回所有成员变量对象的数组

Field getField(String name);//返回单个公共成员变量对象

Field getDeclaredField(String name);//返回单个成员变量对象

Field类中用于创建对象的方法:

void set(Object obj,Object value);//赋值

Object get(Object obj);                  //获取值

import java.lang.reflect.Field;

public class MyReflectTest3 {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        Class<?> clazz = Class.forName("com.ma6.reflect.Student");

        //1.
        Field[] field = clazz.getDeclaredFields();
        for (Field field1 : field) {
            System.out.println(field1);
        }

        //2.
        Field name = clazz.getDeclaredField("name");
        System.out.println(name);

        //3.
        String n = name.getName();
        int mod = name.getModifiers();
        Class<?> type = name.getType();

        //4.获取成员变量记录的值
        Student s = new Student(13,"王牛牛牛");
        name.setAccessible(true);//私有变量,要暴力反射
        String value = (String)name.get(s);
        System.out.println(value);

        //5.修改对象里的值
        name.set(s,"王犇");
        System.out.println(s);

    }

}

五、反射获取成员方法

Method:描述成员方法的类

Method[] getMethods();        //返回所有公共成员方法,包括继承

Method[] getDeclaredMethods();//返回所有成员方法对象,不包括继承

Method getMethods(String name,Class<?>...parameterTypes);

Method getDeclaredMethods(String name,Class<?>...parameterTypes);

Method类中创建对象方法:(方法运行)

Object invoke(Object obj,Object...args)

用obj调用方法,args是传的参数

public class MyReflectTest4 {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        //1.
        Class<?> clazz = Class.forName("com.ma6.reflect.Student");

        //2.
        Method eat = clazz.getDeclaredMethod("eat", String.class);
        System.out.println(eat);

        //3.
        Student s = new Student();
        eat.setAccessible(true);
        eat.invoke(s,"史");
        
    }
}

相关文章:

  • Sass 模块化革命:深入解析 @use 语法,打造高效 CSS 架构
  • 解锁访问者模式:Java编程的灵活之道
  • 神旗视讯Linux client 3.4版本发布和开源
  • 每日学习Java之一万个为什么?(Maven篇+RPC起步+CICD起步)(待完善)
  • [内网安全] Windows 本地认证 — NTLM 哈希和 LM 哈希
  • 从0到1构建AI深度学习视频分析系统--基于YOLO 目标检测的动作序列检查系统:(1)视频信息的获取与转发
  • AR配置静态IP双链路负载分担示例
  • 说一下SpringBoot3新特新和JDK17新特性
  • 去除HTML有序列表(ol)编号的多种解决方案
  • 分布式存储学习——HBase概述
  • 华为hcie证书有什么作用?
  • 【MYSQL数据库异常处理】执行SQL语句报超时异常
  • 深度学习实战:用TensorFlow构建高效CNN的完整指南
  • 在 Apache Tomcat 中,部署和删除项目
  • 5年前问题的答案,如何造统计信息
  • Claude 3.7登顶webdev榜首,国内怎么使用Claude 3.7
  • 【YashanDB认证】yashandb23.3.1 个人版单机部署安装实践
  • 深入MiniQMT:实现远程下单的高效解决方案
  • 14、TCP连接如何确保可靠性【高频】
  • 多线程-定时任务线程池源码
  • 《五行令》《攻守占》,2个月后国博见
  • 广西壮族自治区政府主席蓝天立任上被查
  • 习近平在第三十五个全国助残日到来之际作出重要指示
  • 曾犯强奸罪教师出狱后办教培机构?柳州鱼峰区教育局:正核实
  • 缅甸内观冥想的历史漂流:从“人民鸦片”到东方灵修
  • 新闻1+1丨城市,如何对青年更友好?