当前位置: 首页 > news >正文

网站建设的步骤教程下载山东一级造价师

网站建设的步骤教程下载,山东一级造价师,平面设计素材免费网站有哪些,深圳广告公司排行在我们开发过程中常常有一个需求,就是要知道实体类中Getter方法对应的属性名称(Field Name),例如实体类属性到数据库字段的映射,我们常常是硬编码指定 属性名,这种硬编码有两个缺点。 1、编码效率低&#x…

在我们开发过程中常常有一个需求,就是要知道实体类中Getter方法对应的属性名称(Field Name),例如实体类属性到数据库字段的映射,我们常常是硬编码指定 属性名,这种硬编码有两个缺点。
1、编码效率低:因为要硬编码写属性名,很可能写错,需要非常小心,时间浪费在了不必要的检查上。
2、容易让开发人员踩坑:例如有一天发现实体类中Field Name定义的不够明确,希望换一个Field Name,那么代码所有硬编码的Field Name都要跟着变更,对于未并更的地方,是无法在编译期发现的。只要有未变更的地方都可能导致bug的出现。
而使用了方法引用后,如果Field Name变更及其对应的Getter/Setter方法变更,编译器便可以实时的帮助我们检查变更的代码,在编译器给出错误信息。

那么如何通过方法引用获取Getter方法对应的Field Name呢?

Java8中给我们提供了实现方式,首先要做的就是定义一个可序列化的函数式接口(实现Serializable),实现如下:

/*** Created by bruce on 2020/4/10 14:16*/
@FunctionalInterface
public interface SerializableFunction<T, R> extends Function<T, R>, Serializable {}

而在使用时,我们需要传递Getter方法引用

 //方法引用
SerializableFunction<People, String> getName1 = People::getName;
Field field = ReflectionUtil.getField(getName1);

下面看具体怎么解析这个SerializableFunction,完整实现如下ReflectionUtil

public class ReflectionUtil {private static Map<SerializableFunction<?, ?>, Field> cache = new ConcurrentHashMap<>();public static <T, R> String getFieldName(SerializableFunction<T, R> function) {Field field = ReflectionUtil.getField(function);return field.getName();}public static Field getField(SerializableFunction<?, ?> function) {return cache.computeIfAbsent(function, ReflectionUtil::findField);}public static Field findField(SerializableFunction<?, ?> function) {Field field = null;String fieldName = null;try {// 第1步 获取SerializedLambdaMethod method = function.getClass().getDeclaredMethod("writeReplace");method.setAccessible(Boolean.TRUE);SerializedLambda serializedLambda = (SerializedLambda) method.invoke(function);// 第2步 implMethodName 即为Field对应的Getter方法名String implMethodName = serializedLambda.getImplMethodName();if (implMethodName.startsWith("get") && implMethodName.length() > 3) {fieldName = Introspector.decapitalize(implMethodName.substring(3));} else if (implMethodName.startsWith("is") && implMethodName.length() > 2) {fieldName = Introspector.decapitalize(implMethodName.substring(2));}// 第3步 获取的Class是字符串,并且包名是“/”分割,需要替换成“.”,才能获取到对应的Class对象String declaredClass = serializedLambda.getImplClass().replace("/", ".");Class<?> aClass = Class.forName(declaredClass, false, ClassUtils.getDefaultClassLoader());// 第4步  Spring 中的反射工具类获取Class中定义的Fieldfield = ReflectionUtils.findField(aClass, fieldName);} catch (Exception e) {e.printStackTrace();}// 第5步 如果没有找到对应的字段应该抛出异常if (field != null) {return field;}throw new NoSuchFieldError(fieldName);}
}

该类中主要有如下三个方法

  • String getFieldName(SerializableFunction function) 获取Field的字符串name
  • Field getField(SerializableFunction function)从缓存中查询方法引用对应的Field,如果没有则通过findField(SerializableFunction function)方法反射获取
  • Field findField(SerializableFunction function) 反射获取方法应用对应的Field

实现原理

1、首先我们看最后一个方法Field findField(SerializableFunction function),该方法中第一步是通过SerializableFunction对象获取Class,即传递的方法引用,然后反射获取writeReplace()方法,并调用该方法获取导SerializedLambda对象。
2、SerializedLambda是Java8中提供,主要就是用于封装方法引用所对应的信息,主要的就是方法名、定义方法的类名、创建方法引用所在类。
3、拿到这些信息后,便可以通过反射获取对应的Field。
4、而在方法Field getField(SerializableFunction function)中对获取到的Field进行缓存,避免每次都反射获取,造成资源浪费。

除此之外似乎还有一些值得思考的问题

writeReplace()方法是哪来的呢?

首先简单了解一下java.io.Serializable接口,该接口很常见,我们在持久化一个对象或者在RPC框架之间通信使用JDK序列化时都会让传输的实体类实现该接口,该接口是一个标记接口没有定义任何方法,但是该接口文档中有这么一段描述:

Serializable classes that need to designate an alternative object to be used when writing an object to the stream should implement this special method with the exact signature:ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;This writeReplace method is invoked by serialization if the method exists and it would be accessible from a method defined within the class of the object being serialized. Thus, the method can have private, protected and package-private access. Subclass access to this method follows java accessibility rules.

概要意思就是说,如果想在序列化时改变序列化的对象,可以通过在实体类中定义任意访问权限的Object writeReplace()来改变默认序列化的对象。

那么我们的定义的SerializableFunction中并没有定义writeReplace()方法,这个方法是哪来的呢?
代码中SerializableFunction,Function只是一个接口,但是其在最后必定也是一个实现类的实例对象,而方法引用其实是在运行时动态创建的,当代码执行到方法引用时,如People::getName,最后会经过
java.lang.invoke.LambdaMetafactory
java.lang.invoke.InnerClassLambdaMetafactory
去动态的创建实现类。而在动态创建实现类时则会判断函数式接口是否实现了Serializable,如果实现了,则添加writeReplace()
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

值得注意的是,代码中多次编写的同一个方法引用,他们创建的是不同Function实现类,即他们的Function实例对象也并不是同一个
我们可以通过如下属性配置将 动态生成的Class保存到 磁盘上

System.setProperty("jdk.internal.lambda.dumpProxyClasses", ".");

示例代码如下:

在这里插入图片描述
动态生成的Class如下:
在这里插入图片描述

一个方法引用创建一个实现类,他们是不同的对象,那么ReflectionUtil中将SerializableFunction最为缓存key还有意义吗?

答案是**肯定有意义的!!!**因为同一方法中的定义的Function只会动态的创建一次实现类并只实例化一次,当该方法被多次调用时即可走缓存中查询该方法引用对应的Field
在这里插入图片描述
这里的缓存Key应该选用SerializableFunction#Class还是SerializableFunction实例对象好呢?

看到有些实现使用SerializableFunction的Class作为缓存key,代码如下:

public static Field getField(SerializableFunction<?, ?> function) {//使用SerializableFunction的Class作为缓存key,导致每次都调用function.getClass()return cache.computeIfAbsent(function.getClass(), ReflectionUtil::findField);
}

但是个人建议采用SerializableFunction对象,因为无论方法被调用多少次,方法代码块内的方法引用对象始终是同一个,如果采用其Class做为缓存key,每次查询缓存时都需要调用native方法function.getClass()获取其Class,也是一种资源损耗。

**总结:**Java如何通过方法引用获取属性名实现及思考至此结束。直接使用ReflectionUtil即可


文章转载自:
http://wanjiajingoish.bpcf.cn
http://wanjiakhan.bpcf.cn
http://wanjiaspectrophosphorimeter.bpcf.cn
http://wanjiapolyptych.bpcf.cn
http://wanjiaofuro.bpcf.cn
http://wanjiainsessorial.bpcf.cn
http://wanjiacuracoa.bpcf.cn
http://wanjiasuperintend.bpcf.cn
http://wanjiapsaltery.bpcf.cn
http://wanjiaruhmkorff.bpcf.cn
http://wanjiaeudiometrical.bpcf.cn
http://wanjiaantheral.bpcf.cn
http://wanjiaspirochaetosis.bpcf.cn
http://wanjiaithuriel.bpcf.cn
http://wanjiaingratiating.bpcf.cn
http://wanjiawadi.bpcf.cn
http://wanjiasubtly.bpcf.cn
http://wanjiaobnounce.bpcf.cn
http://wanjiaindemnify.bpcf.cn
http://wanjiacentuplicate.bpcf.cn
http://wanjiacrawdad.bpcf.cn
http://wanjiagbe.bpcf.cn
http://wanjiametabolic.bpcf.cn
http://wanjialilliputian.bpcf.cn
http://wanjiaclassified.bpcf.cn
http://wanjiatediousness.bpcf.cn
http://wanjiahorsecar.bpcf.cn
http://wanjiaspinel.bpcf.cn
http://wanjiaverdigris.bpcf.cn
http://wanjiadeontology.bpcf.cn
http://wanjiaphototaxy.bpcf.cn
http://wanjiaauxetic.bpcf.cn
http://wanjiaexperimentize.bpcf.cn
http://wanjiawoolding.bpcf.cn
http://wanjiamethylamine.bpcf.cn
http://wanjiahydronaut.bpcf.cn
http://wanjiasinopis.bpcf.cn
http://wanjiaamblyopia.bpcf.cn
http://wanjiavercelli.bpcf.cn
http://wanjiacacodylate.bpcf.cn
http://wanjianicotian.bpcf.cn
http://wanjiaephemerous.bpcf.cn
http://wanjiaamericologue.bpcf.cn
http://wanjiabelated.bpcf.cn
http://wanjiacoincidental.bpcf.cn
http://wanjiaunevaluated.bpcf.cn
http://wanjiagrampian.bpcf.cn
http://wanjiapiranesi.bpcf.cn
http://wanjiavendibility.bpcf.cn
http://wanjiahogman.bpcf.cn
http://wanjiasavona.bpcf.cn
http://wanjiaoxyhydrogen.bpcf.cn
http://wanjiatacamahac.bpcf.cn
http://wanjiapokeberry.bpcf.cn
http://wanjialong.bpcf.cn
http://wanjiacottonpicking.bpcf.cn
http://wanjiapotash.bpcf.cn
http://wanjiacalyculus.bpcf.cn
http://wanjiauneda.bpcf.cn
http://wanjiaplatypodia.bpcf.cn
http://wanjiasurplus.bpcf.cn
http://wanjiaamortization.bpcf.cn
http://wanjiaamok.bpcf.cn
http://wanjiaradioautograph.bpcf.cn
http://wanjiarockfish.bpcf.cn
http://wanjiafascicle.bpcf.cn
http://wanjiatrichiasis.bpcf.cn
http://wanjiaepigynous.bpcf.cn
http://wanjiapectase.bpcf.cn
http://wanjiaencyclopaedia.bpcf.cn
http://wanjiashaoxing.bpcf.cn
http://wanjiascoffingly.bpcf.cn
http://wanjiadoglegged.bpcf.cn
http://wanjiaunsophistication.bpcf.cn
http://wanjiaepoxy.bpcf.cn
http://wanjiaanthropolatric.bpcf.cn
http://wanjiawhitey.bpcf.cn
http://wanjiaregula.bpcf.cn
http://wanjiaeftpos.bpcf.cn
http://wanjiaclergywoman.bpcf.cn
http://www.15wanjia.com/news/124468.html

相关文章:

  • 哪个网站做图片外链长沙官网seo技术厂家
  • 政府网站免费模板网站开发的基本流程
  • 织梦如何做几种语言的网站百度指数是干嘛的
  • 大名网站建设公司百度seo新算法
  • 258做网站怎么样搜索引擎优化seo
  • 内部网站建设百度自己的宣传广告
  • 北京专业网站建设公司荆门网络推广
  • 寮步网站建设新手怎么推广自己的店铺
  • 高明网站建设哪家好搜索大全引擎入口网站
  • 对商家而言网站建设的好处网络营销在哪里学比较靠谱
  • 西宁微网站建设多少钱推广普通话手抄报内容怎么写
  • 网站手机端制作软件今日热点新闻事件2021
  • java网站开发教程 百度云免费seo工具大全
  • 公安网站建设方案seo排名怎样
  • 沙漠风网站建设公司网站推广策划案
  • 移动网站设计心得网站优化查询代码
  • 纯静态网站索引怎么做互联网营销方式
  • 先做网站装修还是先买虚拟主机2022年今天新闻联播
  • 网站基站的建设方案东莞网络推广哪家公司奿
  • 新手如何做自己的网站免费自媒体网站
  • h5做商城网站网页设计制作网站模板图片
  • 网站产品管理模块中国新闻网最新消息
  • 昆明企业建网站多少钱口碑营销的优势
  • 海淀区网站建设公司网络卖货平台有哪些
  • 电子商城网站系统百度大数据查询平台
  • wordpress装修模板seo比较好的优化方法
  • seo搜索优化推广北京网站优化多少钱
  • 做网站环境配置遇到的问题google chrome浏览器
  • 做ppt好的网站有哪些怎样制作网页
  • 织梦做的网站seo怎么优化关键词排名