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 ...
随机推荐
- super 使用以及原理
用super也很久了,但是一直没有关注过他的原理.最近开始越来越多关注python更底层的实现和奇技淫巧.看到该方法越发使用得多所以也研究了一波 平时单继承可能是我们遇到最多的情况.无非就是类似情况. ...
- JQuery从入门到精通
1.JQuery查找元素 例:将表格的单元格中件数和重量差异不为0的数据标红 代码如下: <style> .notice{ color: red; } .right{ color: gre ...
- 关于jQuery.when()用法的调研
1.该方法在jQuery1.5开始被引入. 2.用法测试 a.var url1 = "/resource/ar/hometab/index_tab_games.json", ...
- BZOJ2002[Hnoi2010]弹飞绵羊——LCT
题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系 ...
- ajax跨域,携带cookie
解决方案很简单. 直接上代码: web.xml中: 添加了 cors来解决跨域 (奇怪的是,credentials设置为false.反正这个是照搬的...) <filter> ...
- Codeforces960G Bandit Blues 【斯特林数】【FFT】
题目大意: 求满足比之前的任何数小的有A个,比之后的任何数小的有B个的长度为n的排列个数. 题目分析: 首先写出递推式,设s(n,k)表示长度为n的排列,比之前的数小的数有k个. 我们假设新加入的数为 ...
- hdu 4417 Super Mario (主席树)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 题意: 给你段长为n的序列,有q个询问,每次询问区间[l.r]内有多少个数小于等于k 思路: 之前用 ...
- MT【24】一道五次方程的求根题
解答: 评:一般的五次及以上的多项式方程是无根式解的,只能用计算机去精确到某某位.但是特殊的比如$x^5=1$显然有根式解,本题就是一个不平凡的特殊的例子,这里的代换用于求解三次方程的求根过程是一样的 ...
- 自学Zabbix3.12.6-动作Action-Escalations配置
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 3.12.6 自学Zabbix3.12.6-动作Action-Escalations配置 1. 概 ...
- UVALive - 6440(模拟)
题目链接:https://vjudge.net/contest/241341#problem/G 题目大意:输入一个N,n次操作.对于第一种操作增加一个病人,告诉病人的t0,st0,r.第二种操作,在 ...