专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

简简单单的反射和詹杜库放在一起就能好玩了吗?

  背景
  相信大家在日常的工作中,一定遇到过以下的某个场景:前端需要选择某些字段,去展示不同字段下的信息,如果在字段和方法没有绑定的情况下,如何调用get方法呢?如果有一张横转纵的表,存储的do都是实际的字段名称,那么如何转化成实体类对应的get、set方法去执行操作呢?如果我想根据方法名称去调用对象的某个方法呢?
  相信有些基础的程序员会立刻想到使用反射就好了,没错,就是这么简单,但是每用到一次,咱们就去写一次也是比较麻烦的,所以我们可以将它封装成工具类,用的时候直接去调用就好了。实现
  目前我在工具类实现了三个方法,分别是:根据属性名调用对象get方法根据属性名调用对象的set方法根据方法名调用方法根据属性名调用对象get方法
  实现逻辑:获取对象的class获取对象的所有属性获取对象的声明方法遍历属性匹配方法invoke执行该方法返回方法的返回值根据属性名获取属性值returnjava。lang。StringParamfiledNameParamobjDate2022121515:06AuthorwjbgnpublicstaticStringgetObjField(StringfiledName,Objectobj){AtomicReferenceStringvaluenewAtomicReference();Classlt;?aClassobj。getClass();获取所有属性Field〔〕declaredFieldsaClass。getDeclaredFields();获取所有方法Method〔〕declaredMethodsaClass。getDeclaredMethods();Arrays。stream(declaredFields)。forEach(filed{if(filed。getName()。equals(filedName)){属性存在,尝试获取属性,调用get方法,此处get方法需要组装Arrays。stream(declaredMethods)。forEach(method{if(method。getName()。toLowerCase()。equals(getfiledName)){try{执行方法Objectinvokemethod。invoke(obj);value。set(invokenull?null:invoke。toString());}catch(Exceptione){thrownewRuntimeException(e);}}});}});returnvalue。get();}根据属性名调用对象的set方法
  实现逻辑:获取对象的声明方法遍历方法匹配方法名称invoke执行该方法根据属性名设置属性值returnvoidParamfiledName字段名Paramvalue字段值Paramobj对象Date2022121514:41AuthorwjbgnpublicstaticvoidsetObjField(StringfiledName,Stringvalue,Objectobj){Classlt;?aClassobj。getClass();Arrays。stream(aClass。getDeclaredMethods())。forEach(method{if(method。getName()。toLowerCase()。equals(setfiledName)){try{method。invoke(obj,value);}catch(IllegalAccessExceptione){thrownewRuntimeException(e);}catch(InvocationTargetExceptione){thrownewRuntimeException(e);}}});}根据方法名调用方法
  实现逻辑:获取对象的所有方法不同于获取get、set,此处需要获取所有的方法,包括实现和继承来的。遍历方法匹配方法名称invoke执行该方法返回方法返回值根据方法名调用该方法returnjava。lang。ObjectParamfiledNameParamobjDate2022121515:05AuthorwjbgnpublicstaticObjectinvokeMethod(StringfiledName,Objectobj){AtomicReferenceObjectresultnewAtomicReference();Arrays。stream(obj。getClass()。getMethods())。forEach(method{if(method。getName()。toLowerCase()。contains(filedName)){有方法包含该属性try{Objectinvokemethod。invoke(obj);result。set(invoke);return;}catch(Exceptione){thrownewRuntimeException(e);}}});returnresult。get();}测试准备基础代码
  使用一段代码来测试下我们的方法,首先准备一些基础类。
  背景是有三个小学生,分别是詹姆斯,库里,杜兰特,每个人共有一些属性,如下所示:学生类,每个学生可以跑,跳,投篮staticclassStudentimplementsPlayerActon{privateStringname;privateStringage;privateStringteam;FieldDesc(typeexclusive,valuelearnexclusiveskills)privateStringexclusive;FieldDesc(valuesphonenum?Idontknow!)privateStringphone;publicStudent(Stringname,Stringage,Stringteam,Stringphone){this。namename;this。ageage;this。teamteam;this。phonephone;}publicStudent(){}publicStringgetExclusive(){returnexclusive;}publicvoidsetExclusive(Stringexclusive){this。exclusiveexclusive;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this。namename;}publicStringgetAge(){returnage;}publicvoidsetAge(Stringage){this。ageage;}publicStringgetTeam(){returnteam;}publicvoidsetTeam(Stringteam){this。teamteam;}publicStringgetPhone(){returnphone;}publicvoidsetPhone(Stringphone){this。phonephone;}OverridepublicStringrunning(){returnisrunning!;}OverridepublicStringjumping(){returnisjumping!;}OverridepublicStringshooting(){returnmakeashot!;}}
  上面的实体类实现了一个接口PlayerActon,里面是三个方法,表示运动员可以跑,跳,投篮:动作接口privateinterfacePlayerActon{跑Stringrunning();跳Stringjumping();投篮Stringshooting();}
  除此之外,看到下面的两个属性,分别带有一个注解:FieldDesc(typeexclusive,valuelearnexclusiveskills)privateStringexclusive;FieldDesc(valuesphonenum?Idontknow!)privateStringphone;
  这里没什么别的含义,就是想在反射的时候,给这个属性赋默认值,在注解上面可以直接取值,比较方便。另外注解的属性还有一个type,这个type用来指定当前的属性是专属字段,因为不同的球员有不同的个性,我们通过这个类型判断下,如果是这个字段,那么要给上面的三个小学生赋不同的专属技能了:自定义注解,描述字段DocumentedTarget({ElementType。FIELD,ElementType。METHOD})Retention(RetentionPolicy。RUNTIME)privateinterfaceFieldDesc{类型Stringtype()default;字段描述Stringvalue()default;}复制代码
  既然说到了技能了,那就把技能枚举定义一下:技能枚举publicstaticenumSkillsEnum{STANDHAND(James,STANDHAND!!!,摊手),SHAKEHEAD(Curry,SHAKEHEAD!!!,摇头),SHAKESHOULDERS(Durant,SHAKESHOULDERS!!!,晃肩膀);privateStringstudentName;privateStringskillsName;privateStringskillsNameDesc;SkillsEnum(StringstudentName,StringskillsName,StringskillsNameDesc){this。studentNamestudentName;this。skillsNameskillsName;this。skillsNameDescskillsNameDesc;}publicStringgetStudentName(){returnstudentName;}publicvoidsetStudentName(StringstudentName){this。studentNamestudentName;}publicStringgetSkillsName(){returnskillsName;}publicvoidsetSkillsName(StringskillsName){this。skillsNameskillsName;}publicStringgetSkillsNameDesc(){returnskillsNameDesc;}publicvoidsetSkillsNameDesc(StringskillsNameDesc){this。skillsNameDescskillsNameDesc;}根据学生获取技能returnjava。lang。StringParamstudentDate2022121514:21AuthorwjbgnpublicstaticStringgetSkillsByStudent(Studentstudent){for(SkillsEnumskillsEnum:SkillsEnum。values()){if(skillsEnum。getStudentName()。equals(student。getName())){returnskillsEnum。getSkillsName();}}returnnull;}}准备main方法
  下面我们准备一个main方法,模拟一个场景:工具类测试样例ParamargsreturnvoidDate2022121515:10Authorwjbgnpublicstaticvoidmain(String〔〕args){获取动作对应的结果,循环10次for(inti0;i10;i){try{随机获取一个学生StudentstudentstudentList。get(newRandom()。nextInt(3));随机获取一个动作StringactionactionList。get(newRandom()。nextInt(7));打印下随机结果System。out。println(getStudentField(action,student));Thread。sleep(500L);}catch(Exceptione){thrownewRuntimeException(e);}}}
  如上所示,循环10次,分别调用getStudentField方法,方法后面会讲,这个方法就是为了获取学生的属性,但是我们从上面的代码看的出来,获取哪一个学生,获取学生的哪一个属性都是随机的,所以我们首先把这些属性和学生初始化一下,其中除了有字段属性,还有方法名称:动作集合privatestaticListStudentstudentListnewArrayList();动作集合privatestaticListStringactionListnewArrayList();初始化动作集合,学生这里面都使用字段的名称,不使用get、set方法static{获取球员的年龄actionList。add(age);获取球队actionList。add(team);获取电话actionList。add(phone);学习使用专属动作actionList。add(exclusive);跑actionList。add(running);跳actionList。add(jumping);投篮actionList。add(shooting);studentList。add(newStudent(James,37yearsold,FromtheLosAngelesLakers,));studentList。add(newStudent(Curry,34yearsold,FromtheGoldenStateWarriors,));studentList。add(newStudent(Durant,33yearsold,FromtheBrooklynNets,));}
  有了上面的初始化,我们就可以随机的调用getStudentField方法,步骤:首先将学生名字返回拼接到字符串通过属性名称和学生对象调用前面封装好的ObjectDynamicUtil。getObjField方法如果没获取到属性,表示属性为空或者不是属性,是方法去调用setStudentField方法,如果返回有值,则成功,再次ObjectDynamicUtil。getObjField获取一次如果仍然是空,那么就调用前面封装好的ObjectDynamicUtil。invokeMethod,按属性调用方法。返回结果动态获取学生属性ParamreturnvoidDate2022121511:23AuthorwjbgnprivatestaticStringgetStudentField(StringfiledName,Studentstudent)throwsNoSuchFieldException{Stringmsgstudent。getName();获取属性值StringvalueObjectDynamicUtil。getObjField(filedName,student);if(valuenullvalue){如果获取属性是空怎么办?设置一个值进去setStudentField(filedName,student);设置值后,再次执行get方法valueObjectDynamicUtil。getObjField(filedName,student);}调用学生实现的动作接口方法if(valuenull){value(String)ObjectDynamicUtil。invokeMethod(filedName,student);}msgvalue;returnmsg;}
  下面看下设置学生属性值的方法:setStudentField,步骤:获取学生对象class根据属性名获取class的属性根据属性获取注解FieldDesc,即前面自定义的注解如果注解类型是exclusive,就根据学生从枚举类获取专属技能拼装结果并调用ObjectDynamicUtil。setObjField设置对象属性动态设置学生属性ParamreturnvoidDate2022121511:23AuthorwjbgnprivatestaticvoidsetStudentField(StringfiledName,Studentstudent)throwsNoSuchFieldException{Classlt;?extendsStudentstudentClassstudent。getClass();FielddeclaredFieldnull;try{declaredFieldstudentClass。getDeclaredField(filedName);}catch(NoSuchFieldExceptione){return;}catch(SecurityExceptione){thrownewRuntimeException(e);}FieldDescannotationdeclaredField。getAnnotation(FieldDesc。class);Stringvalueannotation。value();StringfinalValuevalue(annotation。type()。equals(filedName)?SkillsEnum。getSkillsByStudent(student):);ObjectDynamicUtil。setObjField(filedName,finalValue,student);}查看结果
  到此为止,所有的代码都准备完毕了,记得把main方法的Thread。sleep注释放开,看到的结果更加直观。
  此处注释是因为在码上掘金导致代码不能运行,不知道码上掘金是什么原因?
  结果如下图所示:
  如上所示,看到不同的学生可以做不同的事,展示不同的属性,都是随机动态获取的。总结
  反射是java中,最基础,也是最核心的内容,同样也是最有用的。然而实际的工作当中,我们接触到的机会少之又少,所以我们需要自我提升,将这些手段融会贯通。本文涉及的知识很小一部分反射知识,但是对应经常与表单,表格打交道的后端程序员来说,却非常有用,赶紧用起来吧

PC上如何进行文件管理?PC文件管理软件一览表(截止20211107)软件操作界面简介图XYplorer被称为pc上被低估的冷门S器,新手劝退的超级软件。qttabbarwindows资源管理器的加强软件原与极速版有什么区别?是重复的吗?今日头条普通版和今日头条极速版是有区别的,并不能说重复。二者在功能定位面向人群方面存在着差异。普通版的功能比较全面一些普通版不但能浏览资讯,还融合了火山抖音懂车帝悟空问答等一些其他云南本地人心中的云南省大学排名是什么?2017年云南大学排名在2017年云南大学排行榜中,云南大学雄居排行榜榜首,昆明理工大学列第2名,云南师范大学列第3名,云南民族大学列第4名,云南农业大学列第5名。全部排名数据请看四川的一本高校有几所?综合实力都怎样?四川省共有109所普通高校,其中普通本科院校51所,普通专科院校58所,高校数量位居全国第十。那么,四川省有多少所一本高校,不错的一本大学,在川投档线各是多少?是众多想报考四川高校风流果有什么功效?风流果是一种果实,主要是药用。风流果学名叫厚鳞柯,又名壮阳果,补肾果,益肾子等。听名字就知道是益肾壮阳的。风流果喜欢高温向阳的地方生长,无明显花,每三年结一次果。而且成熟后期得高温120hz手机为什么没有90hz选项?现在除了60Hz标准刷新率的手机以外,大部分高刷新率手机都是90Hz或120Hz,但是很多用户发现,自己的120Hz手机并不能调整到90Hz及以其它刷新率数值,最低也只能调到60H手机拍照是不是退步了?或者是走偏了?感谢邀请手机拍照是不是退步了?或者是走偏了?如果说只是日常的使用,确实之前的1200万像素已经足够。而且就像题主所言,几年前的手机拍照也不差。那么现在的手机拍照提升是不是就没有意义手机系统新版本明知道很费电,有的厂家为什么还是要发布?首先新版本的发布有以下几个原因1。修复当前系统bug,提高系统运行速度的,是软件自我完善的过程,更新之后卡顿会明显减少。2。某些版本的更新是针对硬件方面的,更新之后的系统能够对硬件手机剩50电量的时候适合充电吗?有哪些需要注意的问题?先来说一下答案,手机剩50电量的时候适合充电的,下面谈一下原因。关于手机充电是一个老生常谈的话题,也是一个让很多人迷惑的问题。结合笔者的实际使用情况,以及一些技术问题,笔者的观点是华为5g手机哪一款性价比最高,最值得购买?华为性价比高的5G手机有哪些?目前华为自家的5G手机,也就只有搭载麒麟820麒麟985麒麟9905G芯片的,那下面分别给题主推荐一款。1。荣耀X10这款手机是今年5月份发布的,搭载假如人们都支持国产,没人再买苹果手机,富士康厂会倒闭吗?假如你不吃饭世界上农民会饿死吗?真的不明白现在中国网络怎么了?天天骂苹果骂特斯拉,这些脑残想过没有,这些企业都是合法合规在中国成立的企业,别人合法经营交税,给中国创造就业,国家没有
聊城市台胞台属学习党的二十大精神畅谈心得体会聊城市台胞台属线上学习贯彻落实(图片来源聊城市台港澳办)中国台湾网12月9日讯聊城市台港澳办近日召开台胞台属学习贯彻落实党的二十大精神座谈会。会议采取线上视频的方式举行。台胞台属代机床工具行业需求持续增长中国工业报记者郭宇中国机床工具工业协会(以下简称协会)根据前三季度数据对行业进行了分析。分析报告指出,前三季度,机床工具行业积极克服疫情等诸多不利因素的影响,经济运行呈现逐步恢复向轻轻推动你圈子的边缘,看看是否有空间容纳那些被排除在外的人每日感悟第17天当小石头掉进水里的那一刻,你可以看见水面上有圈圈,一个个的不断的往外扩,范围越扩越广,甚至包围了水面上漂浮的各种杂物,但他不会因为包围了这些杂物而不再往外扩。人天生vivoX90Pro今日开售全球首发骁龙8Gen2,6499元起IT之家12月6日消息,vivoX90系列于11月22日发布。其中,vivoX90Pro全球首发骁龙8Gen2,将于今日上午1000开售,12GB256GB12GB512GB版本售2002年华为到底经历了什么?任正非每天在做噩梦,梦醒时常常哭?2002年,在深圳华为基地,近6000名新员工,正等待着任正非的一个解释,明明是让我来做研发,凭什么现在要去当维修工!更有甚者,直接冲上讲台,对着任正非吼你一口气招这么多人,是不是热烈祝贺海客智能机器人珠海二校正式开业啦开业大吉!海客智能机器人珠海花园校区2022年11月27日,海客智能机器人珠海花园校区迎来了盛大的开业典礼!众多家长与学生的到来让开业现场热闹非凡!让我们一起来回顾一下精彩瞬间吧现老牌厂商重现巅峰,骁龙888P曲面屏68W快充,12512G售价良心冬日生活打卡季随着智能手机的发展,如今很多厂商都出局了,以往我们熟悉的很多品牌,比如诺基亚,LG,HTC,黑莓等等,现如今已经不见踪影,但其中也有几家苟延残喘的,像是魅族,努比亚,一加11真机渲染图曝光相机模组改动较大搭载骁龙8Gen2芯片还是原来的配方,原来的味道,仅针对后置相机模组进行了改动,并且保留了三段式静音按键,再加个腰带就会有vivox90系列的既视感。12月5日消息,一加11系列新机的外观渲染图曝光。根荣耀X40和红米Note11Pro哪个好?别懵!虽价格相当,但差距极大荣耀X40和红米Note11Pro均为千元级明星代表机型,从各大平台的销量数据来看,这两款机型有着销量排名一二的好成绩,能够吸引众多用户的选购与肯定,相信这两款机型自有其独特之处。华为发布会重新定档12月9日,华为nova10SE华为WATCHBuds将发布由于一些大家都知道的原因,大部分的手机厂商发布会都延期举办了。而数码博主厂长是关同学透露道,原定于12月2日举行的华为新品发布会,将于12月9日下午两点举行。不过,在此前关于这次发叶婷事件,疑似在场者之一发声了,所说过程完全是另外一个版本兼听则明,我们应该听听不同的声音。女子父亲被殴打致死的事引起广泛关注,接着又发生了叶婷失联的事,昨晚又发生了叶婷被取保候审等一系列事情,不知道什么时候是个头。随着越来越多的信息爆出
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网