反射技术菜鸟从入门到精通(一)

前言

俗话说得好:“反射反射,程序员的快乐” 。用好反射,可以使你的开发效率事半功倍。反射技术作为Java特性,已经成为框架构建的基础。如果灵活掌握反射,可谓“一步登天”!

什么是反射?

JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

Java的反射机制是在编译并不确定是哪个类被加载了,而是在程序运行的时候才加载、操作。使用在编译期并不知道的类,这样的特点就是反射。

反射的作用?

  1. 由于众多框架都是用到了反射机制(例如Spring的IOC与AOP,Hibernate的对象实体关系映射),学了反射我们可以更好的学习框架;
  2. 根据反射的特点,我们可以通过反射来了解类的构成,做出一系列比较通用的工具代码(也就是框架);
  3. 将许多代码变为自动化实现,以此达到减少开发周期的目的。
  4. 节约下来的时间可以和美女愉快的交流,或者躲在角落处快乐的喝肥宅水^_^(这条比较关键!)

Case1:

  我们在做JDBC查询数据库时,希望把数据库中的多条记录保存到java中的一个List中对象,例如将Scott的EMP(oracle示例表,oracle安装后自带)表的数据放到java中的Emp的对象中,然后再将Emp的对象放到一个集合中:

package cn.gzsxt.test;

import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;

import cn.gzsxt.model.Emp;import cn.gzsxt.util.DBUtil;

public class TestEmp {

public List getAllEmp() {

List list = new ArrayList<>();

Connection conn = DBUtil.getConnection();

PreparedStatement ps = null;

ResultSet rs = null;

try {

String sql = "select * from emp";

ps = conn.prepareStatement(sql);

rs = ps.executeQuery();

while (rs.next()) {

// 创建一个Emp的对象

Emp e = new Emp();

e.setEmpno(rs.getInt("empno"));

e.setEname(rs.getString("ename"));

e.setJob(rs.getString("job"));

e.setMgr(rs.getInt("mgr"));

e.setHiredate(rs.getDate("hiredate"));

e.setSal(rs.getDouble("sal"));

e.setComm(rs.getDouble("comm"));

e.setDeptno(rs.getInt("deptno"));

list.add(e);

}

} catch (SQLException e) {

e.printStackTrace();

} finally {

DBUtil.close(conn, ps, rs);

}

return list;

}

}

写过JDBC的同学都清楚,红色部分代码的意义是创建对象,并为对象的属性赋值。这些操作其实是“没有意义的体力活”。如果下次查询Dept表,还要创建Dept对象,所以我们可以利用反射将其封装成一个方法:

package cn.gzsxt.test;

import java.lang.reflect.Field;import java.lang.reflect.Method;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.ResultSetMetaData;
import java.util.ArrayList;import java.util.List;import cn.gzsxt.util.DBUtil;

public class TestEmp {

// 目的:将数据库中的一行记录转化为java中一个对象

public List rows2beans(String sql, Class cls) {

List list = new ArrayList();

Connection conn = DBUtil.getConnection();

PreparedStatement ps = null;

ResultSet rs = null;

try {

ps = conn.prepareStatement(sql);

rs = ps.executeQuery();

// 每一个rs对象都对应一个ResultSetMetaData对象

ResultSetMetaData rsmd = rs.getMetaData();

// 获取查询的列数

int count = rsmd.getColumnCount();

while (rs.next()) {

Object object = cls.newInstance(); //cls决定生成什么对象

for (int i = 0; i < count; i++) {

// 获取第一列的名字

String fieldName = rsmd.getColumnName(i + 1).toLowerCase();

// 通过列名获取类中的属性的表述对象

Field field = cls.getDeclaredField(fieldName);

// 根据set方法名获取set方法对应的表述对象

Method m = cls.getDeclaredMethod(getSetMethodName(fieldName), field.getType());

Object objval = rs.getObject(fieldName);

if (objval != null) {

if (objval instanceof Number) {

if (field.getType().getName().equals("int")) {

m.invoke(object, rs.getInt(fieldName));

} else if (field.getType().getName().equals("long")) {

m.invoke(object, rs.getLong(fieldName));

} else if (field.getType().getName().equals("double")) {

m.invoke(object, rs.getDouble(fieldName));

} else if (field.getType().getName().equals("short")) {

m.invoke(object, rs.getShort(fieldName));

} else if (field.getType().getName().equals("byte")) {

m.invoke(object, rs.getByte(fieldName));

} else if (field.getType().getName().equals("float")) {

m.invoke(object, rs.getFloat(fieldName));

}

} else {

m.invoke(object, objval);

}

}

}

list.add(object);

}

} catch (Exception e) {

e.printStackTrace();

} finally {

DBUtil.close(conn, ps, rs);

}

return list;

}
   // 根据属性名获取该属性的set方法的名字

public String getSetMethodName(String fieldName) {

return "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);

}

至此,我们就完成了对任意一条SQL语句的查询封装,尽管这个方法还有很多不如意的地方,比如:sql没有参数。但不管怎么说这个方法使用起来就很方便了,我们只需要给定sql语句以及要生成的类型即可得到一个有关一张表数据的List,一起来看main方法:

public static void main(String[] args) {

List list = obj.rows2beans("select * from emp", Emp.class);

System.out.println(list.size()) //数据为14条

}

好啦,今天的分享就到这里了!

这个封装的方法大家可以保存起来,

以后懒得写查询数据库的代码时,

ctrl+c和ctrl+v瞬间搞定。

不说了,我去喝可乐了!

原文地址:https://www.cnblogs.com/hehy0205/p/10773491.html

时间: 2024-07-31 23:00:55

反射技术菜鸟从入门到精通(一)的相关文章

反射技术菜鸟从入门到精通(二)

前言 大家好,我是老王,今天继续和大家分享反射技术. 上次我们使用反射封装了对数据库的查询,现在我们继续研究反射的用途——探究Spring的IoC容器. 首先,我们得了解什么是IoC? 控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度.其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup).通过控制反转,对象在被创建的

跨平台开发技术-PhoneGap从入门到精通视频教程

跨平台开发技术-PhoneGap从入门到精通视频教程下载   密码: nir2      联系QQ:1026270010 一.课程背景 在近几年的IT行业发展中,最热.最快的无疑是移动互联网,它是继互联网之后的又一次信息技术革命.移动互联网巨大的市场潜力创造了无限商机,人们纷纷加入其中,各种与之相应的新技术.新应用层出不穷. 移动应用离不开移动终端设备,如PC.手机.平板电脑等.目前,移动应用的开发平台大体分为三个方向,一个是收益稳定的iOS系统,另一个是如日中天的Android系统,还有一个是

2018最新区块链技术,从入门到精通视频教程(比特币基础技术)

2017最新区块链技术,从入门到精通视频教程(视频+源码+工具) 最新整理区块链技术视频包含开发工具,源码,视频教程,从小白到大神,分享给大家学习. 区块链最早是比特币的基础技术,目前世界各地均在研究,可广泛应用于金融等各领域 区块链的基本原理 交易(Transaction):一次操作,导致账本状态的一次改变,如添加一条记录: 区块(Block):记录一段时间内发生的交易和状态结果,是对当前账本状态的一次共识: 链(Chain):由一个个区块按照发生顺序串联而成,是整个状态变化的日志记录. 如果

小梅科普:跨平台开发技术-PhoneGap从入门到精通

一.课程背景 在近几年的IT行业发展中,最热.最快的无疑是移动互联网,它是继互联网之后的又一次信息技术革命.移动互联网巨大的市场潜力创造了无限商机,人们纷纷加入其中,各种与之相应的新技术.新应用层出不穷. 移动应用离不开移动终端设备,如PC.手机.平板电脑等.目前,移动应用的开发平台大体分为三个方向,一个是收益稳定的iOS系统,另一个是如日中天的Android系统,还有一个是蓄势待发的Windows Phone系统.丰富的开发平台增加了开发人员选择的灵活性,但同时也带了一个问题,就是应用平台的兼

跨平台技术:JQueryMobile从入门到精通配项目实战

移动开发现在很热门的,尤其是JQueryMobile方向,很多人想要一个系统性的学习,但是网络里对于这方面的资料并不全面. 我推荐一套系统性学习jquerymobile的课程,并且配套有几个企业实战的项目. 咨询QQ:1609173918 课程大纲 一.理论讲解部分: 第1章:掀起你的盖头来--初识jQuery Mobile 第2章:第一次亲密接触--jQuery Mobile页面结构 第3章:从头到尾的打扮--工具栏与格式化内容 第4章:戒指项链一个不能少--页面常用组件 第5章:满衣柜的漂亮

PhoneGap从入门到精通视频教程

跨平台开发技术-PhoneGap从入门到精通视频教程 课程讲师:厉风行 课程分类:手机开发 适合人群:中级 课时数量:76课时 用到技术:PhoneGap.罗盘.运动传感器.地理位置.通信机制及部署和调试 涉及项目:北风动听音乐播放器,北风微博客户端 咨询QQ:1609173918 链接:http://pan.baidu.com/s/1o662bHK密码:7o7i PhoneGap是一个开源的开发框架,它允许用户通过使用类似jQuery Mobile这样的Web技术来开发跨平台的本地应用程序.这

区块链技术从入门到精通

详情请交流  QQ  709639943 01.区块链技术从入门到精通 02.2017年新生大学区块链视频教程 03.Node.js入门到企业Web开发中的应用 04.精通高级RxJava 2响应式编程思想 05.Java秒杀系统方案优化 高性能高并发实战 06.Java深入微服务原理改造房产销售平台 07.快速上手Linux 玩转典型应用 08.快速上手Ionic3 多平台开发企业级问答社区 09.Java Spring Security开发安全的REST服务 10.深入Java虚拟机(JVM

内存泄露从入门到精通三部曲之排查方法篇

内存泄露从入门到精通三部曲之排查方法篇 最原始的内存泄露测试 重复多次操作关键的可疑的路径,从内存监控工具中观察内存曲线,是否存在不断上升的趋势且不会在程序返回时明显回落.这种方式可以发现最基本,也是最明显的内存泄露问题,对用户价值最大,操作难度小,性价比极高. MAT内存分析工具 2.1 MAT分析heap的总内存占用大小来初步判断是否存在泄露 在Devices 中,点击要监控的程序. 点击Devices视图界面中最上方一排图标中的“Update Heap” 点击Heap视图 点击Heap视图

(升级版)Spark从入门到精通(Scala编程、案例实战、高级特性、Spark内核源码剖析、Hadoop高端)

本课程主要讲解目前大数据领域最热门.最火爆.最有前景的技术——Spark.在本课程中,会从浅入深,基于大量案例实战,深度剖析和讲解Spark,并且会包含完全从企业真实复杂业务需求中抽取出的案例实战.课程会涵盖Scala编程详解.Spark核心编程.Spark SQL和Spark Streaming.Spark内核以及源码剖析.性能调优.企业级案例实战等部分.完全从零起步,让学员可以一站式精通Spark企业级大数据开发,提升自己的职场竞争力,实现更好的升职或者跳槽,或者从j2ee等传统软件开发工程