formdata 接受参数中带有class 对象_浅析JAVA中的反射机制及对Servlet的优化
今天来聊聊java中的反射机制,工作以后发现很多东西动不动就要使用反射或者动态代理,如果不能很好的理解反射,那么对于动态代理等一些重要的设计模式就会有种不够通透的感觉。
所谓的反射,就是在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制。通俗点讲,通过反射,该类对我们来说是完全透明的,想要获取任何东西都可以-----很强大。
想要使用反射机制,就必须要先获取到该类的字节码文件对象(.class),通过字节码文件对象,就能够通过该类中的方法获取到我们想要的所有信息(方法,属性,类名,父类名,实现的所有接口等等),每一个类对应着一个字节码文件也就对应着一个Class类型的对象,也就是字节码文件对象。
获取字节码文件对象的三种方式。
1、Class clazz1 = Class.forName("全限定类名"); //通过Class类中的静态方法forName,直接获取到一个类的字节码文件对象,此时该类还是源文件阶段,并没有变为字节码文件。
2、Class clazz2 = Person.class; //当类被加载成.class文件时,此时Person类变成了.class,在获取该字节码文件对象,也就是获取自己, 该类处于字节码阶段。
3、Person p = new Preson();
Class clazz3 = p.getClass(); //通过类的实例获取该类的字节码文件对象,该类处于创建对象阶段
有了字节码文件对象才能获得类中所有的信息,我们在使用反射获取信息时,也要考虑使用上面哪种方式获取字节码对象合理,视不同情况而定。下面介绍Class类的功能
反射机制能够获得的信息:
1.1通过字节码对象创建实例对象:
//如果user类还没有加载,那么可以在源文件阶段获取其字节码文件对象
Class clazz1 = Class.formName("Reflect.User");
//创建User实例,这里通过User的无参构造方法来创建对象
User user = (User)clazz1.newInstance();
//然后通过user对象就可以获取我们想要的信息
1.2获取指定构造器方法,constructor没有无参构造方法:
//获取字节码文件
Class clazz1 = Class.forName("Reflect.User");
//先获取有参构造器,parameterType:表示参数列表,有多少就要写多少,如果不写,默认调用无参构造方法
Construnctor con = clazz1.getConstructor(int.class,String.Class);
//通过构造器来实例化对象,将实际的参数传进去
User user = (User)con.newInstance(12,"小明");
总结上面创建实例对象:该类无参的构造方法来是使用该Class类的newInstance()方法来创建对象的, 如果一个类没有无参的构造函数, 就不能这样创建了。
这时候可以使用getConstructor(String.class,int.class)方法获取一个指定的构造函数然后再调用Constructor类的newInstance("张三",20)方法创建对象获取全部构造方法。
Class clazz1 = Class.forName("Reflect.User");
//获取所有的构造方法
Constructor[] con = clazz1.getConstructors();
//for循环遍历
for(int i=0;i<con.length;i++){
//获取每个构造函数中的参数类型字节码对象
Class[] parameterTypes = con[i].getParameterTypes();
syso("第"+i+"个构造函数");
for(int j =0;j<paraparameterTypes.length;j++){
//获取构造函数中的参数类型
syso(paraparameterTypes[j].getName()+",");
}
}
1.3获取成员变量并使用---Filed对象
获取指定成员变量
Class.getField(String)方法可以获取类中的指定字段(可见的), 如果是私有的可以使用getDeclaedField("name")方法获取,通过set(obj, "李四")方法可以设置指定对象上该字段的值, 如果是私有的需要先调用setAccessible(true)设置访问权限,用获取的指定的字段调用get(obj)可以获取指定对象中该字段的值。
1.4获得方法并使用 Method
Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以获取类中的指定方法,如果为私有方法,则需要打开一个权限。setAccessible(true);用invoke(Object, Object...)可以调用该方法,跟上面同理,也能一次性获得所有的方法:
1.5、获得该类的所有接口
Class[] getInterfaces():确定此对象所表示的类或接口实现的接口
返回值:接口的字节码文件对象的数组
1.6、获取指定资源的输入流
InputStream getResourceAsStream(String name)
return:一个 InputStream 对象;如果找不到带有该名称的资源,则返回 null
参数:所需资源的名称,如果以"/"开始,则绝对资源名为"/"后面的一部分。
上面讲了一些反射的概念和方法,但是在我们开发中,经常会出现这样的情况,就是随着业务逻辑的不断增多,每写一个功能时,就需要写一个对应的servlet,最后就会导致Servlet异常的臃肿。下面来说说如何在servlet中使用反射对其进行优化:
每次从页面传过来一个参数,method="xxx"; 然后编写一个Servlet,获得其参数method的值,进行判断,如果是add,则调用add方法,如果是delete,则调用delete方法,这样就可以写在一个servlet中实现所有的功能了。
编写一个BaseServlet继承HttpServlet,这是一个通用的BaseServlet,这里需要我们明白servlet的生命周期,也就是service方法,因为是servlet,所以在访问的时候,会经过service方法,而子类MyServlet001中并没有,所以就到父类BaseServlet中找,发现有,然后获取参数即知道了需要调用什么方法,因为方法的编写都在子类中,所以通过反射,获取到子类中对应的方法并运行,其中需要注意的是this这个参数在BaseServlet中的用法,需要理解它,才能理解我们这个程序。
编写具体实现的方法servlet类。MySerlvet001 extends BaseServlet
formdata 接受参数中带有class 对象_浅析JAVA中的反射机制及对Servlet的优化相关推荐
- java中的io复用_从 Java 中的零拷贝到五种IO模型
在之前的文章中,我们聊过了 Java 中的零拷贝,零拷贝就是指数据不会在内核空间和用户空间之间相互拷贝.这样就减少了内核态与用户态的切换,自然就很高效. 拷贝文件只是 IO 操作中一个特殊的情况,大多 ...
- java 异常对象_在java中的异常处理中的异常对象是什么
展开全部 Exception类以及他的子类 的一个实例对象 比如32313133353236313431303231363533e58685e5aeb931333264633563 常见异常 1. j ...
- java类怎么删除对象_在java中删除一个对象?
在java中删除一个对象? 我想删除一个我创build的对象(跟随着你的一个椭圆),但是我怎么做呢? delete follower1; 没有工作. 编辑: 好吧,我会给更多的上下文. 我正在制作一个 ...
- java释放对象_在Java中释放Semaphore对象的正确方法是什么...
信号量没有所有权概念.许可证不是真实的东西,只是信号量保持的计数.所以问题是,方法执行后计数正确吗? 如果您被打扰了,您会留下一个或两个可用许可证吗? api文档中Oracle网站上的信号量示例没有f ...
- java如果把字符串转成对象_为什么Java中的字符串对象是不可变的,有什么好处?...
专注于Java领域优质技术号,欢迎关注 原创: 阿杜的世界 阅读本文大概需要 4分钟. 所谓不可变对象,是指一个对象在创建后,它的内部状态不会被改变的对象.这意味着当我们将一个不可变对象的引用赋值给某 ...
- java 堆栈 对象_在Java中,哪些对象放在堆栈上,哪些放在堆上?
对于 Java函数中的语句: Xxx xxx = new Xxx() { public Abc abc(final Writer out) { return new SomeFunction(out) ...
- java中的方法求和_在Java中模拟求和类型的巧妙解决方法
java中的方法求和 在继续阅读实际文章之前,我想感谢令人敬畏的Javaslang库的作者Daniel Dietrich ,他在我面前有了这个主意: @lukaseder尝试使用静态方法<T,T ...
- java中字符流 字节流_理解Java中字符流与字节流的区别
1. 什么是流 Java中的流是对字节序列的抽象,我们可以想象有一个水管,只不过现在流动在水管中的不再是水,而是字节序列.和水流一样,Java中的流也具有一个"流动的方向",通常可 ...
- 在java中如何输入角度_在Java中获取角度的反余弦
为了获得Java中给定值的反余弦,我们使用java.lang.Math.acos()方法.该acos()方法接受需要计算角度的双精度值.返回的角度范围在0到pi之间.如果参数为NaN或大于1或小于-1 ...
最新文章
- mvc存储Cookie和读取Cookie方法
- 读书笔记 — Java高并发程序设计 — 第三章 — 锁
- 一阶差分单位根检验_计量经济学第11讲(时间序列计量经济学模型:平稳性及其检验)...
- 江苏实时分析评价系统项目总结报告
- Linux : ext3_free_blocks: Freeing blocks not in datazone
- 机器学习/深度学习常用库的配置及其适用的算法总结
- 时序报告要看哪些指标
- 2021-11-17每日刷题打卡
- 网络写作一年稿酬最高可达150万元
- D2D加载图片资源(2)
- excel处置4000行数据卡_数十万数据Excel数据不好处理怎么办?几行Python搞定
- 国产操作系统Office哪个好用?6款工具推荐!
- vue实现中根据字母或者中文进行排序
- C++ 强制类型转换:static_cast、dynamic_cast、const_cast 和 reinterpret_cast
- UFUNufun币ufun优趣集团
- 如何下载网易云音乐APP里的MV和短视频?
- 充气娃娃?Python告诉你到底有多爽......
- 微波课设 基于pyqt5+pyqtgraph的Smith圆图GUI程序设计
- 平淡生活:戴戒指的学问
- 537 复数乘法(模拟)
热门文章
- 简谈Java的join()方法(转)
- 《The Pursuit of Happyness / 当幸福来敲门》(2006)
- Windows Server 2003 SP2中文版开放下载
- winscp怎么更改linux权限,Linux下,WinSCP普通用户登录sftp后切换到root权限 教程
- mysql有没有mssql执行计划_MSSQL优化执行计划
- python创建一个有序链表_Python实现合并两个有序链表的方法示例
- Mac/Linux使用fcrackzip
- Mac安装iproute2/dig/traceroute
- AudioUnitRender -10876
- Windows中的磁盘分区、MBR、GPT