记录意外的开关选项

Java开发人员可以做很多事情来使自己的生活以及维护该代码的其他人的生活更加轻松。 在本文中,我将探讨开发人员可以采用的一种非常简单的方法,以使每个人都更轻松。 这篇文章的要点对于每个阅读它的人来说似乎都是显而易见的,但是我发现这样做的频率并不比我预期的要多。 总之,开发人员通常应记录它们的值开关 ,当该值不被任何明确的表示对-ing case是内声明switch

在进行具体说明之前,我将添加一些警告。 有时,记录switch到的值与case没有明确匹配可能没有意义。 其中一些列在这里。

  • 所打开的值是敏感的,出于安全原因不应记录。
  • 在很多情况下,打开该值都不会导致匹配,因此开发人员不想不必要地进行登录。
  • 可以提供一个default值,该default值对于没有匹配case块的任何值都将始终有效(这似乎很少)。

在我所见的情况下,这是导致其成为我主要宠物怒气的原因之一,上述警告均未适用。 实际上,在大多数情况下,开发人员已在default块中提供了一条记录的消息,警告该值是意外的,但同一开发人员未能提供不匹配的候选值。 下一个代码清单显示了一个人为的示例。

枚举default ,不带switch候选值登录

/*** Provides the Roman numeral equivalent of the* provided integer.* * @param integer Integer for which Roman numeral*    equivalent is desired.* @return Roman numeral equivalent of the provided*    integer or empty string ("") if I'm not aware of*    the Roman numeral equivalent.*/
public String getRomanNumeralEquivalent(final int integer)
{String romanNumeral;switch (integer){case 0:romanNumeral = "nulla";break;case 1:romanNumeral = "I";break;case 2:romanNumeral = "II";break;case 3:romanNumeral = "III";break;case 4:romanNumeral = "IV";break;case 5:romanNumeral = "V";break;case 6:romanNumeral = "VI";break;case 7:romanNumeral = "VII";break;case 8:romanNumeral = "VIII";break;case 9:romanNumeral = "IX";break;case 10:romanNumeral = "X";break;default:out.println("Unexpected integer was provided.");romanNumeral = "";break;}return romanNumeral;
}

这里的问题实际上是开发人员应避免的更普遍问题的特定示例:没有足够上下文的日志。 在某些情况下,提供使日志消息更有用的上下文类型可能很困难或计算量很大。 但是,在switch语句中通常不是这种情况,我们可以在其中轻松记录尝试switch的值。 在上面的代码清单中,将仅告知开发人员在部署中支持运行时问题的开发人员“提供了意外的整数”。 没有任何上下文,很难知道所提供的整数是什么,并且如果不知道候选整数,就很难跟踪发生的事情甚至再现它。

只需很少的精力就可以使此default日志记录语句有用,这将在下一个代码清单中显示。

构造更好的default日志语句

default:out.println("Unexpected integer (" + integer+ ") was provided, so empty String being returned for Roman Numeral.");romanNumeral = "";

“增强”日志消息指示正在打开哪个整数,并添加了由于该整数不是期望的整数而返回的内容。 第二部分对于开发人员而言不是必需的,因为静态代码将向开发人员显示在这种“默认”情况下返回的内容。 但是,记录正在打开的整数非常有价值,因为除非以后其他地方的另一条日志消息清楚表明正在打开,否则没有好的方法以后再访问此信息。

许多开发人员没有提供这种简单的上下文,我一直是受害者。 这使得原本很容易诊断的事情变得更加困难。 在极端情况下,我必须将此上下文添加到日志消息中,并等待再次遇到它。 如果开发人员在编写代码时添加了简单的上下文信息,则可以更轻松地解决此问题。

在编写自己的switch语句时,我希望将这一概念更进一步。 即使我的switch明确涵盖了所有可能的(当前) case我也通常添加一个default块。 在编写本文时,此default块是不必要的,并且“永远不会被调用”,但我将其添加到switch语句以适应未来需求(可以使用单元测试来实现类似的保护)。 我将提供给switch语句的意外候选值的日志添加到日志中,以便在代码“上游”添加另一种情况时,我的switch会在运行意外值时Swift告诉我,并告诉我该意外值是什么。

通常会发现,在不匹配case情况下为switch语句提供候选值是一种特殊情况。 在这种情况下,抛出异常比仅记录异常情况更合适。 一个标准的异常(例如IllegalArgumentException)可以很好地解决此问题(从某种意义上说,它是switch语句的非法参数),但是我偶尔也编写了一个自定义异常来帮助解决此问题。 当我决定实现并使用此自定义异常时,做出该决定的部分原因是抛出该异常会鼓励开发人员提供被打开的对象作为异常构造函数的一部分。 接下来显示此类自定义异常的典型示例。

SwitchOptionNotExpectedException.java

package dustin.examples.switchdemo;/*** Exception used to communicate a candidate value for* a {@code switch} statement not being matched by any* of the explicitly provided {@code case} blocks.*/
public class SwitchOptionNotExpectedException extends RuntimeException
{/*** Object being switched on for which no matching* {@code case} clause existed.*/private final Object switchedObject;/*** Constructor accepting exception message and the instance* upon which the {@code switch} was being attempted when no* matching {@code case} was found.** @param newMessage Exception summary message.* @param newSwitchedObject Object being switched on for*    which there was no explicitly specifed {@code case}.*/public SwitchOptionNotExpectedException(final String newMessage, final Object newSwitchedObject){super(newMessage + " (unable to switch on '" + String.valueOf(newSwitchedObject) + "')");switchedObject = newSwitchedObject;}/*** Constructor accepting the instance upon which the {@code switch}* was being attempted when no matching {@code case} was found.** @param newSwitchedObject Object being switched on for*    which there was no explicitly specified {@code case}.*/public SwitchOptionNotExpectedException(final Object newSwitchedObject){super("Switch statement did not expect '" + String.valueOf(newSwitchedObject)+ "'.");switchedObject = newSwitchedObject;}/*** Provides String representation of the object being* switched upon.** @return String representation of the object being*    switched upon.*/public String getSwitchedObjectString(){return String.valueOf(switchedObject);}/*** Provides type of object being switched upon.** @return Type of the object being switched upon or*    {@code null} if that switched upon object is null.*/public Class getSwitchedObjectType(){return switchedObject != null ? switchedObject.getClass() : null;}
}

开发人员是否只是简单地记录未找到切换候选者或引发异常是对此的回应,通常应记录或将所打开的值记录在异常中或包括在异常中,以使诊断问题变得更加容易。 上面的自定义异常将自动提供该消息,而与使用的构造函数无关,只要开发人员提供打开的对象即可。 在这种情况下,开发人员必须竭尽全力不提供该对象,而不仅仅是忽略或忘记包含它。

在排除了不适合登录或写出不匹配值的情况之后,开发人员最有可能无法表明该值的根本原因就是根本没有考虑它。 在编写代码时,对开发人员“显而易见”的是,任何意外情况“都不会发生”,或者如果确实发生了,那么价值是显而易见的。 在这些类型的消息(或与此有关的任何日志消息)中不包括上下文的另一个可能原因是匆忙或懒惰。 开发人员可能知道最好提供这些详细信息,但不想花时间去做。 这是后一个原因,有时会鼓励我编写一个如上所示的自定义异常。

对开发人员来说,调试和维护生产软件是宝贵的经验,因为它可以帮助开发人员更好地了解他们的行为(或缺乏行为)如何使将来的工作更加困难。 通常,有责任心的开发人员可以通过在记录的消息中提供上下文信息来帮助其他人(可能还有他或她自己),尤其是对于警告,错误和异常情况。 特别是,增加什么价值的背景下正在switch时没有找到匹配的-ed是很容易做到,可能相当多的时间保存自己,其他开发人员和客户的未来。

翻译自: https://www.javacodegeeks.com/2017/11/log-unexpected-switch-options.html

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

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

相关文章

View的绘制

1、当测量好一个View后就可以重写onDraw()方法,并在Canvas对象上绘制所需的图形。 public class Canvas extends Objectjava.lang.Object ↳android.graphics.Canvas Public ConstructorsCanvas()Construct an empty raster canvas.Canvas(Bitmap bitmap)Construc…

ViewGroup的测量及绘制

1、ViewGroup的测量public abstract class ViewGroup extends Viewimplements ViewManager ViewParent java.lang.Object ↳android.view.View ↳android.view.ViewGroup Class Overview A ViewGroup is a special view that can contain other views (called children.)…

ejb 2.0 3.0_定义EJB 3.1视图(本地,远程,无接口)

ejb 2.0 3.0这篇文章将讨论使用批注定义EJB视图的可能方法(最后我将只提到使用EJB部署描述符)。我将重点介绍最新的EJB 3.1视图,这些视图将省略旧的本地,远程和本地接口。 因此,我们可以选择: 远程业务界面…

View的事件分发机制简述

要分析的对象就是MotionEvent,点击事件的事件分发其实就是对MotionEvent事件的分发过程,当MotionEvent产生后,系统需要把这个事件传递给一个具体的View,这个传递过程就是分发过程。这个过程由三个很重要的方法共同完成&#xff1a…

ListView的使用用ViewHolder提升效率

public class ListView extends AbsListViewjava.lang.Object ↳android.view.View ↳android.view.ViewGroup ↳android.widget.AdapterView<T extends android.widget.Adapter> ↳android.widget.AbsListView ↳android.widget.ListView Class Ove…

通过投影增强数据模型

介绍 数据模型可能很棘手。 建模可能会更加困难。 有时候&#xff0c;应该放入数据库表中的信息不一定是我们要在每段代码中使用的信息。 和其他许多次一样&#xff0c;Spring来了。 一个称为投影的小功能可以帮助我们在普通界面中仅用几行数据映射数据。 在本文中&#xff0…

ListView常用属性、方法

1、设置item间分割线&#xff0c;分割线高度 android:divider"android:color/darker_gray" android:dividerHeight"10dp" 分割线不仅仅可以设置为一个颜色&#xff0c;也可以设置为一个图片资源。 分割线设置为透明&#xff1a; android:divider"…

具有弹性效果的ListView

Android默认的ListView在滚动到顶端或底端&#xff0c;没有很好的提示&#xff0c;下面通过源码来实现弹性效果。 ListView中有一个控制滑动到边缘的处理方法&#xff1a; protected boolean overScrollBy(int deltaX, int deltaY,int scrollX, int scrollY,int scrollRangeX,…

rememberme多久_使用Spring Security添加RememberMe身份验证

rememberme多久我在“ 向Jiwhiz博客添加社交登录”一文中提到&#xff0c;RememberMe功能不适用于Spring Social Security。 好吧&#xff0c;这是因为该应用程序现在不通过用户名和密码对用户进行身份验证&#xff0c;并且完全依靠社交网站&#xff08;例如Google&#xff0c;…

Java 9:对可选的增强

之前 &#xff0c;我写过Java 8中引入的Optional类&#xff0c;该类用于对可能不存在的值进行建模并减少可能引发NullPointerException的位置的数量。 Java 9向Optional添加了三个新方法&#xff1a; 1. ifPresentOrElse 新ifPresentOrElse方法允许你执行一个动作&#xff0c…

电脑还原Mac地址

之前修改过电脑Mac&#xff0c;现在与手机Mac冲突&#xff0c;导致手机无法连接校园网。 控制面板——》打开网络和共享中心——》选择更改适配器设置 本地连接——》右键选择属性 上图选择配置 高级——》在下拉菜单中选择网络地址——》右边选为“不存在” 之后本地连接会自…

聊天ListView使用ViewHolder

聊天界面会展示至少两种布局&#xff0c;即收到消息和发送消息。这样一个ListView与平时使用的ListView的最大不同&#xff0c;在于它有两个不同的布局&#xff1a;收到的布局和发送的布局。需要利用Adapter实现这样的效果。即需要在获取布局的时候判断该获取哪个布局。 public…

动态改变ListView布局

在getView()时&#xff0c;通过判断选择加载不同的布局。 点击某个item的时候&#xff0c;变为foucus状态&#xff0c;其他的items还原。 下面用两个方法给item设置两个不同的布局。 //foucus状态&#xff0c;显示一个ImageViewprivate View addFocusView(int i) {ImageView…

jpa 关系拥有方_JPA:确定关系的归属方

jpa 关系拥有方使用Java Persistence API&#xff08;JPA&#xff09;时&#xff0c;通常需要在两个实体之间创建关系。 这些关系是通过使用外键在数据模型&#xff08;例如数据库&#xff09;中定义的&#xff0c;而在我们的对象模型&#xff08;例如Java&#xff09;中则使用…

JDBC连接备忘单

抽象 这是常见数据库的JDBC连接的快速参考。 我似乎必须大量查找此信息&#xff0c;因此我认为最好将所有参考资料放在一个地方。 德比 <dependency><groupId>org.apache.derby</groupId><artifactId>derbyclient</artifactId><version>1…

获取View坐标

滑动一个View&#xff0c;即移动一个View&#xff0c;改变其当前所处的位置&#xff0c;通过不断改变View的坐标实现滑动的效果。 1、Android坐标系&#xff1a;坐标原点在屏幕左上角。 public void getLocationOnScreen(int[] location) Computes the coordinates of this vi…

李宏毅 课程打包_按功能而不是按层打包课程

李宏毅 课程打包大多数企业Java应用程序在设计上都有一些相似之处。 这些应用程序的打包通常由它们使用的框架&#xff08;如Spring&#xff0c;EJB或Hibernate等&#xff09;驱动。或者&#xff0c;您可以按功能对打包进行分组。 像任何其他有关建模的项目一样&#xff0c;这也…

error inflating class binaryXML LayoutParams addRule()

报出异常的原因是由于少添加了构造方法&#xff0c;三个构造方法需要写完整&#xff0c;不能只写一个。参数为(Context, AttributeSet)&#xff0c;其中第二个参数用来将xml文件中的属性初始化。 自定义控件若需要在xml文件中使用&#xff0c;就必须重写带如上两个参数的构造方…

AppD方法:Java 9支持

通过从应用程序中学习企业APM产品&#xff0c;发现更快&#xff0c;更高效的性能监控。 参加AppDynamics APM导览&#xff01; 阅读有关Java 9模块化功能带来的挑战以及AppDynamics保持在该领域的领导者的严格要求的更多信息。 我们很高兴宣布Java 17全面支持&#xff0c;这是…

Java反射,但速度更快

在编译时不知道Java类的最快方法是什么&#xff1f; Java框架通常会这样做。 很多。 它可以直接影响其性能。 因此&#xff0c;让我们对不同的方法进行基准测试&#xff0c;例如反射&#xff0c;方法句柄和代码生成。 用例 假设我们有一个简单的Person类&#xff0c;其中包含名…