JAVA反射方法全解

java开发过程总是会利用到java本身的反射机制,由于用的比较多,但是之前没有思考过反射机制每个方法的意义和实现原理,所以趁工作之余总结一下经常遇到的一些反射机制的方法的原理。
反射是Java的特征之一,是一种间接操作目标对象的机制,核心是JVM在运行的时候才动态加载类,并且对于任意一个类,都能够知道这个类的所有属性和方法,调用方法/访问属性,不需要提前在编译期知道运行的对象是谁,他允许运行中的Java程序获取类的信息,并且可以操作类或对象内部属性。程序中对象的类型一般都是在编译期就确定下来的,而当我们的程序在运行时,可能需要动态的加载一些类,这些类因为之前用不到,所以没有加载到jvm,这时,使用Java反射机制可以在运行期动态的创建对象并调用其属性,它是在运行时根据需要才加载。
在这里分享一篇其他博主总结非常好的文章:
Java基础篇:反射机制详解https://blog.csdn.net/a745233700/article/details/82893076

1. Class.forName("");

返回与给定的字符串名称相关联类或接口的Class对象。
Class.forName是一个静态方法,同样可以用来加载类。该方法有两种形式:Class.forName(String name, boolean initialize, ClassLoader loader):
这种形式的参数,name表示的是类的全名;
Class.forName(String className):
initialize表示是否初始化类;loader表示加载时使用的类加载器。第二种形式则相当于设置了参数 initialize的值为 true,loader的值为当前类的类加载器。
如下所示,java类型的属性名称叫name,可以通过forName的方法获取到这个类的实例,从而获取到类里面的属性。

package app.system.model;

import java.util.Date;

/**
 * TSysPerson entity.
 * 
 * @author MyEclipse Persistence Tools
 */

public class TSysPerson implements java.io.Serializable {

	// Fields

	private String fsid;
	private Integer frysnum;//排序值 序号
	private String fryzh;//登陆账号
	private String frymm;//登陆密码
	private String frymc;//姓名
	private String fryxb;//性别
	private String frysfz;//身份证
	private String fryzp;//照片
	private String frydh;//固话
	private String frysjhm;//手机号码
	private String frybm;//选择部门
	//private String fssbm;//所属部门(实际);暂时去掉:2017-10-10 李伟杰
	private String fssbmmc;//所属部门名称(实际)
	private String frydz;//地址
	private String fryhyzk;//婚姻状况
	private String frymz;//民族
	private String fryxl;//最高学历
	private String frybyyx;//毕业院校
	private Date frycsrq;//出生日期
	private Date frydjsj;//登记时间
	private Date fryjlsj;//记录时间
	private String fryzt;//状态 正常,离职
	private String fryqm;//电子签名地址
	private Integer fmoney;//剩余金额
	private String ffuncid;//页面功能权限
	private String frgangwei;//岗位
	private String fqz;//群组
	private String frybmmc;
	// Constructors
	private Integer fryxh;//人员序号

	
	
	public Integer getFryxh() {
		return fryxh;
	}

	public void setFryxh(Integer fryxh) {
		this.fryxh = fryxh;
	}

	public String getFfuncid() {
		return ffuncid;
	}

	public String getFqz() {
		return fqz;
	}

	public void setFqz(String fqz) {
		this.fqz = fqz;
	}

	public String getFssbmmc() {
		return fssbmmc;
	}

	public void setFssbmmc(String fssbmmc) {
		this.fssbmmc = fssbmmc;
	}

	

	public void setFfuncid(String ffuncid) {
		this.ffuncid = ffuncid;
	}

	/** default constructor */
	public TSysPerson() {
	}

	/** minimal constructor */
	public TSysPerson(String fsid) {
		this.fsid = fsid;
	}

	/** full constructor */
	public TSysPerson(String fsid, String fryzh, String frymm, String frymc,
			String fryxb, String frysfz, String fryzp, String frydh,
			String frysjhm, String frybm, String frydz, String fryhyzk,
			String frymz, String fryxl, String frybyyx, Date frycsrq,
			Date frydjsj, Date fryjlsj, String fryzt, String fryqm,String frgangwei) {
		this.fsid = fsid;
		this.fryzh = fryzh;
		this.frymm = frymm;
		this.frymc = frymc;
		this.fryxb = fryxb;
		this.frysfz = frysfz;
		this.fryzp = fryzp;
		this.frydh = frydh;
		this.frysjhm = frysjhm;
		this.frybm = frybm;
		this.frydz = frydz;
		this.fryhyzk = fryhyzk;
		this.frymz = frymz;
		this.fryxl = fryxl;
		this.frybyyx = frybyyx;
		this.frycsrq = frycsrq;
		this.frydjsj = frydjsj;
		this.fryjlsj = fryjlsj;
		this.fryzt = fryzt;
		this.fryqm = fryqm;
		this.frgangwei = frgangwei;
	}

	// Property accessors
	public String getFrybmmc() {
		return frybmmc;
	}

	public void setFrybmmc(String frybmmc) {
		this.frybmmc = frybmmc;
	}
	public String getFsid() {
		return this.fsid;
	}

	public void setFsid(String fsid) {
		this.fsid = fsid;
	}

	public String getFryzh() {
		return this.fryzh;
	}

	public void setFryzh(String fryzh) {
		this.fryzh = fryzh;
	}

	public String getFrymm() {
		return this.frymm;
	}

	public void setFrymm(String frymm) {
		this.frymm = frymm;
	}

	public String getFrymc() {
		return this.frymc;
	}

	public void setFrymc(String frymc) {
		this.frymc = frymc;
	}
	
	public String getFryxb() {
		return this.fryxb;
	}

	public void setFryxb(String fryxb) {
		this.fryxb = fryxb;
	}

	public String getFrysfz() {
		return this.frysfz;
	}

	public void setFrysfz(String frysfz) {
		this.frysfz = frysfz;
	}

	public String getFryzp() {
		return this.fryzp;
	}

	public void setFryzp(String fryzp) {
		this.fryzp = fryzp;
	}

	public String getFrydh() {
		return this.frydh;
	}

	public void setFrydh(String frydh) {
		this.frydh = frydh;
	}

	public String getFrysjhm() {
		return this.frysjhm;
	}

	public void setFrysjhm(String frysjhm) {
		this.frysjhm = frysjhm;
	}

	public String getFrybm() {
		return this.frybm;
	}

	public void setFrybm(String frybm) {
		this.frybm = frybm;
	}

	public String getFrydz() {
		return this.frydz;
	}

	public void setFrydz(String frydz) {
		this.frydz = frydz;
	}

	public String getFryhyzk() {
		return this.fryhyzk;
	}

	public void setFryhyzk(String fryhyzk) {
		this.fryhyzk = fryhyzk;
	}

	public String getFrymz() {
		return this.frymz;
	}

	public void setFrymz(String frymz) {
		this.frymz = frymz;
	}

	public String getFryxl() {
		return this.fryxl;
	}

	public void setFryxl(String fryxl) {
		this.fryxl = fryxl;
	}

	public String getFrybyyx() {
		return this.frybyyx;
	}

	public void setFrybyyx(String frybyyx) {
		this.frybyyx = frybyyx;
	}

	public Date getFrycsrq() {
		return this.frycsrq;
	}

	public void setFrycsrq(Date frycsrq) {
		this.frycsrq = frycsrq;
	}

	public Date getFrydjsj() {
		return this.frydjsj;
	}

	public void setFrydjsj(Date frydjsj) {
		this.frydjsj = frydjsj;
	}

	public Date getFryjlsj() {
		return this.fryjlsj;
	}

	public void setFryjlsj(Date fryjlsj) {
		this.fryjlsj = fryjlsj;
	}

	public String getFryzt() {
		return this.fryzt;
	}

	public void setFryzt(String fryzt) {
		this.fryzt = fryzt;
	}

	public String getFryqm() {
		return this.fryqm;
	}

	public void setFryqm(String fryqm) {
		this.fryqm = fryqm;
	}

	public Integer getFmoney() {
		return fmoney;
	}

	public void setFmoney(Integer fmoney) {
		this.fmoney = fmoney;
	}

	public String getFrgangwei() {
		return frgangwei;
	}

	public void setFrgangwei(String frgangwei) {
		this.frgangwei = frgangwei;
	}

	public Integer getFrysnum() {
		return frysnum;
	}

	public void setFrysnum(Integer frysnum) {
		this.frysnum = frysnum;
	}

	

}
Class classs = (Class<TSysPerson>)Class.forName("app.system.model.TSysPerson");
		        	Field[] declaredFields = classs.getDeclaredFields();
		        	for (Field field : declaredFields) {
						System.out.println("获取字段类型:"+field.getType().toString());
						System.out.println("获取字段属性:"+field.getName());
					}

得到此实体类的全部字段类型和字段属性

获取字段类型:class java.lang.String
获取字段属性:fsid
获取字段类型:class java.lang.Integer
获取字段属性:frysnum
获取字段类型:class java.lang.String
获取字段属性:fryzh
获取字段类型:class java.lang.String
获取字段属性:frymm
获取字段类型:class java.lang.String
获取字段属性:frymc
获取字段类型:class java.lang.String
获取字段属性:fryxb
获取字段类型:class java.lang.String
获取字段属性:frysfz
获取字段类型:class java.lang.String
获取字段属性:fryzp
获取字段类型:class java.lang.String
获取字段属性:frydh
获取字段类型:class java.lang.String
获取字段属性:frysjhm
获取字段类型:class java.lang.String
获取字段属性:frybm
获取字段类型:class java.lang.String
获取字段属性:fssbmmc
获取字段类型:class java.lang.String
获取字段属性:frydz
获取字段类型:class java.lang.String
获取字段属性:fryhyzk
获取字段类型:class java.lang.String
获取字段属性:frymz
获取字段类型:class java.lang.String
获取字段属性:fryxl
获取字段类型:class java.lang.String
获取字段属性:frybyyx
获取字段类型:class java.util.Date
获取字段属性:frycsrq
获取字段类型:class java.util.Date
获取字段属性:frydjsj
获取字段类型:class java.util.Date
获取字段属性:fryjlsj
获取字段类型:class java.lang.String
获取字段属性:fryzt
获取字段类型:class java.lang.String
获取字段属性:fryqm
获取字段类型:class java.lang.Integer
获取字段属性:fmoney
获取字段类型:class java.lang.String
获取字段属性:ffuncid
获取字段类型:class java.lang.String
获取字段属性:frgangwei
获取字段类型:class java.lang.String
获取字段属性:fqz
获取字段类型:class java.lang.String
获取字段属性:frybmmc
获取字段类型:class java.lang.Integer
获取字段属性:fryxh

2. getMethod("");

getMethod方法要注意的地方:

类对象.getMethod(mName,HttpServletRequest.class,HttpServletResponse.class);
第一个参数是mName“方法名称”
第二个参数是“方法参数的类对象”//这个就是为什么他是.class的原因,为什么参数是类对象?因为这个是Java规定的
示例:

	List<TSysSet> stan = (List<TSysSet>) dao.findByProperty4(TSysSet.class, "fsid", "8Y8U2E9Z");//这个方法是查找系统配置表
			String[] strArray = null;  
			for (TSysSet tSysSet : stan) {//循环遍历配置表中的配置
				String ziduan = tSysSet.getFdqz();
		        strArray = ziduan.split(",");//配置的字段
		        for (int k = 0; k < strArray.length; k++) {
		        	String str =strArray[k].replaceFirst(ziduan.substring(0, 1),ziduan.substring(0, 1).toUpperCase());//设置配置字段的首字母大写
		        	Class<LeeChkBasic> clazz=(Class<LeeChkBasic>) Class.forName("app.office.model.LeeChkBasic");//获取实体类
		        	Method method = clazz.getMethod("set"+str,String.class);//获取方法,参数为拼接的字符串和字符串的类对象
		        	method.invoke(bean,"");

		        }
				
			}

3. invoke("","");

invoke(调用)就是调用Method类代表的方法。可以实现动态调用,例如可以动态的传人参数,可以把方法参数化。
可以把方法参数化invoke(class, method),比如Test类里有一系列名字相似的方法setValue1、setValue2等等,可以把方法名存进数组v[],然后循环里invoke(test,v[i]),就顺序调用了全部setValue。

此外,invoke()对带有指定参数的指定对象调用,个别参数被自动解包,与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。如下

public Object invoke(Object obj,Object… args)

throws IllegalAccessException,

IllegalArgumentException,

InvocationTargetException

如果底层方法是静态的,那么可以忽略指定的 obj 参数。该参数可以为 null。

如果底层方法所需的形参数为 0,则所提供的 args 数组长度可以为 0 或 null。

如果底层方法是实例方法,则使用动态方法查找来调用它,这一点记录在 Java Language Specification, Second Edition 的第 15.12.4.4 节中;在发生基于目标对象的运行时类型的重写时更应该这样做。

如果底层方法是静态的,并且尚未初始化声明此方法的类,则会将其初始化。

如果方法正常完成,则将该方法返回的值返回给调用者;如果该值为基本类型,则首先适当地将其包装在对象中。但是,如果该值的类型为一组基本类型,则数组元素不 被包装在对象中;换句话说,将返回基本类型的数组。如果底层方法返回类型为 void,则该调用返回 null。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值