Java关于反射
反射的概念:JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
通俗一些 就是说Java通过反射能够创建类的对象,使用类中的方法以及获取类中的属性信息。
想写这篇博客缘由是最近做项目时,发现前后台交互,前端(vue)传过来的空对象,后台(springboot)获取后使用 obj == null 是无法判断出来的,其实obj里面的属性对应的属性值都为null, 当对象中嵌套对象再被调用时会抛出空指针异常!!!
eg:
Vue前端发送请求代码: // 下一步 按钮(转到基本计划页面)
nextStep: function () {
var inputForm = {
'proposalStk': {},
SpringBoot 后台部分代码:
@RequestMapping(value = "/ProposalFlowBasicPlan", method = RequestMethod.POST)
public DataResult ProposalFlowBasicPlan(HttpServletRequest request,
@RequestBody(required = false) ProposalFlowBasicPlanVO proposalFlowBasicPlanVO) {
ProposalStk proposalStk = proposalFlowBasicPlanVO.getProposalStk();//从入参中获取 proposalStk 对象,这里获取到的 proposalStk 对象是非 NULL 的
if(proposalStk != null){
//if(proposalStk.getStkInsured() != null){ //注释掉这句话时,下面会抛出NullPointerException
if (onlProposalForm.getOnlProposalFormIsd().getIsdname() != null) {
proposalStk.getStkInsured().setInsuredName(onlProposalForm.getOnlProposalFormIsd().getIsdname());
//抛空指针异常的原因:proposalStk不为null,但是proposalStk.getStkInsured()为null,再去调用其他方法就会有异常。 StkInsured为对象,不是简单属性。{对象中嵌套对象}
}
}
}
反射分为: 类反射、方法反射、属性反射。
类反射: 通过反射创建类对象。
方法反射:通过反射调用类中的方法信息。
属性反射:通过反射获取类中的属性信息。
一、类反射
1、得到类Class对象。
方式一: Class c1 = Student.class; //已知类名时使用此方法
方式二: Class c2 = stu.getClass();//已知该类的对象时使用
方式三: Class c3 = Class.forName("com.demo.Student");//已知类的全路径名时使用此方法,会有一个ClassNotFoundException异常
2、通过newInstance()方法创建对象的实例。
ps: 注意调用 newInstance()方法创建对象时需要保证 Student类中有个无参数的构造方法!!!
Class c=Class.forName("com.demo.Student");//这个为第一步中的方式三得到Class对象
Student student = (Student)c.newInstance();//创建对象
二、方法反射
1、获取类中的所有方法
public static void method_1() throws Exception {
Class clazz = Class.forName("com.demo.Student");
//获取的是该类中所有的公有方法,包含继承和实现的方法,不包含private私有方法。
Method[] methods = clazz.getMethods();
//获取的是该类中的所有方法,包含私有方法,但不包含继承的方法。
methods = clazz.getDeclaredMethods();
for(Method method : methods) {
System.out.println(method);
}
}
2、获取类中指定方法名的方法,并且运行该方法
public static void method_2() throws Exception {
Class clazz = Class.forName("com.demo.Student");
//获取指定名称的方法; 参数: 方法名 show, 方法中的入参类型 int.class ,String.class
Method method = clazz.getMethod("show", int.class,String.class);
Object obj = clazz.newInstance();
method.invoke(obj, 18,"zhagnsan");//执行该方法; 参数: obj为当前类对象, 后面为运行该方法需要的参数值
}
3、获取私有方法
public static void method_3() throws Exception {
Class clazz = Class.forName("com.makaruina.reflect.Person");
//想要获取私有方法必须用getDeclearMethod();
Method method = clazz.getDeclaredMethod("show", null); //当该私有方法时没有参数时使用null.
// 私有方法不能直接访问,因为权限不够。
method.setAccessible(true);//一般很少用,因为私有就是隐藏起来,所以尽量不要访问。
}
三、属性反射
public void isObjectFieldEmpty() throws Exception {
Class clazz=Class.forName("com.demo.Student"); //得到类Class对象
Student student = clazz.newInstance();
Field[] fields = clazz.getDeclaredFields(); //得到所有属性集合
for(Field field : fields ){//遍历属性
field.setAccessible(true); //设置属性是可以访问的(私有的也可以)
System.err.println(field.getName()+field.get(student)); // field.getName()得到属性名,field.get(student)得到属性名对应的属性值
}
}
应用示例:
/**
* 想用于对象嵌套对象时的非null判断,避免出现 空指针异常
* 这里需要注意 序列化 以及带有默认值的字段 布尔类型 boolean 这两种类型是有值的
* @throws Exception
*/
@Test
public void isObjectFieldEmpty() throws Exception {
CheckboxVO checkVO = new CheckboxVO(); //创建被判断的对象
checkVO.setCode("123");
Class clazz=checkVO.getClass(); //得到类Class对象
System.err.println("CheckVO的Class类对象:"+clazz);
Field[] fs=clazz.getDeclaredFields(); //得到所有属性集合
System.err.println("Fields[]::"+fs);
List<String> list=new ArrayList<String>();
for(Field field:fs){ //遍历属性
field.setAccessible(true); //设置属性是可以访问的(私有的也可以)
System.err.println("Field::"+field);
System.err.println("field.get(checkVO):"+field.get(checkVO));
if(field.get(checkVO)==null||field.get(checkVO)==""){
String name=(String)field.getName();
list.add(name);
}
}
System.err.println("list:"+list);
}
CheckVO.java类
package com.chinalife.proposal.web.build.basicplanVO;
import java.io.Serializable;
public class CheckboxVO implements Serializable{
private static final long serialVersionUID = 1L;
private String name;
private boolean check;
private String code;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isCheck() {
return check;
}
public void setCheck(boolean check) {
this.check = check;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
输出结果:

Java关于反射的更多相关文章
- JAVA的反射理解
1----------------------------反射的概念----------------------------------------------- JAVA的反射机制是在运行状态中,对 ...
- java的反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制. ...
- iOS运行时编程(Runtime Programming)和Java的反射机制对比
运行时进行编程,类似Java的反射.运行时编程和Java反射的对比如下: 1.相同点 都可以实现的功能:获取类信息.属性设置获取.类的动态加载(NSClassFromString(@“clas ...
- Java 类反射机制分析
Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...
- java的反射机制
一.java的反射机制浅谈 最近研究java研究得很给力,主要以看博文为学习方式.以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出.受到各位指教之处,如若让小生好好感动, ...
- Java:反射
初识Java反射机制: 从上面的描述可以看出Java的反射机制使得Java语言可以在运行时去认识在编译时并不了解的类/对象的信息,并且能够调用相应的方法或修改属性的值.Java反射机制的核心就是允许在 ...
- Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别
一.Java的反射机制 每个Java程序执行前都必须经过编译.加载.连接.和初始化这几个阶段,后三个阶段如下图: 其中
- java笔记--反射进阶之总结与详解
一.反射进阶之动态设置类的私有域 "封装"是Java的三大特性之一,为了能更好保证其封装性,我们往往需要将域设置成私有的, 然后通过提供相对应的set和get方法来操作这个域.但是 ...
- java笔记--反射机制之基础总结与详解
一.反射之实例化Class类的5种方式: java的数据类型可以分为两类,即引用类型和原始类型(即基本数据类型). 对于每种类型的对象,java虚拟机会实例化不可变的java.lang.Class对象 ...
- Java中反射的三种常用方式
Java中反射的三种常用方式 package com.xiaohao.test; public class Test{ public static void main(String[] args) t ...
随机推荐
- 使用Qpaint在图片上写文字
开发过程中需要实现在图片上叠加文字,可以采用Qpaint在图片上写文字,然后将图片显示在上面.再将Qlabel加到Qwidget中.效果如下 //创建对象,加载图片 QPixmap pix; pix. ...
- Codeforces 1079 E - The Unbearable Lightness of Weights
E - The Unbearable Lightness of Weights 思路: 分组背包dp 每组最多只能选一个 一些优化可以快很多 代码: #pragma GCC optimize(2) # ...
- Codeforces 961E - Tufurama
961E - Tufurama 思路: 线段树或者分块 遍历 1 - n - 1,求 区间[i + 1, min(a[i], n)]大于等于 i 的个数,累加起来 线段树: #include<b ...
- jenkins之从0到1利用Git和Ant插件打war包并自动部署到tomcat(第一话):初次启动jenkins,输入给定密码后登录失败问题解决
Jenkins是一个持续集成平台,它能够从git等源码管理服务器拉取代码.打包并发布到tomcat等中间件,只要配置好相关插件,就可以做到项目的自动化构建.部署,不论是对开发来说监控代码质量,还是对测 ...
- 自动化部署之jenkins及简介
一.什么是持续集成? (1)Continuous integration(CI) 持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员至少集成一次,也就意味着每天可能会发生多次集 ...
- BroadcastReceiver(广播)的静态注册和动态注册 --Android开发
BroadcastReceiver是安卓四大组件之一,本例通过代码的方式演示静态注册和动态注册. 1.静态注册 静态注册只需要AndroidManifest.xml中进行配置: AndroidMani ...
- 【错误】IntelliJ IDEA使用Gradle编译报错
一.异常如下: No signature of method: org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.Def ...
- canvas学习之柱状图
项目地址:http://pan.baidu.com/s/1nvhWrwP 因为最近项目中使用到了图表,而且个人一直希望研究canvas,所以最近几天花时间对canvas好好研究了一下,并写了一个dem ...
- apicloud 环信总结
点击链接先查看一下apicloud 环信的文档 https://docs.apicloud.com/Client-API/Open-SDK/easeChat 文档中写了很多,但官方给的文档还是有问题, ...
- 《剑指offer》总结一
目录 1.二维数组中的查找(223ms) 2.替换空格(24ms) 3.从尾到头打印链表(22ms) 4.重建二叉树(37ms) 5.用两个栈实现队列 1.二维数组中的查找(223ms) 题目描述: ...