美文网首页
反射入门

反射入门

作者: 许先森的许 | 来源:发表于2017-03-12 15:33 被阅读66次

1、认识反射

“反”,有反就有“正”。正常情况先有类,再产生对象。所谓的反就是可以利用对象找到对象的出处:

在Object类里面提供有一个方法:取得Class对象:

public final Class getClass();

可以输出类的完整名称,就找到了对象的出处。

Class类对象的实例化:

java.lang.Class是一个类。这个类是反射操作的源头,所有的反射都要从此类开始进行。最关键的是这个类有三种实例化方式。

1、调用Object类中的getClass()方法:Class cls = mIntent.getClass();需要实例化对象,需要import导入类

2、使用“类.class”取得:Class cls = Intent.class。不需要实例化对象,需要import导入类

3、调用Class类提供的方法:Class.forName(String className)。不需要import语句导入一个明确的类

反射实例化对象。

当拿到一个类的时候,肯定用关键字new进行对象的实例化操作,但是如果有了Class类对象后,就可以不用New关键字也可以进行对象的实例化操作:

public T newInstance()相当于使用new调用无参构造函数。

有了反射之后,进行实例化的操作不再只是单单依靠关键字new完成了。反射也可以。

所以用反射获取一个对象实例化的步骤为:

1、先获取Class类的实例化对象:Class cls = Class.forName(“xxxxxx”);

2、用Class类的实例化对象获取制定类的实例化对象:Book book=(Book)cls.newInstance();


但是本来用关键字new一行代码就可以完成实例化操作,反射需要两步,这样好吗?


2、理解反射的作用

在任何开发中,一起的耦合都起源于new。

看工程模式。如果想要扩展,就必须改动工厂类中的if else。如果一直扩展,就需要一直修改工厂类。因为工厂类中是通过New产生对象实例的,所以New就是问题的关键。

如果工厂中用反射代替new,就不需要if else和new实例化每个if else中的对象。只需要传入类的完整名称,就可以解耦和。扩展性非常的强!

3、利用反射调用类的结构

a、使用反射调用构造:

之前所说的newInstance()方法实际上等于调用了无参构造函数,但是实际中可能么有无参构造函数,

Class中有方法可以取到构造:public Constructor[]getConstructors():取得全部构造。

和:public Constructor getConstructor(Class… paramterTypes):取得一个指定参数顺序的构造函数。

Constructor类是java.lang.reflect,这时候真正到了反射中。

实例化对象方法public T newInstance(Object… initargs)

所以用反射获取一个没有无参构造函数的类的实例化对象步骤为:

1、先获取Class类对象:Class cls = Class.forName(“xxxxx”);

2、获取指定参数类型顺序的构造函数:Constructor con = cls.getConstructor(Sring.class,double.class);

3、使用获取到的构造函数实例化对象:Object obj = con.newInstance(“第一个参数字符串类型”,10086.8);

所以建议,不管有多少个构造方法,都尽量提供一个无参构造函数,不然太麻烦了。

b、反射调用方法:

Class类中提供了一下方法用来获取类的方法:

public Method[]getMethods()

public Method getMethod(String methodName,Class… paramterTypes)

Method类似java.lang.reflect包下的,其中有个

public Object invoke(Object obj,Object… args)方法。

所以用反射调用方法的步骤为:

1、先获取Class对象:Class cls = Class.forName(“xxxxx”);

并获取对象Object object = cls.newInstance();//必须给出实例化对象

2、获取指定方法:Method setTitleMethod = cls.getMethod(“setTitle”,String.class);

3、调用方法:setTitleMethod.invoke(object,“一本书的标题”);//等价于Book对象.setTitle(“一本书的标题”)

但是这个过程中完全没有出现过Book。也就是说,利用反射可以实现任意类的制定方法的调用。

c、反射调用成员:

类中的属性一定要在本类实例化对象产生后才可以分配内存空间。

Class类中提供了取得成员的方法:

1、取得全部成员:public Field[]getDeclaredFields()

2、取得指定成员:public Field getDeclaredField(String fieldName)

Field是java.lang.reflect包下。其中有:

1、取得属性内容:public Object get(Object obj);

2、设置属性内容:public void set(Object obj,Object value)

所以反射调用成员的步骤为:

假设一个Book类,里面只有一个属性private String title;没有getter/setter方法。

1、先获取Class对象:Class cls = Class.forName(“xxx”);

2、获取对象:Object obj = cls.newInstance();

3、获取指定成员:Field titleField = cls.getDeclaredField(“title”);

4、设置属性内容:titleField.set(obj,“书的名字”);//相当于:Book类对象.title =“书的名字“

但是调用get还是会报错。因为封装性。

这时候需要用到:AccessbleObject

在java.lang.reflect.AccessibleObject类下面(JDK1.8修改):

~ Executable//可执行的

~ Constrictor

~Method

~Field

在这个类中有一个方法:

public void setAccessible(boolean flag)设置是否封装,

设置为false后,就是取消封装,这个时候再调用刚才的get就可以正常调用了。

构造方法和普通方法一样可以取消封装,只不过很少这样去做,而且对属性的访问还是应该是getter和setter方法完成。

学习完这些,反射算是入门了。

相关文章

  • Java反射机制入门

    Java反射机制入门 一、什么是反射 JAVA反射机制(The JAVA reflection mechanism...

  • Java基本知识

    java反射机制 大白话说Java反射:入门、使用、原理[https://www.cnblogs.com/chan...

  • C#它山之石

    C# 使用反射技术实例化指定的类C#之玩转反射Reactive Extensions入门IoC solutions...

  • 反射入门

    1、认识反射 “反”,有反就有“正”。正常情况先有类,再产生对象。所谓的反就是可以利用对象找到对象的出处: 在Ob...

  • 反射入门

    Java的反射机制实在运行状态中,对于一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的方...

  • Java入门--反射

    Java入门--反射(Reflect) 利用反射和配置文件, 加载不同的类和方法 创建配置文件对象 new Pro...

  • 2018-10-05

    反射_invoke aop详解 代理51cto 代理图解 jvm_死灰级反射入门_笨蛋 代理111 动态代理的目的...

  • 反射

    详见Java从入门到精通一书 反射就是Reflection,Java的反射是指程序在运行期可以拿到一个对象的所有信...

  • Python 入门 之 反射

    1、反射 : (自省) ​ 反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。 Python...

  • Java 反射入门

    定义 Java的反射(reflection)机制是指在程序的运行状态中,可以构造任何一个类的对象,可以了解任意一个...

网友评论

      本文标题:反射入门

      本文链接:https://www.haomeiwen.com/subject/ujntnttx.html