管理系统网站,免费下载百度app最新版本,免费空间浏览量,iapp网站做软件在大型企业应用程序中#xff0c;有时我们需要将数据对象与Map相互转换。 通常#xff0c;这是特殊序列化的中间步骤。 如果可以使用某种标准#xff0c;则最好使用该标准#xff0c;但是很多时候#xff0c;一些首席架构师所设想的体系结构#xff0c;严格的环境或某些类… 在大型企业应用程序中有时我们需要将数据对象与Map相互转换。 通常这是特殊序列化的中间步骤。 如果可以使用某种标准则最好使用该标准但是很多时候一些首席架构师所设想的体系结构严格的环境或某些类似的原因使得使用JOOQHibernateJacksonJAX或其他某种东西成为可能。像那样。 在这种情况下就像几年前我遇到的那样我们必须将对象转换为字符串或二进制的某种专有格式朝该方向的第一步是将对象转换为Map 。 最终转换不仅仅是简单的 Map myMap (Map)myObject; 因为这些对象几乎从来都不是自己的地图。 转换中真正需要的是具有一个Map 其中每个条目都对应于“ MyObject”类中的一个字段。 条目中的关键字是字段的名称值是可能转换为Map本身的字段的实际值。 一种解决方案是使用反射并以反射方式读取对象的字段并从中创建地图。 另一种方法是在需要转换为Map的类中创建toMap()方法该方法只需使用字段名称将每个字段简单地添加到返回的Map中即可。 这比基于反射的解决方案要快一些并且代码要简单得多。 几年前当我在一个实际的应用程序中遇到这个问题时我为每个数据对象编写原始但众多的toMap()方法感到沮丧以至于我创建了一个简单的基于反射的工具该工具可以针对我们想要的任何类进行操作。 它解决了问题吗 没有。 这是一个专业的环境在这里不仅功能很重要而且代码质量和我的程序员的判断所得出的我的代码质量都不匹配。 他们认为基于反射的解决方案很复杂如果它成为代码库的一部分那么后来加入普通开发人员将无法维护它。 好吧我不得不承认它们是正确的。 在不同的情况下我会说开发人员必须在Java所需的水平上学习Java的反射和编程。 但是在这种情况下我们不是在谈论某个特定的人而是在将来某个人加入并加入团队可能是在我们已经离开该项目的某个时候。 假定此人是普通开发人员这似乎很合理因为我们对该人一无所知。 从这个意义上讲代码质量不好因为它太复杂了。 开发人员团队的法定人数决定维护许多手动制作的toMap()方法比将来寻找高级和有经验的开发人员要便宜。 老实说我有点不愿意接受他们的决定但是即使我仅根据我在团队中的职位就可以推翻它我还是接受了它。 即使我不同意但我倾向于接受团队的决定但前提是我可以接受这些决定。 如果一项决定是危险的可怕的并且威胁着项目的未来那么我们必须继续讨论细节直到达成协议。 几年后我开始创建Java :: Geci作为副项目可以从http://github.com/verhas/javageci下载 Java :: Geci是在Java开发生命周期的测试阶段运行的代码生成工具。 Java :: Geci中的代码生成是一个“测试”。 它运行代码生成并且如果所有生成的代码都保留下来则测试成功。 如果代码库中的任何内容发生了更改导致代码生成器生成的代码与以前不同因此源代码发生了更改则测试将失败。 如果测试失败则必须修复该错误并运行构建包括再次进行测试。 在这种情况下测试将生成新的现已固定的代码因此您所要做的只是再次运行构建。 在开发框架时我创建了一些简单的生成器来生成equals()和hashCode() 设置器和获取器委托生成器最后我无法抗拒但创建了通用的toMap()生成器。 该生成器生成的代码将对象转换为Map 就像我们之前讨论的一样还有我之前未提到的fromMap() 但显然也需要。 Java :: Geci生成器是实现Generator接口的类。 Mapper生成器可以扩展抽象类AbstractJavaGenerator 。 这使生成器可以抛出任何异常从而简化了生成器开发人员的工作并且它已经在查找从当前已处理的源生成的Java类。 生成器可以通过参数klass来访问实际的Class对象同时可以通过参数source来访问源代码 source代表源代码并提供创建要插入其中的Java代码的方法。 第三个global参数类似于保存源代码注释Geci定义的配置参数的映射。 package javax0.geci.mapper;import ...public class Mapper extends AbstractJavaGenerator {...Overridepublic void process(Source source, Class? klass, CompoundParams global)throws Exception {final var gid global.get(id);var segment source.open(gid);generateToMap(source, klass, global);generateFromMap(source, klass, global);final var factory global.get(factory, new {{class}}());final var placeHolders Map.of(mnemonic, mnemonic(),generatedBy, generatedAnnotation.getCanonicalName(),class, klass.getSimpleName(),factory, factory,Map, java.util.Map,HashMap, java.util.HashMap);final var rawContent segment.getContent();try {segment.setContent(Format.format(rawContent, placeHolders));} catch (BadSyntax badSyntax) {throw new IOException(badSyntax);}} 生成器本身仅调用这两个方法generateToMap()和generateFromMap() 这两个方法generateToMap() 其名称暗示将toMap()和fromMap()方法引入类。 两种方法都使用Segment类提供的源生成支持还使用Jamal提供的模板。 还需要注意的是这些字段是通过调用反射工具方法getAllFieldsSorted()来收集的该方法返回该类具有确定顺序的所有字段而不依赖于实际的JVM供应商或版本。 private void generateToMap(Source source, Class? klass, CompoundParams global) throws Exception {final var fields GeciReflectionTools.getAllFieldsSorted(klass);final var gid global.get(id);var segment source.open(gid);segment.write_r(getResourceString(tomap.jam));for (final var field : fields) {final var local GeciReflectionTools.getParameters(field, mnemonic());final var params new CompoundParams(local, global);final var filter params.get(filter, DEFAULTS);if (Selector.compile(filter).match(field)) {final var name field.getName();if (hasToMap(field.getType())) {segment.write(map.put(\%s\, %s null ? null : %s.toMap0(cache));, field2MapKey(name), name, name);} else {segment.write(map.put(\%s\,%s);, field2MapKey(name), name);}}}segment.write(return map;)._l(}\n\n);} 该代码仅选择由filter表达式表示的字段。 翻译自: https://www.javacodegeeks.com/2019/06/converting-objects-map-back.html