像java一样,一种具有反射功能的语言。允许开发人员在运行时检查类型、方法、字段、注解等,并在程序运行时决定是否使用。 为此,Java的反射API提供类,类,字段,构造函数,方法,注释和其他。 使用它们可以与编译时未知的类型进行交互,例如创建未知类的实例并对它们调用方法。

这个快速提示旨在让您深度了解什么是反射,它在Java中的使用,以及它可以用于什么。 之后,你将准备好开始或工作更长的教程。 为了充分使用它,你应该很好地理解Java的类构造器,特别是什么类和方法以及它们如何关联。 了解注释可解锁单独的部分。

Reflection API

我们从一个简单的Java代码开始(代码针对有一定java基础的阅读人员)

URL url = new URL("https://sitepoint.com/java ");
String urlString = url.toExternalForm();
System.out.println(urlString);

我决定在编译时(即当我在写代码时)创建一个URL对象,并且调用了其中的一些方法。下面演示了我使用Java的反射API完成了同样的事情:

// the gateway to reflection is the `Class` instance
// for the class you want to operate on
Class<?> type = Class.forName("java.net.URL");
// fetches the constructor that takes a `String` argument
// and uses it to create a new instance for the given string
Constructor<?> constructor = type.getConstructor(String.class);
Object instance = constructor.newInstance("https://sitepoint.com/java");
// fetches the `toExternalForm` method and invokes it on
// the instance that was just created
Method method = type.getMethod("toExternalForm");
Object methodCallResult = method.invoke(instance);
System.out.println(methodCallResult);

使用反射API的确比直接写代码要笨重一点. 但是使用反射你会发现, 你在代码当中的调用细节 (比如说我用的URL这个类以及我调用其中的方法) 变成了仅仅一个参数. 结果呢,在编译期间URL以及toExternalForm并没有绑定, 它们是在程序开始运行的时候才被决定绑定的

反射的大多数用例都是“框架”的场景下 ,想想junit, 比如说, 执行所有被@ test注解的方法. 一旦框架在classpath扫描的时候找到注解它就会调用getMethod以及invoke函数去执行用户代码. spring和其他的一些web框架在搜索控制器以及url映射的收也差不多是这么做的,对可扩展的应用程序来说反射的另外一个用途就是在运行时加载用户提供的插件

基本类型和方法

调用反射API的方法是Class :: forName。 在它的简单形式中,这个静态方法只需要一个完全限定的类名,并为它返回一个Class实例。 该实例可用于获取字段,方法,构造函数等。

通过构造器函数获取类对象,getConstructor方法可以使用构造函数参数的类型调用,就像我上面做的那样。 类似地,可以通过调用getMethod并传递其名称以及参数类型来访问特定方法。 上面的getMethod(“toExternalForm”)调用没有指定任何类型,因为该方法没有参数。

这里有一个方法:

Class<?> type = Class.forName("java.net.URL ");
// `URL::openConnection` has an overload that accepts a java.net.Proxy
Method openConnection = type.getMethod("openConnection ", Proxy.class);

这些调用返回的实例分别是Constructor和Method类型。 要调用底层成员,他们提供类似于Constructor :: newInstance和Method :: invoke的方法。 后者的一个有趣的细节是,要调用该方法的实例需要作为第一个参数传递给它(它指类的实例)。 其他参数将被传递给被调用的方法。

继续openConnection示例:

openConnection.invoke(instance, someProxy);

如果要调用静态方法,则将忽略实例参数,因此可以为null。

注解

注解是反射的重要组成部分。 事实上,注解主要针对反射。 它们旨在提供程序运行时访问的元信息,然后用于塑造程序的行为。 (如上所述,JUnit的@Test和Spring的@Controller和@RequestMapping是很好的例子。)

所有重要的反射相关类型,如类,字段,构造函数,方法和参数实现AnnotatedElement接口。 链接的Javadoc包含了注释如何与这些元素(直接呈现,间接呈现或关联)相关的详细解释,但是它最简单的形式是:getAnnotations方法以注释实例数组的形式返回该元素上存在的注释 ,然后可以访问其成员。

写在最后:欢迎留言讨论,加关注,持续更新!

七分钟理解 Java 的反射 API的更多相关文章

  1. 理解Java的反射与内省及其区别

    java的内省机制和反射机制什么区别 内省操作只针对JavaBean,只有符合JavaBean规则的类的成员才可以采用内省API进行操作....而反射则不同,一个类的所有成员都可以进行反射操作. 内省 ...

  2. 深入理解Java的反射机制

    https://blog.csdn.net/u012585964/article/details/52011138 http://www.importnew.com/20339.html 一,java ...

  3. 简单理解Java的反射

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

  4. 《深入理解Java虚拟机》-----第6章 类文件结构——Java高级开发必须懂的

    代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语言发展的一大步. 6.1 概述 记得在第一节计算机程序课上我的老师就讲过:“计算机只认识0和1,所以我们写的程序需要经编译器翻 ...

  5. 深入理解Java虚拟机(类文件结构+类加载机制+字节码执行引擎)

    目录 1.类文件结构 1.1 Class类文件结构 1.2 魔数与Class文件的版本 1.3 常量池 1.4 访问标志 1.5 类索引.父索引与接口索引集合 1.6 字段表集合 1.7 方法集合 1 ...

  6. [1] 注解(Annotation)-- 深入理解Java:注解(Annotation)基本概念

    转载 http://www.cnblogs.com/peida/archive/2013/04/23/3036035.html 深入理解Java:注解(Annotation)基本概念 什么是注解(An ...

  7. Java的反射机制和动态代理

    介绍Java注解的时候,多次提到了Java的反射API.与javax.lang.model不同的是,通过反射API可以获取程序在运行时刻的内部结构.反射API中提供的动态代理也是非常强大的功能,可以原 ...

  8. 深入理解Java:注解(Annotation)基本概念

    转自:http://www.cnblogs.com/peida/archive/2013/04/23/3036035.html 竹子-博客(.NET/Java/Linux/架构/管理/敏捷) 什么是注 ...

  9. 深入理解Java的注解(Annotation):基本概念(1)

    zz自:http://www.cnblogs.com/peida/archive/2013/04/23/3036035.html 什么是注解(Annotation): Annotation(注解)就是 ...

随机推荐

  1. PostMan Request Export

  2. Qt QJson解析json数据

    Qt QJson解析json数据 //加载根目录文件 void TeslaManageData::loadRootFolderFiles() { QNetworkAccessManager *mana ...

  3. 将map对象参数转换成String=String&方式

    * 将map对象参数转换成String=String&方式 * @param params * @param charset * @return * @throws UnsupportedEn ...

  4. Qt编写安防视频监控系统14-本地回放

    一.前言 在上一篇文章将视频文件存储好了,需要提供界面方便用户查询视频文件进行回放,其实这个回放就是播放历史存储的视频文件,并不是什么高大上的东西,视频回放在这个系统中分三种,第一种是本地回放,回放存 ...

  5. Linux中搜索大于200M的文件

    Linux中清理磁盘空间时,经常需要找出大于200M的文件. 这个命令可以实现这个功能: find / -size +200M -exec du -h {} \;

  6. Pytorch 类别平衡化处理

    采用  WeightedRandomSampler: def make_weights_for_balanced_classes(images, nclasses): count = [0] * nc ...

  7. [ARM-Linux开发]linux 里 /etc/passwd 、/etc/shadow和/etc/group 文件内容解释

    linux 里 /etc/passwd ./etc/shadow和/etc/group 文件内容解释 一./etc/passwd 是用户数据库,其中的域给出了用户名.加密口令和用户的其他信息 /etc ...

  8. springmvc中跨域问题

    对于web框架中的跨域问题是一个非常普遍的问题,常见的解决方案也有很多,如:jsonp.cros.websocket等.下面是最近处理springmvc中使用cors解决跨域问题的一些总结. Filt ...

  9. mysql高并发配置

    mysql高并发配置 要在mysqld下设置1 修改back_log参数值:由默认的50修改为500.(每个连接256kb,占用:125M)back_log=500<pre> back_l ...

  10. 10 Servlet+Http+Request对象

    1.Servlet的体系结构 Servlet -- 接口----->GenericServlet -- 抽象类------->HttpServlet -- 抽象类 (1)GenericSe ...