浅谈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(); 如果想变成 实例化 其他类, 那么必须修改源代码, ...
随机推荐
- Google单元测试框架gtest--值参数测试
测试一个方法,需要较多个参数进行测试,比如最大值.最小值.异常值和正常值.这中间会有较多重复代码工作,而值参数测试就是避免这种重复性工作,并且不会损失测试的便利性和准确性. 如果测试一个函数,需要些各 ...
- 番外----python入门----pip相关
pip 是 Python 包管理工具,该工具提供了对Python 包的查找.下载.安装.卸载的功能. 但是,由于pip使用的pip仓库默认为:http://pypi.python.org/ 是国外的 ...
- 线上MySQL读写分离,出现写完读不到问题如何解决
大家好,我是历小冰. 今天我们来详细了解一下主从同步延迟时读写分离发生写后读不到的问题,依次讲解问题出现的原因,解决策略以及 Sharding-jdbc.MyCat 和 MaxScale 等开源数据库 ...
- FreeBSD pkg安装软件时出现创建用户失败解决
问题示例:[1/1] Installing package...===> Creating groups.Creating group 'package' with gid '000'.===& ...
- OpenCV 之 角点检测
角点 (corners) 的定义有两个版本:一是 两条边缘的交点,二是 邻域内具有两个主方向的特征点. 一般而言,角点是边缘曲线上曲率为极大值的点,或者 图像亮度发生剧烈变化的点.例如,从人眼角度来看 ...
- 字符串匹配-BF算法和KMP算法
声明:图片及内容基于https://www.bilibili.com/video/av95949609 BF算法 原理分析 Brute Force 暴力算法 用来在主串中查找模式串是否存以及出现位置 ...
- HashMap源码阅读(小白的java进阶)
OverView 构造方法 //构造方法 public HashMap(int initialCapacity, float loadFactor) { if (initialCapacity < ...
- 解析库--XPath
from lxml import etree 2 text = ''' 3 <div> 4 <ul> 5 <li class = "item-0"&g ...
- swing实现QQ登录界面1.0( 实现了同一张图片只加载一次)、(以及实现简单的布局面板添加背景图片控件的标签控件和添加一个关闭按钮控件)
swing实现QQ登录界面1.0( 实现了同一张图片只加载一次).(以及实现简单的布局面板添加背景图片控件的标签控件和添加一个关闭按钮控件) 代码思路分析: 1.(同一张图片仅仅需要加载一次就够了,下 ...
- Bonuses on a Line Gym - 102569B
题目链接:https://vjudge.net/problem/Gym-102569B 题意:数轴上有N个点,从0出发最多走t步问最多经过几个点. 思路:分开存负数点和整数点,然后枚举每个端点,某个点 ...