在JDK 8中可通过反射获得构造函数/方法参数元数据

JDK 8较不为人所知的一项新 功能是在编译的Java类中包含参数元数据的可选功能[JDK增强建议( JEP ) 118 ]。 此功能允许Java应用程序在运行时通过反射访问此参数元数据信息。

Java Tutorial的Reflection API路径包括一个名为“ 获取方法参数的名称”的课程,该课程讨论并演示了如何在Java 8中应用此新功能。该课程包括一个示例Java类MethodParameterSpy ,可以对提供的Java类运行该类以指示特征方法和构造函数参数。 本课还强调这是一项可选功能,因为在.class文件中存储其他参数元数据会增加这些文件的大小。 该课程还指出,在某些情况下,参数名称包含开发人员不希望在已编译的.class文件中使用的敏感信息。

通过将-parameters选项传递给javac编译器,可以将其他参数元数据包含在用Java 8编译的.class文件中。 当一个人键入javac -help时,也会显示此-parameters选项,如下一个屏幕快照所示。

jdk8JavacHelp-parameters突出显示

该javac的甲骨文技术说明页面显示此附加方法/构造函数的参数数据在运行时可以访问:在生成的类文件“房屋构造函数和方法的形式参数名称,这样的方法java.lang.reflect.Executable.getParameters从Reflection API可以检索它们。” 以下代码片段(名为ParameterDisplayer类)对此进行了演示(重点在displayParametersMetadata(String[])方法上)。

ParameterDisplayer.java

package dustin.examples.jdk8;import static java.lang.System.out;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;/*** Uses JDK 8 Parameter class to demonstrate metadata related to the parameters* of the methods and constructors of the provided class (includes private,* protected, and public methods, but does not include methods inherited from* parent classes; those classes should be individually submitted).* * @author Dustin*/
public class ParameterDisplayer
{private static void displayParametersMetadata(final String[] classesNames){for (final String className : classesNames){try{final Class clazz = Class.forName(className);// Get all class's declared methods (does not get inherited methods)final Method[] declaredMethods = clazz.getDeclaredMethods();for (final Method method : declaredMethods){writeHeader("Method " + method.toGenericString()+ " has " + method.getParameterCount() + " Parameters:");int parameterCount = 0;final Parameter[] parameters = method.getParameters();for (final Parameter parameter : parameters){out.println("\targ" + parameterCount++ + ": "+ (parameter.isNamePresent() ? parameter.getName() : "Parameter Name not provided,")+ (isParameterFinal(parameter) ? " IS " : " is NOT ")+ "final, type " + parameter.getType().getCanonicalName()+ ", and parameterized type of " + parameter.getParameterizedType()+ " and " + (parameter.isVarArgs() ? "IS " : "is NOT ")+ "variable." );}}}catch (ClassNotFoundException cnfEx){out.println("Unable to find class " + className);}}}private static void writeHeader(final String headerText){out.println("\n==========================================================");out.println("= " + headerText);out.println("==========================================================");}/*** Indicate whether provided Parameter is final.* * @param parameter Parameter to be tested for 'final' modifier.* @return {@code true} if provided Parameter is 'final'.*/private static boolean isParameterFinal(final Parameter parameter){return Modifier.isFinal(parameter.getModifiers());}public static void main(final String[] arguments){if (arguments.length < 1){out.println("You must provide the fully qualified name of at least one class.");System.exit(-1);}displayParametersMetadata(arguments);}
}

我最初考虑过对JDK的知名类运行此类,但是意识到这并不太有用,因为这些类不太可能是使用-parameters选项构建的。 因此,我创建了一个简单的示例类来辅助演示。 它称为ManyMethods然后显示。

ManyMethods.java

package dustin.examples.jdk8;import java.util.List;/*** Class with numerous methods intended to be used in demonstrating JDK 8's new* Parameter class.* * @author Dustin*/
public class ManyMethods
{public ManyMethods() {}private void addArrayOfStrings(String[] strings) {}private void addManyStrings(final String ... strings) {}private void addListOfStrings(final List<String> strings) {}@Overridepublic String toString(){return "ManyMethods";}
}

接下来的两个屏幕快照演示了ManyMethods不使用-parameters选项的情况下编译的ManyMethods实例上运行ParameterDisplayer 。 最显着的区别是,不使用-parameters选项进行编译时,不提供参数名称。 同样,如果没有-parameters选项,则在编译时参数是否为final也没有可信信息。 在不使用-parameters进行编译的情况下,无论-parameters是否为final , Parameter.getModifiers()方法均不包含final

parameterDisplayerOnClassWithoutParametersCompilation

parameterDisplayerOnClassWITHParametersCompilation

ParameterDisplayer类使用Parameter.isNamePresent()以编程方式标识不存在参数名称(当未使用-parameters选项进行编译时)。 如果未进行检查,则Parameter.getName()返回的参数名称将为“ arg”加上参数编号(第一个参数为arg0,第二个参数为arg1,依此类推)。

ManyMethods类中具有参数的三个方法中的ManyMethods具有该参数的final修饰符。 仅当使用-parameters选项编译类时,才可以通过使用Parameter.getModifiers()进行反射来正确识别这些情况。

略相关的旁注:Sun / Oracle工具文档始终由“ windows”页面和“ solaris”页面组成,后者通常用于描述特定工具如何在Linux和Unix上的所有版本上工作。 我注意到Java 8文档对此进行了更改。 该文档仍然具有“ windows”版本,但是Unix / Linux版本现在其URL中具有“ unix”。 为了说明这一点,这里是Java SE 7和Java SE 8 javac工具页面的URL:

  • http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html
  • http://docs.oracle.com/javase/8/docs/technotes/tools/unix/javac.html
  • http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html
  • http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javac.html

回到新的(使用Java 8) 参数类,值得注意的是,存储此附加参数元数据的已编译.class文件有所增加。 对于上面显示的我的ManyMethods类, .class文件从909字节扩大到961字节。

像Method一样, 构造 方法扩展了Executable ,因此Constructor类享有与Method相同的getParameters方法。 当使用这些额外信息显式编译代码时,Java 8将提供有关方法和构造函数参数的更多详细信息。

翻译自: https://www.javacodegeeks.com/2014/04/constructormethod-parameters-metadata-available-via-reflection-in-jdk-8.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/364201.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Web控件TreeView展开无闪烁的两个解决方法

已经无数次见到有人提出这个问题了。。。。。 第一种。。。。。 用.net控件TreeView而展开时不刷新的变通方法主要有以下步骤&#xff1a; 1。在Page_Load中为你的TreeView添加以下属性&#xff0c;这句话为TreeView添加Click时的回发事件。 TreeView1.Attributes["On…

基于面向对象的图片轮播(js原生代码)

无论你想走多远&#xff0c;你都需要不断地走下去。前端最精华的便是原生的js,这也是我们前端工程师的技术分层的重要指标&#xff0c;也提现这你的代码能力&#xff0c;开发的水平。废话不多说&#xff0c;进入今天的主要分享————基于面向对象思想的图片轮播。其效果如下所…

Spring boot 上传文件大小限制

1.spring boot 1.x 版本 application.properties 文件中 位置在&#xff08;resources下&#xff09; spring.http.multipart.maxFileSize 10Mb spring.http.multipart.maxRequestSize100Mb 2.spring boot 2.x 版本 application.properties 文件中 位置在&#xff08;resourc…

C#定义只能处理枚举类型的泛型类型

1 internal sealed class GenericTypeThatRequireAnEnum<T>2 {3 public static int age 12; //该 static 字段在不同的封闭类型之间是独立不共享的4 5 //静态构造器针对每个封闭类型都会执行一次&#xff0c;泛型类型定义静态构造器的目的就是为了保证传递的类…

电脑注册表被停用

“开始→运行”&#xff0c;输入“Gpedit&#xff0e;msc”后回车&#xff0c;打开“组策略”。然后依次展开“用户配置→管理模板→系统”&#xff0c;双击右侧窗口中的“阻止访问注册表编辑工具”&#xff0c;在弹出的窗口中选择“已禁用”&#xff0c;“确定”后再退出“组策…

Spring应用程序与JNDI连接池的集成测试

我们都知道&#xff0c;无论何时连接到数据库&#xff0c;都需要使用连接池。 所有使用JDBC 4类的现代驱动程序都支持它。 在本文中&#xff0c;我们将概述Spring应用程序中的连接池&#xff0c;以及如何在非JEE环境&#xff08;例如测试&#xff09;中处理相同的上下文。 在S…

jsp 上传转码_最完整的处理jsp处理乱码问题步骤,不需要手工转码

以编码格式为UTF-8为例1&#xff0c;jsp页面文件编码格式&#xff0c;在eclipse右键-》properties-》resource-》text file encode修改该UTF-82&#xff0c;jsp页面上的跟上面一样&#xff0c;为文件存储格式&#xff0c;按此格式存储文件&#xff0c;并编译里面汉字3&#xff…

CSS未知宽高元素水平垂直居中

方法一 &#xff1a;table、cell-table 思路&#xff1a;显示设置父元素为&#xff1a;table&#xff0c;子元素为&#xff1a;cell-table&#xff0c;这样就可以使用vertical-align: center&#xff0c;实现水平居中优点&#xff1a;父元素&#xff08;parent&#xff09;可以…

在java web工程中jsp页面中使用kindeditor

在这之前我们用Notepad写过kindeditor 在Java web工程里也差不多 首先我们复制之前的thml代码粘贴到工程里 然后把样式也复制进去 然后就可以运行了 转载于:https://www.cnblogs.com/q2546/p/11066539.html

数据分析方法论

把零散的报表整成数据监控体系 把每次拍脑袋的评估整成数据考核体系 在推荐、广告等算法上有所突破&#xff0c;而不是自己瞎捣鼓个没人看的聚类分析 在推送响应等有业绩的地方产出产品&#xff0c;而不是每次用时间序列法预测个销量走势再被业务喷回来。 分析自己的现状&am…

链接服务器

使用sql-server进行分布式查询&#xff08;链接服务器&#xff09; 可以使用sql-server企业管理器进行建立&#xff0c;注意其中的rpc及rpc out两项&#xff0c;也可以使用sql语句来完成定义&#xff0c;主要涉及到三个存储过程sp_addlinkedserver&#xff0c;sp_serveroption和…

mysql表级别的操作_MySql 库/表级操作 及 数据类型 - 纪宇

数据库分类关系型数据库(SQL)&#xff1a;存储方式固定&#xff0c;安全非关系型数据库(NoSQL)&#xff1a;存储方式比较灵活&#xff0c;存储数据的效率比较高&#xff0c;不太安全MySQL是一种关系型数据库管理系统(采用关系模型来组织管理数据的数据库系统)注意事项大小写&am…

具有Java 8支持的Spring Framework 4.0.3和Spring Data Redis 1.2.1

Spring Framework 4.0.3 正如Spring社区宣布的那样&#xff0c;Spring Framework 4.0.3现在可用。 它是上周Java 8发布后框架的第一个版本&#xff0c;因此它是使用OpenJDK 8 GA构建的&#xff0c;并包含最新的ASM 5.0.1。 Spring Framework 4.0.3为WebSockets带来了重要的增强…

Markdown的使用笔记

Markdown的使用笔记 Markdown在我看是一种使用几种标记符号就可以完成清晰排版的一种标记语言&#xff0c;是写笔记文章的一大利器&#xff0c;使用简单、方便&#xff0c;上手快&#xff0c;而且可以很好的兼容html&#xff0c;即html中的标签在markdown中也同样试用。这边文章…

多项式孤儿桶

巨佬制作人们大家好&#xff0c;我是练习多项式两周半的个人练习生lgl。这里总结一下多项式基本操作。 1.多项式加、减、输出 不说了。 时间复杂度$O(n)$。 2.多项式取模 已知多项式$F(x)$&#xff0c;求它对$x^n$取模。 人话&#xff1a;把$n$次及以上的系数清零。 时间复杂度…

焦头烂额

好久没有蹭公司的饭了&#xff0c;今天堕落了一把&#xff0c;和师弟师妹们一起蹭饭&#xff0c;唉&#xff0c;事情有点多&#xff0c;不知道干哪个好&#xff0c;后天回家&#xff0c;感觉GF好像不大愿意&#xff0c;虽然表面没说。。。 转载于:https://www.cnblogs.com/leol…

python亲密度_Python OpenCV 图像2D直方图,取经之旅第 25 天

Python OpenCV 365 天学习计划&#xff0c;与橡皮擦一起进入图像领域吧。基础知识铺垫在之前的博客中&#xff0c;我们获取图像直方图的方式都是获取一维直方图&#xff0c;简单说就是只获取一个通道的特征&#xff0c;例如灰度&#xff0c;B 通道&#xff0c;R 通道。今天要学…

Spring MVC,Thymeleaf,Spring Security应用程序中的CSRF保护

跨站点请求伪造&#xff08;CSRF&#xff09;是一种攻击&#xff0c;它迫使最终用户在当前已通过身份验证的Web应用程序上执行不需要的操作。 如果您使用Spring Security 3.2及更高版本&#xff0c;在Spring MVC / Thymeleaf应用程序中防止CSRF攻击相当容易。 怎么测试&#x…

清除浮动的方式

1、父级div定义伪类&#xff1a;after和zoom <style type"text/css"> .div1{background:#000080;border:1px solid red;}.div2{background:#800080;border:1px solid red;height:100px;margin-top:10px}.left{float:left;width:20%;height:200px;background:#D…

centos7 samba配置完成后不管怎么登陆都会显示密码错误的解决方案

添加系统用户 useradd samba 添加samba用户 smbpasswd -a samba 激活samba用户 smbpasswd -e samba 1.winr运行secpol.msc打开本地安全策略 2.安全策略->本地策略->安全选项 3.右侧找到 网络安全:LAN管理器身份验证级别 打开 &#xff0c;选择 仅发送NTLMv2响应&#xf…