浅谈Java的反射机制和作用
浅谈Java的反射机制和作用
作者:Java大师
欢迎转载,转载请注明出处
很多刚学Java反射的同学可能对反射技术一头雾水,为什么要学习反射,学习反射有什么作用,不用反射,通过new也能创建用户对象。
那么接下来大师就带你们了解一下反射是什么,为什么要学习反射?
下面我们首先通过一个实例来说明反射的好处:
方法1、不用反射技术,创建用户对象,调用sayHello方法
1.1 我们首先创建一个User类
package com.dashi; /**
* Author:Java大师
* User对象,包含用户的id和姓名以及sayHello方法
*/
public class User {
private int id;
private String name; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String sayHello(String who) {
return who+ "{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
1.2 创建测试用例
package com.dashi; import org.junit.Test; /**
* 创建Juinit测试对象
*/
public class Test01 { @Test
public void test01(){
User user = new User();
user.setId(1);
user.setName("Java大师");
//调用sayHello方法
System.out.println(user.sayHello("user1"));
}
}
1.3运行结果如下,打印出sayHello结果:
user1{id=1, name='Java大师'}
Process finished with exit code 0
方法2、通过反射技术,创建用户对象,调用sayHello方法
2.1 调用测试用例
@Test
public void test02(){
try {
//创建用户对象字符串
String obj = "com.dashi.User";
//通过用户对象字符串加载类
Class clz = Class.forName(obj);
//通过newInstance方法,创建用户对象
User user = (User)clz.newInstance();
user.setId(2);
user.setName("Java大师2");
//调用sayHello方法
System.out.println(user.sayHello("user2"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
2.2 运行结果如下,打印出sayHello结果:
user1{id=1, name='Java大师'}
user2{id=2, name='Java大师2'} Process finished with exit code 0
通过两者以上对比,发现方法1和方法2都能创建用户对象,并调用sayHello方法,并且打印的结果都正确。但是方法2比方法1先进的地方是方法2针对字符串编程,方法1针对实体类编程。
那么针对字符串编程有什么好处呢,小伙伴们耐心接着往下看:
我们通过一个Dao层来演示下针对字符串编程的好处:
假设我们有一个IUserDao接口,里面有一个load方法,代码如下:
package com.dashi; public interface IUserDao {
public void load();
}
有两个实现类来实现该IUserDao接口,实现类如下:
package com.dashi; /**
* A实现类
*/
public class AUserDao implements IUserDao{
@Override
public void load() {
System.out.println("这是AUserDao");
}
}
package com.dashi; /**
* B实现类
*/
public class BUserDao implements IUserDao{
@Override
public void load() {
System.out.println("这是BUserDao");
}
}
方法3、不通过反射技术,创建IUserDao,调用load方法
@Test
public void testDao01(){
IUserDao userDao = new AUserDao();
userDao.load();
}
打印结果如下:
这是AUserDao Process finished with exit code 0
方法4、通过反射技术,创建IUserDao,调用load方法
@Test
public void testDao02(){
try {
//创建接口实现类字符串
String dao_str = "com.dashi.AUserDao";
//通过类加载的方式创建IUserDao
IUserDao userDao = (IUserDao) Class.forName(dao_str).newInstance();
//调用load方法
userDao.load();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
打印结果如下:
这是AUserDao
这是AUserDao Process finished with exit code 0
通过类加载的方式,我们也创建了IUserDao对象,调用了load方法,和方法3的运行结果一样
方法5、通过反射技术,创建IUserDao,调用load方法
@Test
public void testDao03(){
try {
//创建接口实现类字符串
String dao_str = "com.dashi.BUserDao";
//通过类加载的方式创建IUserDao
Class clz = Class.forName(dao_str);
IUserDao userDao= (IUserDao)clz.newInstance();
//创建调用方法字符串
String mm = "load";
//创建method对象
Method method = clz.getMethod(mm);
//调用通过反射调用invoke方法
method.invoke(userDao);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
运行结果如下:
这是AUserDao
这是AUserDao
这是BUserDao Process finished with exit code 0
通过method.invoke方法也可以实现load方法的调用
方法5比方法4和方法3更加灵活,不需要知道AUserDao和BUserDao实体类,只提供类的字符串和类的方法名称,通过反射就可以实现方法的调用
实战中的实际意义
假设我们的Dao层,从mysql迁移导oracle,SQL server等
运用反射技术,通过字符串编程,那么我们不需要进行Dao层实体类的更改,只需要改动我们的字符串名字就可以进行Dao层的更新。比如:
1、不通过反射技术,我们需要修改实现类中的AUserDao改为BUserDao
IUserDao userDao = new AUserDao();
userDao.load();
``如果有几百个Dao,我们需要修改几百次``
``
2、运用发射技术通过字符串编程,我们可以把字符串定义在properties文件中,通过修改properties文件中的配置即可实现Dao的更新
//创建接口实现类字符串
String dao_str = "com.dashi.AUserDao"; //可以改写为:String dao_str = PropertyUtil.get("dao");
//通过类加载的方式创建IUserDao
IUserDao userDao = (IUserDao) Class.forName(dao_str).newInstance();
//调用load方法
userDao.load();
这就是反射技术的实际运用,通过以上实例就可以看出字符串编程和通过实现类编程的最大的区别和实际的意义
并且通过反射技术可以使我们的编程更加灵活
灵活运用反射技术,我们可以设计出更加灵活的框架哦~
关注博主公众号, 每日推送干货文章, 回复「资源」, 即可领取全网最火的Java学习&面试核心资源!~。
浅谈Java的反射机制和作用的更多相关文章
- Java:描述反射机制的作用?举几个反射的应用?
比较全的解释了:JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方 ...
- 浅谈java垃圾回收机制
今天看thinking in java,里面很详细的谈到java垃圾回收器机制,看完后让我对这神秘的区域有一定的了解,特写一些小总结记录下来. 分两点来说. 第一点:Object.finalize() ...
- Android5_浅谈Java的package机制
当代码量越来越大,类越来越多.尤其会增加同名类的风险.所以对类进行管理就显得非常重要. 包(package)机制是java中管理类的重要手段. 包名的命名方式:业内默认的做法是使用公司的网络域名的倒写 ...
- 浅谈Java多线程同步机制之同步块(方法)——synchronized
在多线程访问的时候,同一时刻只能有一个线程能够用 synchronized 修饰的方法或者代码块,解决了资源共享.下面代码示意三个窗口购5张火车票: package com.jikexueyuan.t ...
- 浅谈Java的反射的原理
Java的编译过程 谈及反射,不得不先了解一下,java的整个编译过程,整体的java编译过程可以参考 之前的一篇 一个java文件被执行的历程 这里我们只针对 对象这一层级来讨论,一个java文件, ...
- 浅谈Java之反射
反射 四种获取Class实例的方法 定义测试结构 获取属性结构 获取方法结构 获取构造器结构(包括父类泛型) 获取实现的接口 获取所在包 获取注解 获取并创建指定构造器 获取指定属性 获取并运行指定方 ...
- java的反射机制浅谈(转)
原文链接:java的反射机制浅谈 一.java的反射机制浅谈 1.何谓反射机制 根据网文,java中的反射机制可以如此定义: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性 ...
- Java反射机制的作用?
Java反射机制的作用? 解答:Java反射机制的作用是: 1)在运行时判断任意一个对象所属的类. 2)在运行时构造任意一个类的对象. 3)在运行时判断任意一个类所具有的成员变量和方法. 4)在运行时 ...
- java反射机制的作用与优点
java的反射机制就是增加程序的灵活性,避免将程序写死到代码里,例如: 实例化一个 person()对象, 不使用反射, new person(); 如果想变成 实例化 其他类, 那么必须修改源代码, ...
随机推荐
- rar密码破解工具汇总
rar密码破解工具汇总 前言 假如酷爱在网络上找各种资源的你,经历千辛万苦终于找到了一个rar打包的文件,兴奋地慌忙点击,可打开才发现是加密的,相信这样的场景很多人都遇到过,今天就针对压缩文件密码的破 ...
- Go的指针
目录 指针 一.指针的声明 二.指针的默认值(Zero Value) 三.指针的解引用 四.向函数传递指针参数 1.非 数组/切片 指针传参 2.数组/切片 指针传参 五.Go不支持指针运算 指针 指 ...
- springcloud alibaba-nacos配置中心
nacos除了充当注册中心外,还能作为配置中心,下面进行演示. 1. 创建 模块,用于读取 nacos配置中心的统一配置 2. 添加依赖 <dependencies> <!-- na ...
- 最新版大数据平台安装部署指南,HDP-2.6.5.0,ambari-2.6.2.0
一.服务器环境配置 1 系统要求 名称 地址 操作系统 root密码 Master1 10.1.0.30 Centos 7.7 Root@bidsum1 Master2 10.1.0.105 Cent ...
- 利用CORDIC算法计算三角函数
这里主要先介绍如何利用CORDIC算法计算固定角度\(\phi\)的\(cos(\phi)\).\(sin(\phi)\)值.参考了这两篇文章[1].[2]. 一般利用MATLAB计算三角函数时,用\ ...
- HDOJ-4725(Dijikstra算法+拆点求最短路)
The Shortest Path in Nya Graph HDOJ-4725 这题是关于最短路的问题,但是和常规的最短路有点不同的就是这里多了层次这一结构. 为了解决这一问题可以把每一层抽象或者划 ...
- CCF(消息传递口:80分):字符串相关+队列
消息传递口 201903-4 本题主要是利用队列进行模拟,因为一开始我没有注意到要按照顺序,所以一开始的解法错误. #include<iostream> #include<algor ...
- 如果一个网站存在CSRF漏洞,可以通过CSRF漏洞做下面那些事情?
如果一个网站存在CSRF漏洞,可以通过CSRF漏洞做下面那些事情? 答:跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求.利用受害者在被攻击网站已经获取的注册凭证 ...
- 部分rpm包总结描述
acl-2.2.51-15.el7.x86_64 Commands for Manipulating POSIX(可移植操作系统接口 of unix) Access Control Lists.有ge ...
- JS table排序
<html lang="en"> <head> <meta charset="UTF-8"> <meta http-e ...