反射机制的使用(个人学习笔记)

反射机制

在Java中,Class类与java.lang.reflect类库一起对反射技术进行了全力的支持。在反射包中,我们常用的类主要有Constructor类表示的是Class 对象所表示的类的构造方法,利用它可以在运行时动态创建对象、Field表示Class对象所表示的类的成员变量,通过它可以在运行时动态修改成员变量的属性值(包含private)、Method表示Class对象所表示的类的成员方法,通过它可以动态调用对象的方法(包含private)

所有与反射相关的类大部分都在java.reflect包下

反射的作用:
反射一般用于封装框架、工具类、IDE工具;因为反射这门技术可以使代码变得非常灵活!

反射的概念:
只需要给一个类名,就可以通过反射机制得到里面的所有成员(属性、方法、构造器)

反射的入口(Class类)

任何类中包含这些属性:

字段、方法、构造器

!!所以!!
java中把这些属性规划到"java.lang.Class类"中充当其属性
java中所有的类都属于Class类对象

如何获取每一个类的Class类对象(三种方式):

1>Class.forName(“完整类名”)
2>类名.class
3>对象名.getClass()

获取class对象中的信息

字段(java.lang.reflect.Field)
方法(java.lang.reflect.Method)
构造器(java.lang.reflect.Constructor)

获取所有的字段

Field[] getFields(); //public的,包含继承的
Field[] getDeclaredFields(); //本类所有的,不包含继承的

获取所有的方法

Method[] getMethods(); //public的,包含继承的
Method[] getDeclaredMethods();

获取所有的构造器

Constructor[] getConstructors();
Constructor[] getDeclaredConstructors();

Field、Method、Constructor的常用方法

Field字段
获取字段的名称
获取字段的类型

Method方法
获取方法名
获取方法的返回类型
获取方法的参数列表

Constructor构造器
获取构造器的参数列表

应用:

给Field赋值
field对象.set(该字段所属实例,要赋的值);

调用Method
method对象.invoke(该方法所属实例,[参数列表的值1,参数列表的值1…]);
该invoke方法的返回值代表的就是调用方法所产生的返回值

调用Constructor

案例

定义一个方法,能够将map集合的映射给任意实体类对象的<属性-值>。

subjectInfo.java

public class SubjectInfo {
	
	private int subject_id;
	private String subject_name;
	
	
	public int getSubject_id() {
		return subject_id;
	}
	public void setSubject_id(int subject_id) {
		this.subject_id = subject_id;
	}
	public String getSubject_name() {
		return subject_name;
	}
	public void setSubject_name(String subject_name) {
		this.subject_name = subject_name;
	}
	
	
	@Override
	public String toString() {
		return "SubjectInfo [subject_id=" + subject_id + ", subject_name="
				+ subject_name + "]";
	}
	
}

StudentInfo.java

public class StudentInfo {
	private int stu_id;
	private String stu_no;
	private String stu_name;
	private int stu_age;
	
	public int getStu_id() {
		return stu_id;
	}
	public void setStu_id(int stu_id) {
		this.stu_id = stu_id;
	}
	public String getStu_no() {
		return stu_no;
	}
	public void setStu_no(String stu_no) {
		this.stu_no = stu_no;
	}
	public String getStu_name() {
		return stu_name;
	}
	public void setStu_name(String stu_name) {
		this.stu_name = stu_name;
	}
	public int getStu_age() {
		return stu_age;
	}
	public void setStu_age(int stu_age) {
		this.stu_age = stu_age;
	}
	
	@Override
	public String toString() {
		return "StudentInfo [stu_id=" + stu_id + ", stu_no=" + stu_no
				+ ", stu_name=" + stu_name + ", stu_age=" + stu_age + "]";
	}
	
	
	
}

ClassInfo

public class ClassInfo {

	private int class_id;
	private String class_name;
	
	
	public int getClass_id() {
		return class_id;
	}
	public void setClass_id(int class_id) {
		this.class_id = class_id;
	}
	public String getClass_name() {
		return class_name;
	}
	public void setClass_name(String class_name) {
		this.class_name = class_name;
	}
	
	@Override
	public String toString() {
		return "ClassInfo [class_id=" + class_id + ", class_name=" + class_name
				+ "]";
	}
	
	
}

Test.java

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Test {

	public static void main(String[] args) {
		
		Map<String, Object> map = new HashMap<String, Object>();

		// ClassInfo实体类的属性【班级类】
		map.put("class_id", 1);
		map.put("class_name", "大数据2班");

		// SubjectInfo实体类的属性【科目类】
		map.put("subject_id", 1);
		map.put("subject_name", "web前端");

		// StudentInfo实体类的属性【学生类】
		map.put("stu_id", 1);
		map.put("stu_no", "1001");
		map.put("stu_name", "张三");
		map.put("stu_age", 18);

		// 定义一个mapCastToEntity()方法,能够将map集合映射给任意实体类对象
		 ClassInfo classInfo = (ClassInfo) mapCastToEntity(map, ClassInfo.class);
		 SubjectInfo subjectInfo = (SubjectInfo) mapCastToEntity(map,SubjectInfo.class);
		 StudentInfo studentInfo = (StudentInfo) mapCastToEntity(map,StudentInfo.class);
		 System.out.println(classInfo);
		 System.out.println(subjectInfo);
		 System.out.println(studentInfo);
	}
	
	/**
	 * 将集合中的数据映射到实体类中
	 * 
	 * @param list
	 *            一个list集合对象
	 * @param clazz
	 *            类型
	 * @return
	 */
	public static Object mapCastToEntity(Map<String, Object> map, Class clazz) {
		Object obj = null;
		try {
			obj = clazz.newInstance();
			Field[] fieldArray = clazz.getDeclaredFields();
			Set<String> set = map.keySet();
			for (String key : set) {
				for (Field field : fieldArray) {
					if (field.getName().equals(key)) {
                        // 值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查
						field.setAccessible(true);
						field.set(obj, map.get(key));
					}
				}
			}
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return obj;
	}
}

相关知识

setAccessible

如果 accessible 标志被设置为true,那么反射对象在使用的时候,不会去检查Java语言权限控制(private之类的);

如果设置为false,反射对象在使用的时候,会检查Java语言权限控制。

Field类及其使用

方法返回值方法名称方法说明
FieldgetDeclaredField(String name)获取指定name名称的(包含private修饰的)字段,不包括继承的字段
Field[]getDeclaredField()获取Class对象所表示的类或接口的所有(包含private修饰的)字段,不包括继承的字段
FieldgetField(String name)获取指定name名称、具有public修饰的字段,包含继承字段
Field[]getField()获取修饰符为public的字段,包含继承字段
方法返回值方法名称方法说明
voidset(Object obj, Object value)将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
Objectget(Object obj)返回指定对象上此 Field 表示的字段的值
Class<?>getType()返回一个 Class 对象,它标识了此Field 对象所表示字段的声明类型。
booleanisEnumConstant()如果此字段表示枚举类型的元素则返回 true;否则返回 false
StringtoGenericString()返回一个描述此 Field(包括其一般类型)的字符串
StringgetName()返回此 Field 对象表示的字段的名称
Class<?>getDeclaringClass()返回表示类或接口的 Class 对象,该类或接口声明由此 Field 对象表示的字段
voidsetAccessible(boolean flag)将此对象的 accessible 标志设置为指示的布尔值,即设置其可访问性

Method类及其使用

方法返回值方法名称方法说明
MethodgetDeclaredMethod(String name, Class<?>… parameterTypes)返回一个指定参数的Method对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
Method[]getDeclaredMethod()返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
MethodgetMethod(String name, Class<?>… parameterTypes)返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
Method[]getMethods()返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
方法返回值方法名称方法说明
Objectinvoke(Object obj, Object… args)对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。
Class<?>getReturnType()返回一个 Class 对象,该对象描述了此 Method 对象所表示的方法的正式返回类型,即方法的返回类型
TypegetGenericReturnType()返回表示由此 Method 对象所表示方法的正式返回类型的 Type 对象,也是方法的返回类型。
Class<?>[]getParameterTypes()按照声明顺序返回 Class 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型。即返回方法的参数类型组成的数组
Type[]getGenericParameterTypes()按照声明顺序返回 Type 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型的,也是返回方法的参数类型
StringgetName()以 String 形式返回此 Method 对象表示的方法名称,即返回方法的名称
booleanisVarArgs()判断方法是否带可变参数,如果将此方法声明为带有可变数量的参数,则返回 true;否则,返回 false。
StringtoGenericString()返回描述此 Method 的字符串,包括类型参数。

[]: https://pdai.tech/md/java/basic/java-basic-x-reflection.html “部分知识来自Java全站知识体系”

如有侵权请联系我删除!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Micek

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值