10G网站空间,100种宣传方式,济南官网seo推广,项目策划书范文案例在开发#xff0c;阅读#xff0c;复审和维护成千上万行Java代码的几年中#xff0c;我已经习惯于看到Java代码中的某些“ 危险信号 ”#xff0c;这些信号通常#xff08;但可能并非总是#xff09;暗示着代码问题。 我不是在谈论总是错误的做法#xff0c;而是在有限的… 在开发阅读复审和维护成千上万行Java代码的几年中我已经习惯于看到Java代码中的某些“ 危险信号 ”这些信号通常但可能并非总是暗示着代码问题。 我不是在谈论总是错误的做法而是在有限的情况下谈论适当的做法但通常都表明存在错误。 这些“ 危险信号 ”有时可能是无辜的但经常警告不可避免地会不可避免地出现“ 伤害堆 ”。 在这里我总结了其中的一些内容并简要讨论了它们可能还不错的情况并描述了它们通常不正常的原因。 这些“红色标志”中的许多标志意义重大足以保证可从诸如FindBugs之类的代码分析工具发出警告。 流行的Java IDE也标记了其中许多。 但是我已经看到开发人员错过了这些工具和IDE的更多文字标记这是因为他们关闭了这些选项或者是因为他们习惯了或者由于不了解与标志相关的风险而忽略了警告。 在引用中使用而不是.equals 大多数Java开发人员都学会了使用比较基元以及使用.equals比较引用类型。 通常这是一个容易记住的规则通常可以很好地为Java开发人员服务。 有时使用比较标准Java类型引用StringIntegerLong等 可以很好地工作 但是依靠要缓存的值来使它可行并不是一个好主意。 在某些情况下可能需要检查身份相等性而不是内容相等性然后适合比较引用。 我在这里更喜欢Groovy的方法其中作用类似于.equals和并且显然传达了开发人员更严格地比较身份的愿望。 相同的参数适用于使用!将两个引用比较为一个红色标记因为如果被比较的两个对象即使共享相同的内容也不共享相同的标识内存地址则始终返回true。 在枚举中使用.equals而不是 坦白说Java开发人员对枚举使用还是.equals并不重要。 但是我更喜欢将与enums一起使用 。 此首选项的最重要原因是将与枚举一起使用可避免将枚举与某个不相关的对象永远不会相等进行比较的可能错误。 Object.equalsObject方法必须必须接受任何Object但这意味着编译器无法强制传入的对象实际上是要比较的类型。 与动态运行时检测问题相比我通常更喜欢静态问题的静态编译时间检测并且将与枚举一起使用可满足此偏好。 当然在比较枚举时同样的参数适用于!和!.equals使用。 幻数和文字字符串 我知道它是“计算机科学101”但是我仍然经常看到在Java代码中经常使用“ 魔术数字 ”和文字字符串。 这些作为将来可维护性的“危险信号”而大声疾呼使我对当前应用程序的正确性产生严重怀疑。 在单个位置将它们表示为常量或者在适当时更好地表示为枚举可以提高将来的可维护性并且也使我对使用这些值的所有代码都使用相同的值具有更高的信心。 此外集中定义的常量和枚举使使用IDE的“查找用法”功能轻松查找这些常量的所有“客户端”。 字符串常量 当我看到一组有限的相关String常量时我常常认为枚举会更好。 对于具有高度内聚性的一组String常量尤其如此它允许枚举很好地表示这些String构成的概念。 与String常量相比该枚举提供了编译时静态类型的安全性和潜在的性能优势。 在程序正确性方面最让我感兴趣的是编译时安全。 使用Java的“ Goto” 在这篇文章中我几乎没有在使用分支到带标签的代码上包含这个项目因为事实是我在生产代码中看到的大多数实例都是合理的 。 换句话说在这篇文章中列出该项目的原因更多是因为它有可能以错误的方式滥用和使用而不是我实际看到的。 在大多数情况下我看到Java开发人员使用Java的“ goto”是为了避免过于混乱和难以阅读的代码。 很少使用此事实可能部分归因于其正确使用。 如果经常使用那么这些用途中的大多数可能会变味。 取决于适用范围的同名变量的适当引用 在我看来该项目属于绝对不合适的类别但绝对可行甚至某些时候某些Java开发人员有意地完成了。 最好的例子是Java开发人员在执行方法期间将传递给方法的变量指向另一个引用。 指向方法参数的变量暂时指向它所分配的任何替代方法直到方法结束为止此时该方法超出范围。 在这种情况下将final关键字放在方法定义的参数定义之前会导致编译器错误这也是我喜欢在所有方法参数之前使用final的原因之一。 对我来说简单地在该方法的局部声明一个新变量更容易理解因为无论如何该变量仅在该方法局部使用。 更重要的是作为代码的读者我无法知道开发人员是否有意让该参数的名称仅在本地用于不同的值还是他们引入了一个错误认为将参数重新分配给新的引用会实际上在主叫方进行更改。 当我看到这些内容时我要么与原始开发人员合作要么从单元测试和生产中搜集信息然后使用意图并使其更加清晰或者如果打算更改调用方客户的价值则进行修复。 equalsObject和hashCode方法不匹配 尽管我相信应该为几乎所有编写的Java类都编写一个toString方法但是我对equalsObject和hashCode重写的感觉并不相同。 我认为只有在打算将类用于需要这些方法的情况下才应编写这些内容因为它们的存在应暗示它们在设计和开发中具有一定程度的额外彻底性。 特别是equals和hashCode方法需要满足它们的意图并进行广告宣传在Object的API文档中并且必须彼此对齐。 大多数IDE和分析工具会确定何时存在一种方法而没有另一种方法。 但是我想确保将用于equals的相同属性用于hashCode并且我希望在两种方法中以相同的顺序考虑它们。 缺少Javadoc注释 我喜欢将所有合同方法尤其是公共方法与Javadoc注释一起注释。 我还发现用属性要存储的内容进行注释非常有用。 我已经听过当代码“自我记录”时不使用Javadoc注释的借口但是我几乎总是可以告诉提出该要求的人一个或多个示例以了解简单的Javadoc注释如何能够传递与传递给您相同的信息。比解密代码花费的时间更长。 甚至更长的方法名称通常也不能足够长以指定给定方法的所有预期输入条件和输出预期。 我认为像我一样许多Java开发人员都喜欢在使用JDK时阅读Javadoc注释而不是阅读JDK代码。 为什么我们自己的内部代码应该有所不同 当注释不足或行为与所宣传的不一样时或者当我有理由认为注释可能陈旧或伪劣时我会阅读源代码。 我还希望看到Javadoc对类属性的注释。 有些人喜欢用属性信息注释公共的get / set方法但是我也不喜欢这种方法因为它假定get / set方法将始终可用我不喜欢这样的假设。 方法的Javadoc注释中的实现详细信息 尽管我觉得没有Javadoc注释是一个危险信号但是使用错误类型的Javadoc注释也是一个危险信号。 Javadoc注释不应解释实现细节而应侧重于客户端对方法的期望参数和客户端对方法的期望返回类型和可能引发的异常。 在真正的面向对象的系统中实现应该可以在公共接口下进行修改因此将这些实现详细信息放在接口文档中似乎是不合适的。 这是一个“危险信号”因为Javadoc中存在实现细节使我怀疑注释的及时性。 换句话说这些类型的注释通常会随着代码的发展而Swift过时并且完全错误。 源代码中的注释 尽管在接口上缺少注释通常在Javadoc中是一个危险信号但方法和其他源代码体内是否存在注释也是一个指示潜在问题的危险信号。 如果需要对代码进行注释以了解其功能则代码可能比需要的复杂得多“注释是臭代码的除臭剂”通常是正确的也很有趣。 就像这篇文章中的许多“红色标记”一样当我看到代码中的注释内容丰富时也有一些例外在这些注释中我无法想到一种更好的方式来呈现代码以消除对这些注释的需要。 但是我认为代码内而不是接口描述性Javadoc注释应该相对较少并且应该关注“为什么”做某事而不是“怎么做”。 该代码应该说明“如何”的细节但通常不能被编写为隐式地解释“为什么”由于客户/管理方向设计决策正式接口要求正式算法要求等。 实现继承扩展 我已经看到许多情况下可以很好地使用extends 实现继承并且适合这种情况。 我已经看到了很多情况相反的情况实现继承带来的麻烦多于好处。 艾伦·霍鲁布Allen Holub曾写过“ 扩展是邪恶的” 《 四种 设计模式的帮派》 一书非常着重于为什么组合通常比实现继承更可取的原因。 开发Java代码的时间越长更重要的是我维护Java代码的时间越长我就越相信组合的优点和实现继承的弊端。 正如我所说我已经看到实现继承可以起到很好的作用但是通常情况下类会“苦苦挣扎”以适应继承层次结构并且子类会遇到UnsupportedOperationException或“ noop ”实现因为它们继承的方法没有实现。真的适用。 抛出一些在有效Java中概述的继承问题例如用于继承具体类的equals和hashCode方法实现它可能会变成一团糟。 实现继承并不总是不好的但是它经常被不好地使用因此是一个危险信号。 死码 闲置未使用的代码永远不是一件好事。 人们很快就会忘记如何使用它或为什么使用它。 此后不久开发人员开始怀疑它是否由于某种原因而遗留了下来。 死代码不仅增加了必须读取和可能维护的代码而且在通过IDE完成编码的世界中仅基于死代码的名称和参数列表就可以轻松意外地调用死方法。 死代码通常也是被忽略的代码库的症状。 注释代码 已注释掉的代码可能不像可执行的死代码那样糟糕因为至少不能意外地调用它并且更明显的是未使用它但是它仍然是一个危险信号因为它表明潜在的代码库被忽视了。 就像死掉的可执行代码一样在注释掉代码之间经过的时间越长就越难知道为什么代码在那里为什么注释掉了以及为什么不再不再删除代码了需要。 开发人员可能会害怕删除它因为它显然很重要因此必须先离开但没人记得为什么。 待办事项 在代码中添加“待办事项”语句变得非常普遍以至于现代Java IDE为它们提供了特殊的支持和功能。 这些功能之所以有用是因为它们经常将待办事项标记放在列表中以供查看但是“待办事项”注释仍然是危险标记并且可能带来一些与死代码和注释掉代码相同的问题。 我肯定会使用“做”注释来进行短期提醒但是我认为最好在“做注释”中包括“有效期”和联系信息以及可能的人员或事件如果有需要蒸蒸日上以使“工作”得以完成。 拥有到期日期联系信息以及解决“待办事项”所必需的事件或人员可以减少在代码中进行“待办事项”注释的可能性因为没人记得确切的用途但没人敢删除它们因为是一件重要的事情。 当我在代码中看到“要做”的陈述时我不禁想知道代码是否某种程度上缺乏功能。 编译器警告和IDE /工具警告/提示/发现 Java红旗的明显示例是javac编译器发出的警告以及IDE和其他代码分析工具提供的发现和提示。 这些发现和警告中的每一个都可能是其自己的危险信号。 实际上javac编译器或工具和IDE会警告或暗示我在本文中引用的许多危险信号。 这些警告提示和发现不仅直接对应于许多Java代码危险信号而且它们的合计存在是一个巨大的危险信号表明潜在的被忽略的代码库可能会在其中丢失严重的警告甚至是某些定义的错误。大量的警告和提示。 编译器警告和IDE /工具警告/提示/发现已关闭 我绝对不认为FindBugs在我的Java代码中发现的每个问题都必然是错误或缺陷。 实际上在某些情况下我什至禁用了一些发现因为我不同意这些发现并且它们使FindBugs输出变得混乱。 话虽如此对发现的这种选择应该谨慎进行以确保只忽略真正的非发现并且对开发团队重要的事情是显而易见的。 同样我希望打开许多IDE警告但确实要关闭一些警告。 我也不认为在禁用Javac警告的情况下构建Java应用程序不是一个好主意。 禁用这些警告和发现可能会删除警告所代表的危险信号但是将其关闭的动作可能会导致更大的危险信号因为这些警告和提示指出了可以解决的许多潜在危险信号。 太聪明了/ Science Fair项目/过度设计/过早的优化 我最后一类危险信号是一大类过于复杂的软件这通常是常见的开发人员功能失常行为之一的结果。 过于聪明以致于无法阅读的代码或者在不需要时以灵活性或过早的优化为 重点的代码但往往以可读性为代价这通常会带来其他问题。 对代码进行过度工程化的开发人员可能正在这样做以查看他们是否可以或尝试一些新的东西或者只是想改变一些东西但是这些行为很少会不利于高质量的软件。 一旦软件变得过于复杂且难以理解就不太可能对其进行正确维护并且更有可能对其进行不正确的更改。 通常在阅读代码并想知道为什么开发人员没有以更明显和直接的方式实现此功能时这种危险信号的例子就是一个明显的例子。 一方面您可能会对他们知道并能够应用某些高级功能印象深刻但另一方面您知道这可能比原本应该的复杂。 这类危险信号有许多表现形式但我似乎在一些地区普遍看到它们。 特别是其中一个领域是通过反射Spring或其他依赖项注入动态代理观察者等将过多的功能这些功能在静态Java代码中能很好地发挥作用推向更多的动态构造。 所有这些东西在正确应用时都是方便且有用的但我也看到所有这些东西都被过度使用和滥用这使开发人员难以跟踪代码中发生的事情。 结论 在本文中我研究了在Java代码和Java开发环境中看到的一些常见的Java红色标记。 如果使用不当这些事情不一定是错误的或负面的但如果使用不当则可以视为对潜在有害做法的警告。 当我看到这些危险信号时我不会急于做出判断直到我有机会更深入地研究以确定在这些危险信号下进行酿造是否有困难或者它们是否处于可以采用该策略的情况下。 通常这些危险信号是即将发生问题的早期指标。 在某些情况下它们是对严重的现有问题也许以前无法解释的问题的解释或指示。 参考来自JCG合作伙伴 Dustin Marx的Java开发中的常见 危险信号 来自Inspired by Actual Events博客。 翻译自: https://www.javacodegeeks.com/2013/06/common-red-flags-in-java-development.html