关于反射的总结

本文详细介绍了Java反射机制,包括其在动态语言中的重要性、如何通过反射创建和操作对象,以及如何调用类的属性和方法。示例代码展示了如何根据随机数动态创建不同类的对象,同时探讨了反射在JavaBean中的作用。此外,还讲解了获取Class实例的三种方式以及创建运行时类对象的方法。文章最后通过实例演示了如何调用运行时类的属性、方法和构造器。
摘要由CSDN通过智能技术生成

1反射概述

在这里插入图片描述

2关于反射的理解

反射是动态语言的关键,反射机制允许程序在执行期间借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法
框架 = 反射+注解+设计模式

3体会反射动态性的例子

生成的随机数决定了创建哪个类的对象,在执行时并不确定会创建哪一个

public class test {
    @Test
    public void test3() throws InstantiationException, IllegalAccessException {

        int num = 1;
        String classpat ="";
        switch (num) {
            case 0:
                classpat = "java.util.Date";
                break;
            case 1:
                classpat = "java.lang.String";
                break;
            case 2:
                classpat = "exer2.com.atguigu.java.Person";
                break;
        }
        try{
            Object o = getinstance(classpat);
            System.out.println(o.toString());
            System.out.println(o.getClass());

        }catch (Exception e){
            e.getMessage();
        }

    }
    public Object getinstance(String f) throws Exception {
        Class aClass = Class.forName(f);
        return aClass.newInstance();
    }
}

4反射机制所提供的功能在这里插入图片描述

5相关API

在这里插入图片描述

Class类的理解
1.类的加载过程
程序经过javac.exe命令以后,会生成一个或多个字节码文件(.class)结尾。
接着我们使用java.exe命令对某个字节码文件进行解释运行。相当于把某个字节码文件加载到内存中。此过程就称为类的加载,加载到内存中的类,我们就称之为运行时类,此运行时类就作为一个Class的实例。
2.换句话说,Class的实例就对应着一个运行时类。
3.加载到内存中的运行时类,会缓存一定的时间。在此时间之内,我们可以通过不同的方式来获取此运行时类。


获取Class实例的几种方式(需要掌握)
方式一:调用运行时类的属性:.class
Class clazz1 = Person.class
方式二:通过运行时类的对象,调用getClass()
Person p1 = new Person
Class clazz2 = p1.getClass();
方式三:调用Class的静态方法:forName(String classPath)
Class clazz3 = Class.forName(com.atguigu.java.Person)


创建类的对象的几种方式?

  1. new + 构造器
  2. 要创建类的对象,可以考虑类的静态方法(构造器隐藏了)
  3. 通过反射

创建运行时类的对象
Class clazz = Person.class
Person obj = clazz.newInstance()
要想使用此方法正常的创建运行时类的对象,要求:

  1. 运行时类必须提供空参的构造器
  2. 空参构造器的访问权限得够,通常,设置为public

在JavaBean中提供一个public的空参构造器,因为:

  1. 便于通过反射,创建运行时对象
  2. 便于子类继承此运行时类时,默认调用super,保证父类此构造器

调用运行时类的指定结构
调用指定的属性:

public class test {
    public static void main(String[] args) throws Exception {
        Class<person> clazz1 = person.class;
        //创建运行时类的对象
        person p = clazz1.newInstance();
        //1.getDeclaredField(String fieldname):获取运行时类中指定变量名的属性
        Field name = clazz1.getDeclaredField("name");
        //2.保证当前属性是可访问的
        name.setAccessible(true);
        //3.获取、设置指定对象的此属性值
        name.set(p,"wq");
        System.out.println(name.get(p));

        /*
        试一下public权限的属性
         */
        Field id = clazz1.getDeclaredField("id");
        //public权限不用设置能输出
        id.setAccessible(true);
        id.set(p,123);
        System.out.println(id.get(p));

    }
}

调用指定的方法:

    @Test
    public void test() throws Exception {
        Class<person> clazz = person.class;
        person p= clazz.newInstance();

        //1.获取指定的某个方法
        Method show1 = clazz.getDeclaredMethod("show1");
        //2.设置
        show1.setAccessible(true);
        //3.调用invoke()方法
        Object o = show1.invoke(p);
        System.out.println(o);

        Method show2 = clazz.getDeclaredMethod("show2");
        show2.setAccessible(true);
        show2.invoke(p);

        //测试静态方法
        Method show3 = clazz.getDeclaredMethod("show3");
        /*
        这里的静态方法需要注意的是,invoke方法里(),第一个参数是传入对象,
        即是调用方法的对象,第二个参数是传入的参数值,对于静态来说,类加载时就已经
        存在,因此可以直接传入person.class
         */
        Object invoke = show3.invoke(person.class);
        System.out.println("-------------");
        //测试带参数的
        /*
        带参数的,idea会自动生成形参列表
         */
        Method put = clazz.getDeclaredMethod("put", String.class, int.class);
        put.invoke(p,"lya",21836965);
        
    }
}

调用指定的构造器:

 @Test
    public void test2() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<person> clazz = person.class;
        Constructor<person> constructor = clazz.getDeclaredConstructor(String.class, int.class);
        person wq = constructor.newInstance("wq", 0000);
        System.out.println(wq);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值