java基础-反射浅析(磨砺营马剑威java)

徘徊边缘 提交于 2019-12-10 20:43:28

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

【威哥说】本文里波波老师将带领大家一起学习一下什么是反射,文中暂且没有详细给大家介绍反射如何去获取类中的所有属性和方法,更多的是介绍什么场景下会使用到反射,使用反射有什么好处和缺点,大家有自己的理解也可以相互探讨。 反射,一种计算机处理方式。是程序可以访问、检测和修改它本身状态或行为的一种能力。 这是百度百科里的一个说法,我曾经还看到一个对反射的描述为:在运行状态中,对于任意一个class类,都能知道此类的所有属性和方法,对于任意一个对象都能对他的属性和方法进行调用。那在我的理解来看,就是动态的获取一个类的所有属性和方法。这个可以理解为反射的概念,或者说作用。

那么反射的使用在那些场景中呢?应用场景如下:当程序写完之后,如果想添加功能,没法直接创建对象(注意:此处是因为一个完整的程序代码已经成型了,封装好了,你无法直接创建对象),但是一般程序会在定义结构时为了扩展而对外提供接口,所以我们通过实现这个接口,并在使用时告诉程序类名称,然后去通过反射找到class文件,并针对其中的元素进行操作;第二就是为了适应变化,你传入什么类型,我对什么类型进行具体的操作,这类一般用于数据解析。 一般应用: 1、比如java中连接数据库操作时,内部的连接操作已经写好了,如果密码发生变化,我们不需要改变原有的代码逻辑,直接在配置文件中更改即可,这里登录操作就是一个已经封装好的完整的代码块,我不希望后续的更改一些东西时会动到我里面的代码,此时使用反射,很好的解决了这个问题。 2、比如咱们的计算机在设置时会提供对外访问的USB接口,那么连接USB接口的这一块操作计算机内部已经封装好了,不希望外部改动,此时就对外提供了一个访问的接口,你直接连接就行了,这里也使用到反射。 3、Android中请求网络数据时,要解析成什么对象,传入一个对应的class类型,直接根据类型解析数据...... 可能很多初学者,甚至说开发已经有一年经验的开发者都有些没搞懂反射的概念,还有可能有些开发者一直知道这么去用,但是知其然不知其所以然。那今天讲一个简单的示例来给大家引申出这个概念。 就拿USB接口这个来说,我们会在封装时直接定义一个父类接口 USB,注意:这里是对外提供的扩展的接口,如下: public interface PCI {

public void open();

public void close();

} 然后我们需要去定义计算机内部的驱动程序,这里我的驱动程序是一个体系不希望外部来操作,所以电脑内部的驱动代码大家是无法调用的,但是具体实现是如何来实现的呢?我们简单模拟一下: 首先主板的驱动类: public class Mainboard {

public void run() {

System.out.println("main board run....");

}

public void useUSB(USB u) {

if (u != null) {

u.open();

u.close();

}

}

}

正常情况下,每添加一个USB接口,我们都得重新new一个对象,然后放进去进行使用,如下: //使用一个鼠标的USB

Mainboard mb = new Mainboard();

mb.run();

//每次添加一个设备都需要修改代码传递一个新创建的对象

mb.useUSB(new MouseUSB());

//使用一个键盘的USB

这里又需要修改代码

mb.useUSB(new KeyBoardUSB());

那如果说像电脑一样直接把内部封装好了,不直接让你去修改代码可如何是好? 此时我们就需要反射的知识了,我们通过接入的USB直接告诉电脑一个类型,也就是说我是什么类型的,不动你原本的东西,我在外部稍微改动一下即可,那在代码中该如何体现呢?在java中我们可以使用配置文件的方式来解决这类问题。 比如我们新建一个usb.properties

在其中保留usb1=MouseUSB.class

在主板中直接定义好处理逻辑,读取properties文件,并执行所有USB接口:

File configFile = new File("usb.properties");

Properties prop = new Properties();

FileInputStream fis = new FileInputStream(configFile);

prop.load(fis);

for(int x=0; x

String usbName = prop.getProperty("usb"+(x+1));

//通过类名得到类对象

Class clazz = Class.forName(usbName);//用Class去加载这个usb子类。

//通过类对象的newInstance()方法调用空参的构造方法创建实例

USB u = (USB)clazz.newInstance();

mb.usePCI(u);

}

fis.close();

有了这么一个定义之后,我们如果有了后续要添加的USB接口,我们只需要在配置文件中添加定义即可,如:usb2=KeyBoardUSB.class,就不用去改变原有的逻辑了。 优点: A:能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性。 B:与Java动态编译相结合,可以实现无比强大的功能 缺点: A:使用反射的性能较低 B:使用反射相对来说不安全 C:破坏了类的封装性,可以通过反射获取这个类的私有方法和属性 更多内容关注微信公众号mjw-java或访问www.moliying.com

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!