反射 详解

反射

概念:将类的各个组成部分封装为其他对象。

好处:1、可以在程序的运行过程中操作对象。

           2、降低程序的耦合性,提高程序的可扩展性。

看下面的图:反射将在写好的代码中,成员变量,构造方法,成员方法各自拿出进行封装,封装为不同的类。后续就对这些封装好的类进行操作。

 

 

反射获取字节码Class对象的三种方式:对应三种不同阶段

        1、forName获取:       //类还未调用时获取

                    Class<?> class1 = Class.forName("路径比如xxx.xx.x");

        2、通过类名点class获取class对象    //还未创建对象时获取

                    这种是最简单的获取方法,例如:

                                Class<?> class1 = 类名.class;

        3、getClass获取           //创建对象后获取

                    注意:getClass获取前需要先有对象,再通过类名点class获取。

                    比如:Person person = new Person();

                    Class<?> class1 = person.getClass();

Class对象功能:

1、获取成员变量:Field[ ] getFields();          获取某个类的public修饰的成员变量,包括父类的成员变量

                               Field getField(String name);       获取某一个public修饰的成员变量。

 

                               Field[ ] getDeclaredFields();     获取某个类的所有的成员变量(包括private,父类中的不算入内)

                               Field getDeclaredField(String name);   获取某个类的指定成员变量。

                               这里private也能获取到,在反射面前没有什么私有的公有的,你的都是我的,我的还是我的。

                               在使用Declared的时候要忽略访问权限修饰符的安全检查  对象点setAccessible(true);不然会报错。不管是Field还是Method还是Constructor都有这个说法。

                     

2、获取构造方法:

                               Constructor<?>[ ]  getConstructors();

                               Constructor<T>  getConstructor(类<?>...parameterTypes);

 

                                Constructor<?>[ ]  getDeclaredConstructors();

                                Constructor<T>  getDeclaredConstructor(类<?>...parameterTypes);

3、获取成员方法

                                Method[ ] getMethods();

                                Method  getMethod(String name,类<?>...parameterTypes);           //parameterTypes是参数类型

 

                                Method[ ] getDeclaredMethods();

                                Method  getDeclaredMethod(String name,类<?>...parameterTypes);

4、获取类名

                               String getName();

 

目的:

拿到Field是想要干什么?无外乎取值和赋值

    ① 赋值:set方法void set(Object obj,Object value);

                           obj是给哪个对象赋值就是谁,value是赋值为什么内容。

    ② 取值:get方法,get(Object obj);

                           传递的参数obj为被调用的对象

 

构造方法是用来干什么的?为什么要获取构造方法?

        ① 构造方法是用来创建对象的。获取到了构造方法就可以创建对象了。

        ② 获取构造方法:用之前获得的class对象来调用构造方法,返回的类型为Constructor。

                举例:Constructor  cons1 = new Constructor(String.class , int.class);

        ③ 创建对象通过constructor构造出来的对象点newInstance()来实现,返回的对象类型是Object,newInstance中传的是构造这个              实例时所需要传递的真正的值。

                举例:Object object1 = cons1.newInstance("csdn" , 999);

拿到方法后要调用方法,调用方法就要用到invoke();

        //先获取一个Method对象,假设想要获取的是Person类的方法。

           Method add1 = class1.getMethod("addName",String.class);   //这儿第二个参数是方法所需传值的类型,用意在于重载的时               候可以清楚找的是哪个方法。

           Person person = new Person();      //invoke方法中需要传对哪个对象调用的方法,所以这里新建一个对象。

           add1.invoke(person,"张三");           //invoke传的参数,第一个是哪个对象来调用方法,第二个是调用方法时需要传的参数。

 

那我们要反射究竟是要干什么?

        比如:写一个程序,这个程序可以在不改变类的代码前提下,帮我们创建任意类的对象,执行其中的方法。

                  //需要用到反射,配置文件(Properties类,以键值对形式进行参数配置)。

                  //可以将这任意的类放置到配置文件中,再通过反射加载文件,创建对象,执行方法。

 

补充:

        ① 构造方法为空参时创建对象可以简化:

                直接使用Class对象的newInstance方法来创建。

                举例:Object  object1 =  class1.newInstance();

        ② 同一个字节码文件(.class)在一次程序运行过程中,只会被加载一次,不管是通过哪一种方式获取的Class对象,都是同一个。

 

        ③ 获取Class对象的三种方式:forName:通常用于配置文件中

                                                      类名.class:多用于参数的传递

                                                      对象.getClass() :多用于对象获取字节码的方式

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Python中,反射是指通过字符串的形式去访问对象的属性、方法和其他成员。Python中的每个对象都有一组内置的特殊属性和方法,比如 `__dict__`、`__class__`、`__name__`、`__bases__` 等等。这些属性和方法可以通过反射机制来访问和操作。 Python中的反射通常涉及到以下三个内置函数: 1. `hasattr(object, attribute)`:检查对象是否具有指定的属性或方法。 2. `getattr(object, attribute[, default])`:获取对象的属性或方法。如果属性或方法不存在,则返回默认值(如果指定了)或引发 AttributeError 异常。 3. `setattr(object, attribute, value)`:设置对象的属性或方法。 下面是一些示例: ```python class MyClass: def __init__(self): self.x = 10 def my_method(self): print("Hello, World!") # 创建一个对象 obj = MyClass() # 使用 getattr 获取对象的属性和方法 print(getattr(obj, 'x')) # 输出: 10 getattr(obj, 'my_method')() # 输出: Hello, World! # 使用 hasattr 检查对象是否具有属性和方法 print(hasattr(obj, 'x')) # 输出: True print(hasattr(obj, 'y')) # 输出: False # 使用 setattr 设置对象的属性和方法 setattr(obj, 'y', 20) print(obj.y) # 输出: 20 setattr(obj, 'my_method', lambda: print("Hello, Python!")) obj.my_method() # 输出: Hello, Python! ``` 除了使用内置函数之外,Python中还有另一种反射机制,即使用元类。元类是用于创建类的类,可以通过元类来动态地创建、修改和删除类的属性和方法。元类的使用超出了本文的范围,感兴趣的读者可以自行学习。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值