反射机制的概念

简介: 反射机制的概念

 目录

前言

反射机制的作用

IOC容器的技术剖析

反射与工厂模式实现IOC

下面用反射机制实现工厂模式:

总结:



前言

考虑一个场景,在程序运行时,一个对象想要检查自己所拥有的成员变量属性,该如何操作?另外一个场景,想要在运行期获得某个类的Class信息如它的属性、构造方法、一般方法后再考虑是否创建它的对象,这种情况就需要用到反射!

1)java文件在编译后会变成.Class文件,这就像是个镜面,本身是.Java,在镜中是.Class,他们其实是一样的;同理,看到镜子的反射是.Class,就能通过反编译,了解到.Java文件的本来面目。

2)对于反射,官方给出的概念:反射是Java语言的一个特性,它允许在程序运行时(注意不是编译的时候)来进行自我的检查并且对内部的成员进行操作。例如它允许一个Java类获取它所有的成员变量和方法并且显示出来。

3)反射主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。在Java中,只要给定类的名字,那么就可以通过反射机制来获取类的所有信息

4)反射是Java中的一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时进行装配,无需在组件之间进行源代码链接。但是反射使用不当会成本很高!类中有什么信息,利用反射机制就能可以获得什么信息,不过前提是得知类的名字。

反射机制的作用

1)在运行时判断任意一个对象所属的类

2)在运行时获取类的对象

3)在运行时访问java对象的属性,方法,构造方法等

首先需要搞清楚为什么要反射机制?这就涉及到了动态与静态的概念。

静态编译:在编译时确定类型,绑定对象,即通过。

动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了Java的灵活性,体现了多态的应用,降低类之间的耦合性。

IOC容器的技术剖析

1)IOC中最基本的技术就是“反射(Reflection)”编程,通俗来讲就是根据给出的类名(字符串方式)来动态的生成对象,这种编程方式可以让对象在生成时才被决定到底是哪一种对象。只是在spring中要生产 的对象都在配置文件中给出定义,目的就是提高灵活性和可维护性;

2)目前C#、Java和PHP5等语言均已支持反射,其中PHP5的技术书籍中,有时候也被译成“映射”。有关反射的概念和用法,大家应该都很清楚,反射的应用是很广泛的,很多的成熟框架,比如像Java中的Hibernate、Spring框架,。NET中的NHibernate、Spring.NET框架都是把“反射”作为最基本的技术手段;

3)反射技术其实很早就出现了,但是一直被忽略,没有被进一步的利用,当时的反射编程方式相对于正常的对象生成方式要慢至少10倍,现在的反射技术经过改良优化,已经非常成熟,反射方式生成对象和通常对象生成方式,速度已经相差不大了,大约是1-2倍的差距。

4)我们可以把IOC容器的工作模式看做是工厂模式的升华,可以把IOC容器看做是一个工厂,这个工厂里要生产的对象都在配置文件中给出定义,然后利用编程语言提供的反射机制,根据配置文件给出的类名生成相应的对象。从实现来看,IOC是把以前在工厂方法里写死的对象生成代码,改变为有配置问价来定义,也就是把工厂和对象生成的这两者独立分割开来,目的就是提高灵活性和可维护性。

反射与工厂模式实现IOC

Spring 中的IoC 的实现原理就是工厂模式加反射机制。我们首先看一下不用反射机

制时的工厂模式:

interface fruit {
public abstract void eat();
}
class Apple implements fruit{
public void eat(){
System.out.println("Apple");
}
}
class Orange implements fruit{
public void eat(){
System.out.println("Orange");
}
}

image.gif

//也就是说以后如果我们在添加其他的实例的时候只需要修改工厂类就行了

class Factory{
public static fruit getInstance(String fruitName){
fruit f=null;
if("Apple".equals(fruitName)){
f=new Apple();
} if("Orange".equals(fruitName)){
f=new Orange();
}
return f;
}
}
class hello{
public static void main(String[] a){
fruit f=Factory.getInstance("Orange");
f.eat();
}
}

image.gif

上面写法的缺点是当我们再添加一个子类的时候,就需要修改工厂类了。如果我们添加太多的子类的时候,改动就会很多。

下面用反射机制实现工厂模式:

interface fruit {
public abstract void eat();
}
class Apple implements fruit{
public void eat(){
System.out.println("Apple");
}
}
class Orange implements fruit{
public void eat(){
System.out.println("Orange");
}
}
class Factory{
public static fruit getInstance(String ClassName){
fruit f=null;
try{
f=(fruit)Class.forName(ClassName).newInstance();
}catch (Exception e) {
e.printStackTrace();
}
return f;
}
}
class hello{
public static void main(String[] a){
fruit f=Factory.getInstance("Reflect.Apple");
if(f!=null){
f.eat();
}
}
}

image.gif

总结:

现在就算我们添加任意多个子类的时候,工厂类都不需要修改。使用反射机制实现的工

厂模式可以通过反射取得接口的实例,但是需要传入完整的包和类名。而且用户也无法知道

一个接口有多少个可以使用的子类,所以我们通过属性文件的形式配置所需要的子类。

相关文章
|
存储 JavaScript 前端开发
用 HTML + JavaScript DIY 渐进式延迟法定退休年龄测算器
用 HTML + JavaScript DIY 渐进式延迟法定退休年龄测算器
|
10月前
|
Web App开发 前端开发 JavaScript
鸿蒙5开发宝藏案例分享---Web适配一多开发实践
这是一份实用的鸿蒙Web多设备适配开发指南,针对开发者在不同屏幕尺寸下的布局难题提供了解决方案。文章通过三大法宝(相对单位、媒体查询和窗口监听)详细介绍如何实现智能适配,并提供了多个实战案例,如宫格布局、对话框变形和自适应轮播图等。此外,还分享了调试技巧及工具推荐,帮助开发者快速上手并优化性能。最后鼓励读者实践探索,并提示更多官方资源等待发现。
|
存储 内存技术
内存条RAM详细指南
内存条(RAM)是电脑中用于临时存储数据和程序的部件,CPU依赖它执行操作。内存条经历了从主内存扩展到读写内存整体的发展,常见类型包括SDRAM和DDR SDRAM。内存容量、存取时间和奇偶校验是衡量其性能的关键指标。在选购时,应考虑类型、容量、速度和品牌,知名品牌的内存条提供更好的可靠性和稳定性。
5668 2
|
Web App开发 Python
Selenium Python 更改 chrome 默认下载目录
关于使用Selenium和Python无法更改Google Chrome默认下载目录的可能问题和解决方法,按照以上步骤,你应该能够成功使用Selenium和Python更改Google Chrome的默认下载目录。
705 0
|
监控 安全 Unix
在Linux中,如何进行安全漏洞扫描?
在Linux中,如何进行安全漏洞扫描?
|
资源调度
vue.config常用配置项、自动导入依赖项
vue.config常用配置项、自动导入依赖项
439 0
|
存储 供应链 开发者
Python列表打造简易进销存系统:轻松管理库存信息!
Python列表打造简易进销存系统:轻松管理库存信息!
556 0
|
存储 编译器 C语言
【C++ 基础知识】C++右值引用及其应用场景 (C++ Rvalue References and Their Use Cases)
【C++ 基础知识】C++右值引用及其应用场景 (C++ Rvalue References and Their Use Cases)
384 0
|
存储 Python
uwsgi部署python web项目
uwsgi部署python web项目
672 0
uwsgi部署python web项目
|
JavaScript 前端开发 C++
JavaScript 添加事件绑定的三种方法
JavaScript 添加事件绑定的三种方法
805 0