Java学习笔记---反射

本文深入讲解Java反射机制的应用场景及基本原理,介绍如何通过三种方式获取Class对象,并演示使用反射实例化对象、调用构造方法及操作属性和方法的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java学习笔记—反射

  • 应用场景:通用性比较高的代码中
  • 框架的底层是反射
  • 在框架开发中,都是基于配置文件开发,配置文件中配置了类 ,可以通过反射得到类中的所有内容,可以让类中的某个方法来执行
    - 类中所有内容包括:属性、没有参数的构造方法、有参数的构造方法、普通方法

  • 反射的基本原理:

  • 第一步:将写好的代码保存成*.java文件(本地硬盘中)
  • 第二步:编译*.java文件成.class文件
  • 第三步:把.class文件通过类加载器加载到内存中(JVM)
  • 第四步:.class文件在内存中用Class类表示,得到Class类(字节码文件),就可以得到类中所有内容

    • 使用反射首先需要得到Class类,有三种方法可以得到Class类:
      1、类名.class
      2、对象.getClass()
      3、使用Class.forName(“路径”)
      • 类中不同内容的类不同:
        1、属性 — Field
        2、构造方法 — Constructor
        3、普通方法 — Method
  • 使用反射操作类

    • 首先获取到Class类
import org.junit.Test;

public class TestDemo {
    public static void main(String[] args) throws Exception {
        //获取Class类
        Class clazz1 = Person.class;
        Class clazz2 = new Person().getClass();
        Class clazz3 = Class.forName("fanshe.Person");
    }
}
 /*要对一个类进行实例化有两种方法:
   1、可以new
   2、不new 使用反射获取方式如下*/

 /*操作无参构造方法*/

//操作无参数的构造方法
    @Test
    public void test1() throws Exception{
        //得到Class
        Class clazz3 = Class.forName("fanshe.Person");
        //得到Person类的实例
        Person p = (Person) clazz3.newInstance();
        //设置值
        p.setName("zhangsan");
        System.out.println(p.getName());
    }
/*操作有参构造方法*/
//操作有参的构造方法
    @Test
    public void test2() throws Exception{
        //得到Class
        Class clazz1 = Class.forName("fanshe.Person");
        //使用有参的构造方法
        //clazz1.getConstructors();//获取所有的构造方法,不常用
        //传递的是有参的构造方法里面的参数类型,类型使用Class形式传递
        Constructor cs = clazz1.getConstructor(String.class,String.class);
        //通过有参构造方法设置值
        //通过有参构造方法创建person实例
        Person p = (Person) cs.newInstance("lisi","20");
        System.out.println(p.getId()+" "+p.getName());
    }
/*操作name属性*/
//操作name属性
    @Test
    public void test3(){
        try{
            //得到class
            Class clazz2 = Class.forName("fanshe.Person");
            //得到name属性
            //clazz2.getDeclaredFields();//得到所有属性,不常用
            //通过下面的方法得到属性,参数是属性的名称
            Field field = clazz2.getDeclaredField("name");
            //得到Person类的实例
            Person person = (Person) clazz2.newInstance();
            //设置可以操作私有属性;
            field.setAccessible(true);//如果不写这句话,会报错,报错原因:私有属性不能更改
            //设置name set方法:两个参数,第一个参数类的实例,第二个参数是设置
            field.set(person, "wangwu");//相当于p.name = "wangwu";
            System.out.println(field.get(person));//相当于p.name
        }catch(Exception e){
            e.printStackTrace();
        }
    }
/*使用泛型操作普通方法*/
    //操作普通方法,比如操作setName
    @Test
    public void test4() throws Exception{
        //得到Class类
        Class clazz4 = Class.forName("fanshe.Person");
        //得到普通方法
        //clazz4.getDeclaredMethods();//得到所有的普通方法 不常用
        //要传递两个参数,第一个参数是方法名,第二参数是通过方法设置的值(是类)
        Method m1 = clazz4.getDeclaredMethod("setName", String.class);
        //得到实例
        Person person = (Person) clazz4.newInstance();
        //操作的是私有方法的话,需要设置下面值为true(这里可以不写)
        clazz4.setAccessible(true);
        //让setName方法执行,执行设置值
        //使用invoke(person, "zhaoliu")方法,第一个参数是person的实例,第二个是设置的值
        //执行了invoke(person, "zhaoliu")方法之后,相当于执行了setname("zhaoliu")这个方法,同时向里面传递了参数
        m1.invoke(person, "zhaoliu");
        System.out.println(person.getName());
    }
  • 当操作的方法是静态方法时,因为静态方法调用的方式是:类名.方法名,不需要类的实例
    • 使用反射操作静态方法的时候,也不需要实例
      • 在invoke方法的第一个参数里面,写一个null
      • 如: m1.invoke(null, “zhaoliu”);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值