Javaweb中提到的反射浅析(附源码)
反射:一个jdk5.0的新特性,高级运用。在后期的框架中,这个是一大重点,现在估计我们都不会太多的接触他的。但是为了后面的铺垫,我想还是先了解一下:
先构造一个类,然后我们用反射来获取,调用里面的方法,属性
package com.changeyd.test09;
public class Person {
// 属性
private String name;
private String id;
// 没有参数的构造方法
public Person() {
}
public Person(String name, String id) {
super();
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
好了,创建好类了,就可以构造一个Test来获取它的内容了:
哦。。对对对,在运用前,先得了解一下反射的基本原理:
一:反射的原理
*应用在一些通用性比较高的代码中
*在后期中的框架中,大多数都是使用反射来实现的
*在框架开发中,都是基于配置文件开发
**在配置文件中配置了类,可以通过反射得到类中的所有内容,可以让类中的某个方法来执行
*类中的所有内容:属性、没有参数的构造方法,有参数的构造方法、普通方法
**反射的原理:
*首先需要把java文件保存到本地硬盘 .java
*编译java文件,成 .class文件
*使用jvm,把class文件通过类加载加载到内存中
*万事万物皆对象,class文件到内存中使用Class类表示
*当使用反射时候,首先需要获取到Class类,得到这个类之后,就可以得到clss文件里面的所有内容了
-包含属性 构造方法 普通方法
*属性通过一个类:Filed
*构造方法通过一个类:Constructor
*普通方法通过一个类:Method
二:现在就可以获取第一步,无参方法
使用反射操作类里面的无参数的构造方法
*首先获取到Class类
// 获取class类
Class class1 = Person.class;
Class class2 = new Person().getClass();
Class class3 = Class.forName("com.changeyd.test09.Person");
*比如:对一个类型进行实例化,可以new,如果不使用new,如何获取?
//得到class类
Class class1 = Class.forName("com.changeyd.test09.Person");
//得到Person类的实例
Person person = (Person) class1.newInstance();
-代码:
//操作无参数的构造方法
@Test
public void test1() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
//得到class类
Class class1 = Class.forName("com.changeyd.test09.Person");
//得到Person类的实例
Person person = (Person) class1.newInstance();
//设置值
person.setName("Wangji");
System.out.println(person.getName());
}
三:使用反射操作有参数的构造方法
//操作有参数的构造方法
@Test
public void test2() throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// 得到class类
Class class1 = Class.forName("com.changeyd.test09.Person");
// 使用有参数的构造方法
// class1.getConstructors();//获取所有的构造方法
Constructor cs = class1.getConstructor(String.class, String.class);
// 通过有参数的构造方法设置值
// 通过有参数的构造方法来创建Person实例
Person person = (Person) cs.newInstance("lisi", "100");
System.out.println(person.getId() + " " + person.getName());
}
四:使用反射来操作属性
* @Test
public void test3() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException,
SecurityException, InstantiationException {
try {
// 得到class类
Class class1 = Class.forName("com.changeyd.test09.Person");
// 得到name属性
// class1.getDeclaredFields();//表示得到所有的属性
// 得到Person类的实例
Person person = (Person) class1.newInstance();
//通过这个方法得到属性,参数是属性的名称
Field field = class1.getDeclaredField("name");
//操作的是私有的属性,不让操作,需要设置可以操作私有属性setAccessible(true),可以操作私有属性
field.setAccessible(true);
// 设置name值 set方法,两个参数:第一个参数类的实例,第二个参数是设置的值
field.set(person, "wangwu");// 相当于在p.name = "wangwu";
System.out.println(field.get(person)); // 相当于p.name;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
五:使用泛型来操作普通方法
*使用Method来表示普通方法
*代码
// 普通方法,比如操作 setName
@Test
public void test4() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException,
NoSuchMethodException, SecurityException, InstantiationException, ClassNotFoundException {
// 得到Class类
Class class1 = Class.forName("com.changeyd.test09.Person");
// 得到Person的实例
Person person = (Person) class1.newInstance();
// 得到普通方法
// class1.getDeclaredFields();//得到所有的普通方法
//传递两个参数:第一个参数,方法名称;第二个参数,通过方法设置的值
Method method = class1.getDeclaredMethod("setName", String.class);
// 让setName方法执行,执行设置值
//使用invoke(person, "niuqi");传递两个参数;第一个参数,person实例;第二个参数,设置的值
//执行了invoke方法之后,相当于,执行了setName方法,同事通过这个方法设置了一个值是niuqi。
method.invoke(person, "niuqi");
System.out.println(person.getName());
}
在里面还需要一些注意的地方:
//如果操作的是私有的方法,需要设置值为true
method.setAccessible(true);
*当操作的方法是静态的方法时候,因为静态方法调用的方式是 类名.方法名,不需要类的实例
*使用反射操作静态方法的时候,也是不需要实例
*在invoke方法的第一个参数里面,写一个null
-method.invoke(null, "wangji");
对于反射中,原理很重要,先了解,但是对于反射,这些只是皮毛,在进入框架,才有具体的认识
Javaweb中提到的反射浅析(附源码)的更多相关文章
- V8中的快慢数组(附源码、图文更易理解😃)
接上一篇掘金 V8 中的快慢属性,本篇分析V8 中的快慢数组,了解数组全填充还是带孔.快慢数组.快慢转化.动态扩缩容等等.其实很多语言底层都采用类似的处理方式,比如:Golang中切片的append操 ...
- Lazy<T>在Entity Framework中的性能优化实践(附源码)
在使用EF的过程中,导航属性的lazy load机制,能够减少对数据库的不必要的访问.只有当你使用到导航属性的时候,才会访问数据库.但是这个只是对于单个实体而言,而不适用于显示列表数据的情况. 这篇文 ...
- Android中Canvas绘图基础详解(附源码下载) (转)
Android中Canvas绘图基础详解(附源码下载) 原文链接 http://blog.csdn.net/iispring/article/details/49770651 AndroidCa ...
- Vue路由实现之通过URL中的hash(#号)来实现不同页面之间的切换(图表展示、案例分析、附源码详解)
前言 本篇随笔主要写了Vue框架中路由的基本概念.路由对象属性.vue-router插件的基本使用效果展示.案例分析.原理图解.附源码地址获取. 作为自己对Vue路由进行页面跳转效果知识的总结与笔记. ...
- 在网站开发中很有用的8个 jQuery 效果【附源码】
jQuery 作为最优秀 JavaScript 库之一,改变了很多人编写 JavaScript 的方式.它简化了 HTML 文档遍历,事件处理,动画和 Ajax 交互,而且有成千上万的成熟 jQuer ...
- Web 开发中很实用的10个效果【附源码下载】
在工作中,我们可能会用到各种交互效果.而这些效果在平常翻看文章的时候碰到很多,但是一时半会又想不起来在哪,所以养成知识整理的习惯是很有必要的.这篇文章给大家推荐10个在 Web 开发中很有用的效果,记 ...
- Entity Framework在Asp.net MVC中的实现One Context Per Request(附源码)
上篇中"Entity Framework中的Identity map和Unit of Work模式", 由于EF中的Identity map和Unit of Work模式,EF体现 ...
- javaweb异常提示信息统一处理(使用springmvc,附源码)
一.前言 后台出现异常如何友好而又高效地回显到前端呢?直接将一堆的错误信息抛给用户界面,显然不合适. 先不考虑代码实现,我们希望是这样的: (1)如果是页面跳转的请求,出现异常了,我们希望跳转到一个异 ...
- 在Winform窗体中使用WPF控件(附源码)
原文:在Winform窗体中使用WPF控件(附源码) 今天是礼拜6,下雨,没有外出,闲暇就写一篇博文讲下如何在Winform中使用WPF控件.原有是我在百度上搜索相关信息无果,遂干脆动手自己实现. W ...
随机推荐
- poj 3694 Network(割边+lca)
题目链接:http://poj.org/problem?id=3694 题意:一个无向图中本来有若干条桥,有Q个操作,每次加一条边(u,v),每次操作后输出桥的数目. 分析:通常的做法是:先求出该无向 ...
- matplotlib绘图3
#scatter fig=plt.figure() ax=fig.add_subplot(3,3,1)#3行3列 第一个图 n=128 X=np.random.normal(0,1,n) Y=np.r ...
- matplotlib绘图2
fig=plt.figure() fig.add_subplot(3,3,1)#3行3列 第一个图 n=128 X=np.random.normal(0,1,n) Y=np.random.normal ...
- BZOJ1926[Sdoi2010]粟粟的书架——二分答案+主席树
题目描述 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Co rmen 的文章.粟粟家中有一个 R行C 列的巨型书架,书架的每一个位 ...
- BZOJ1283 序列(费用流)
不妨看做是先用k个指针指向被选择的前k个元素,然后每次将选中当前第一个元素的指针移到最后,并且需要满足位置变化量>=m.显然这样可以构造出所有的合法方案.那么可以以此建立费用流模型,以一条流量k ...
- 最小费用最大流spfa
#include <iostream> #include <cstring> #include <cstdio> #include <queue> #d ...
- hud 1312
There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A ...
- 批量修改sharepoint 2013站点里区域设置
cls [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") foreach ($we ...
- 洛谷 P1158 导弹拦截(不是那个DP) 解题报告
P1158 导弹拦截 题目描述 经过1111年的韬光养晦,某国研发出了一种新的导弹拦截系统,凡是与它的距离不超过其工作半径的导弹都能够被它成功拦截.当工作半径为0时,则能够拦截与它位置恰好相同的导弹. ...
- break、continue区别
break命令break命令允许跳出所有循环(终止执行后面的所有循环).下面的例子中,脚本进入死循环直至用户输入数字大于5.要跳出这个循环,返回到shell提示符下,就要使用break命令.1. #! ...