文章目录

  • 反射的定义
  • 什么是“正射”
  • 反射的作用

反射的定义

计算机科学中的反射(reflection) 指计算机程序在运行时(runtime) 可以访问、检测和修改它本身状态或行为的一种能力。通俗说,反射就是程序在运行的时候能够“观察”并且修改自己的行为,是程序对自身的反思、自检、修改。英文 reflection 本身就有反思的意思。而反思一词听起来让程序有了生命力,也说明了反射只有在程序运行时才能起作用,因为程序代码只有在CPU上“跑”起来才有“生命力”。既然有反射那有没有正射呢?

什么是“正射”

在Java程序中,在没有用到反射相关的类的时候,我们都是在做正射。

class Human {String name;int age;String nation;Human(String name,int age,String nation) {this.name=name;this.age=age;this.nation=nation;}void changeName(String name){this.name=name;}
}public class Main {public static void main(String[] args){Human human=new Human("张静文",22,"中国");human.changeName("张文");}
}

在上面Main类的main方法中,我之所以可以写human.changeName(“张文”) 是因为Human类也是我自己写的,我清楚的知道,human作为Human的实例对象,可以调用changeName方法,如果我手抖写了调用changeNamee方法,我也会立即改回来,因为我知道Human里没有这个方法。假如我不知道Human里有没有一个改名字的方法,即Human类对我来说是不透明的第三方类,我尝试性的在程序中调用了一个newName方法,保存、编译。这时候编译器会通知我,这样写程序是不对的,Human里没有一个叫newName的方法,编译失败。

不管是我们手动纠错还是编译器纠错,对程序本身来说都是外部对自身的修改,由外部“思考”程序究竟能否调用changeName这个方法。而反射做的事就是将这种“思考”交给程序自身,由程序在运行时确定Human中有没有一个叫changeName的方法,进而去调用它。

反射的作用

从反射的定义中我们可以了解到反射的作用,即在运行时访问、修改对象的状态和行为,可以给程序带来极大的灵活性。

使用Java注解配合反射可以开发出各种工具、框架。例如,用自定义注解 @FieldAnnotation 实现为属性赋值。

定义注解 @FieldAnnotation:

package com.houch.annotation;import java.lang.annotation.*;@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldAnnotation {String value() default "";
}

编写解析类。BeanFactory中的createBean方法通过反射拿到注解 @FieldAnnotation的值并赋给对象。

package com.houch.annotation;import java.lang.reflect.Field;public class BeanFactory {public static <T> T createBean(Class<T> clazz) {T o = null;try {o = clazz.newInstance();} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}Field[] declaredFields = clazz.getDeclaredFields();for (Field declaredField : declaredFields) {if (declaredField.isAnnotationPresent(FieldAnnotation.class)) {FieldAnnotation fieldAnnotation = declaredField.getAnnotation(FieldAnnotation.class);if (!declaredField.isAccessible())declaredField.setAccessible(true);try {if (declaredField.getType().getSimpleName().equals("String"))declaredField.set(o, fieldAnnotation.value());else if (declaredField.getType().getSimpleName().equals("byte"))declaredField.set(o, Byte.parseByte(fieldAnnotation.value()));else if (declaredField.getType().getSimpleName().equals("short"))declaredField.set(o, Short.parseShort(fieldAnnotation.value()));else if (declaredField.getType().getSimpleName().equals("int"))declaredField.set(o, Integer.parseInt(fieldAnnotation.value()));else if (declaredField.getType().getSimpleName().equals("long"))declaredField.set(o, Long.parseLong(fieldAnnotation.value()));else if (declaredField.getType().getSimpleName().equals("float"))declaredField.set(o, Float.parseFloat(fieldAnnotation.value()));else if (declaredField.getType().getSimpleName().equals("double"))declaredField.set(o, Double.parseDouble(fieldAnnotation.value()));else if (declaredField.getType().getSimpleName().equals("long"))declaredField.set(o, Long.parseLong(fieldAnnotation.value()));else if (declaredField.getType().getSimpleName().equals("boolean"))declaredField.set(o, Boolean.parseBoolean(fieldAnnotation.value()));elsethrow new RuntimeException(declaredField.getName() + " of " + clazz.getName() + " is not a value field");} catch (IllegalAccessException e) {throw new RuntimeException(e);}}}return o;}
}

实体类:

package com.houch;import com.houch.annotation.FieldAnnotation;public class Teacher {@FieldAnnotation("12138")private int id;@FieldAnnotation("Zhang")private String name;@FieldAnnotation("24")private int age;@FieldAnnotation("false")private boolean isProfessor;@FieldAnnotation("M")private String  sex;@FieldAnnotation("CQU")private String school;public int getId() {return id;}public String getName() {return name;}public int getAge() {return age;}public boolean isProfessor() {return isProfessor;}public String getSex() {return sex;}public String getSchool() {return school;}public void setId(int id) {this.id = id;}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}public void setProfessor(boolean professor) {isProfessor = professor;}public void setSex(String sex) {this.sex = sex;}public void setSchool(String school) {this.school = school;}@Overridepublic String toString() {return "Teacher{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", isProfessor=" + isProfessor +", sex=" + sex +", school='" + school + '\'' +'}';}
}

测试类

package com.houch;import com.houch.annotation.BeanFactory;public class Main {public static void main(String[] args) {Teacher teacher = BeanFactory.createBean(Teacher.class);System.out.println(teacher);}
}

Java中的反射(Reflection)为什么叫“反射”?什么是“正射”?如何自定义注解并解析?相关推荐

  1. pandas dataframe中的列进行重新排序、倒排、正排、自定义排序详解及实践

    pandas dataframe中的列进行重新排序,pandas dataframe列重排.倒排.正排.自定义排序详解及实践 实施数据构建: import pandas as pd import nu ...

  2. Java中布尔值的定义_使用简单的布尔值作为自定义验证器

    我正在Angular 4中尝试表单验证,我对实现自定义验证器有点困惑 . 这是我的表格组声明: this.signupForm = fb.group({ 'username': [null, Vali ...

  3. java反射用法示例_Java反射示例教程

    java反射用法示例 Java Reflection provides ability to inspect and modify the runtime behavior of applicatio ...

  4. 使用Java反射(Reflect)、自定义注解(Customer Annotation)生成简单SQL语句

    使用Java反射(Reflect).自定义注解(Customer Annotation)生成简单SQL语句 这次给大家介绍一下在Java开发过程中 使用自定义注解开发: 主要知识点:          ...

  5. Java中关于内存泄漏分析和解决方案,都在这里了!

    作者:李序锴 www.jianshu.com/p/54b5da7c6816 最近正在熟悉Java内存泄漏的相关知识,上网查阅了一些资料,在此做个整理算是对收获的一些总结,希望能对各位有所帮助,有问题可 ...

  6. Java中注解(非注释^_^) --转载

    本文将向你介绍J2SE5.0中的新特性之一:注解.本文将从什么是注解:J2SE5.0中预定义的注解:如何自定义注解:如何对注解进行注解以及如何在程序中读取注解5个方面进行讨论. 一.什么是注解 说起注 ...

  7. java中注解 详解

    本文将向你介绍J2SE5.0中的新特性之一:注解.本文将从什么是注解:J2SE5.0中预定义的注解:如何自定义注解:如何对注解进行注解以及如何在程序中读取注解5个方面进行讨论. 一.什么是注解 说起注 ...

  8. Java中的远程过程调用(RPC)

    文章目录 1. 背景 2. 远程过程调用的定义 3. 远程过程调用的优点 4. 远程过程调用的缺点 5. 实例 5.1. 客户端 5.1.1. 客户端实现 5.1.2. 动态代理类 5.1.3. 连接 ...

  9. [转载] Java中如何引用另一个类里的集合_Java工程师面试题整理

    参考链接: 在Java中将预定义的类名用作类或变量名 花了一星期把学过的都整理一遍 尽量易懂,从基础到框架 最新版大厂面经汇总出炉,持续更新中 汇总完了上传网盘,设计到后端架构师的一切知识 如果没更新 ...

最新文章

  1. Sql — CTE公用表表达式和With用法总结
  2. 通过手动创建统计信息优化sql查询性能案例
  3. 服务器otter部署-实现MySql数据同步
  4. Java自动拆装箱面试_跟王老师学泛型(二):Java自动装箱与拆箱
  5. 阿里巴巴招聘最全集合帖:宣讲会+岗位+30篇面试宝典来啦
  6. 一个讨论:SAP项目实施的顾问,需要花时间去调试代码了解技术细节吗
  7. 老工程师谈电子物料:别拿一分钱不当回事!
  8. win2008的搜索功能就是个鸡肋
  9. 【文末赠书】漫画:什么是 “跳表” ?
  10. 关于pdf阅读器的选择
  11. 区块链 solidity 零知识证明DApp开发实践【身份证明/以太坊】
  12. Python上传文件到百度网盘(一)
  13. 贪心算法适用条件_贪心算法
  14. 中国芝麻市场竞争规模及销售渠道分析报告2022-2028年版
  15. Android热更新方案Robust——美团热更新(热修复)使用介绍
  16. JAVA面向对象编程——学生喂养三种宠物:猫、狗和鸟
  17. 用python庆祝生日_雷吉娜用搞笑的歌曲庆祝自己50岁的生日:“今天一个婊子老了”...
  18. 如何在office2016(word2016)中安装mathtype6.9及相关问题解决方案
  19. python \xef\xbb\xbf --- 去除
  20. 快手上市 CEO写下70万行代码 致敬程序员改变世界

热门文章

  1. 微信全功能HOOK接口源码
  2. C语言译密码字符串A变E,C语言经典编程算法
  3. 小米Note顶配版 救砖详细步骤
  4. ENVI 5.3 分类后类别合并
  5. 换城市为什么需要换号
  6. 基于PyQt5和requests的小说在线阅读器(小说爬虫)
  7. 快速实现Excel到ODX/PDX数据文件的自动转换工具:VisualODX—ODX
  8. 上海社交媒体平台发展趋势分析
  9. echarts 画中国地图缺少 china.js
  10. 前端实现序列帧_炫酷H5中序列图片视频化播放的高性能实现